diff --git a/.github/workflows/backup-to-gitlab.yml b/.github/workflows/backup-to-gitlab.yml index 8f3ad5f07..2ebbd4db7 100644 --- a/.github/workflows/backup-to-gitlab.yml +++ b/.github/workflows/backup-to-gitlab.yml @@ -28,3 +28,25 @@ jobs: - name: Print log run: | jenkins-bridge-client -printlog -token "${{ secrets.BRIDGETOKEN }}" -runid "${{ steps.generate-runid.outputs.RUN_ID }}" + + backup-to-gitee: + if: github.repository_owner == 'linuxdeepin' + runs-on: ubuntu-latest + steps: + - name: create-repo + run: | + repo=${{ github.event.repository.name }} + homepage="https://github.com/linuxdeepin/${repo}" + description="mirror of ${homepage}" + # remove '.' prefix + repo=${repo#"."} + curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/enterprises/linuxdeepin/repos' -d '{"private": 1,"access_token":"${{ secrets.GITEE_SYNC_TOKEN }}","name":"'"$repo"'","description":"'"$description"'","homepage":"'"$homepage"'","has_issues":"false","has_wiki":"false","can_comment":"false"}' || true + - name: push + run: | + git clone --bare https://github.com/linuxdeepin/${{ github.event.repository.name }}.git .git + repo=${{ github.event.repository.name }} + # remove '.' prefix + repo=${repo#"."} + git remote set-url origin https://myml:${{ secrets.GITEE_SYNC_TOKEN }}@gitee.com/linuxdeepin/${repo}.git + git push -f --all --prune origin + git push --tags origin diff --git a/.github/workflows/call-build-deb.yml b/.github/workflows/call-build-deb.yml deleted file mode 100644 index fd67cbec9..000000000 --- a/.github/workflows/call-build-deb.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Call build-deb -on: - pull_request_target: - paths-ignore: - - ".github/workflows/**" - types: [ opened, closed, synchronize ] - -concurrency: - group: ${{ github.workflow }}-pull/${{ github.event.number }} - cancel-in-progress: true - -jobs: - check_job: - if: github.event.action != 'closed' || github.event.pull_request.merged - uses: linuxdeepin/.github/.github/workflows/build-deb.yml@master - secrets: - BridgeToken: ${{ secrets.BridgeToken }} diff --git a/.github/workflows/call-build-distribution.yml b/.github/workflows/call-build-distribution.yml index c4c277ef3..a509d5f89 100644 --- a/.github/workflows/call-build-distribution.yml +++ b/.github/workflows/call-build-distribution.yml @@ -10,8 +10,4 @@ on: jobs: check_job: uses: linuxdeepin/.github/.github/workflows/build-distribution.yml@master - secrets: - BUILD_GPG_PRIVATE_KEY: ${{ secrets.BUILD_GPG_PRIVATE_KEY }} - BUILD_SSH_PRIVATE_KEY: ${{ secrets.BUILD_SSH_PRIVATE_KEY }} - WEBDAV_PASSWD: ${{ secrets.WEBDAV_PASSWD }} - WEBDAV_USER: ${{ secrets.WEBDAV_USER }} + secrets: inherit diff --git a/.github/workflows/call-chatOps.yml b/.github/workflows/call-chatOps.yml index 0eb0b7bc2..18c76bc33 100644 --- a/.github/workflows/call-chatOps.yml +++ b/.github/workflows/call-chatOps.yml @@ -6,5 +6,4 @@ on: jobs: chatopt: uses: linuxdeepin/.github/.github/workflows/chatOps.yml@master - secrets: - APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} + secrets: inherit diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml index 6a92b5467..e808a89b1 100644 --- a/.github/workflows/cppcheck.yml +++ b/.github/workflows/cppcheck.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - run: export - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false diff --git a/.obs/workflows.yml b/.obs/workflows.yml new file mode 100644 index 000000000..9a3e95dab --- /dev/null +++ b/.obs/workflows.yml @@ -0,0 +1,44 @@ +test_build: + steps: + - link_package: + source_project: deepin:Develop:dde + source_package: %{SCM_REPOSITORY_NAME} + target_project: deepin:CI + + - configure_repositories: + project: deepin:CI + repositories: + - name: deepin_develop + paths: + - target_project: deepin:CI + target_repository: deepin_develop + architectures: + - x86_64 + - aarch64 + + - name: debian + paths: + - target_project: deepin:CI + target_repository: debian_sid + architectures: + - x86_64 + + filters: + event: pull_request + +tag_build: + steps: + - branch_package: + source_project: deepin:Develop:dde + source_package: %{SCM_REPOSITORY_NAME} + target_project: deepin:Unstable:dde + filters: + event: tag_push + +commit_build: + steps: + - trigger_services: + project: deepin:Develop:dde + package: %{SCM_REPOSITORY_NAME} + filters: + event: push diff --git a/.reuse/dep5 b/.reuse/dep5 index 8be347ad9..b59147727 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -4,7 +4,7 @@ Upstream-Contact: UnionTech Software Technology Co., Ltd. <> Source: https://github.com/linuxdeepin/image-editor # ci -Files: .github/* +Files: .github/* .obs/workflows.yml Copyright: UnionTech Software Technology Co., Ltd. License: CC0-1.0 @@ -63,6 +63,11 @@ Files: tests/* Copyright: UnionTech Software Technology Co., Ltd. License: GPL-3.0-or-later +# patches +Files: patches/* +Copyright: UnionTech Software Technology Co., Ltd. +License: GPL-3.0-or-later + # qt web Files: src/web/toSearchMd/common/qwebchannel.js src/web/toManual/qwebchannel.js src/web_dist/toManual/qwebchannel.js src/web_dist/toSearchMd/qwebchannel.js Copyright: 2016 The Qt Company Ltd. @@ -73,3 +78,8 @@ License: BSD-3-Clause Files: tests/src/third-party/stub/* Copyright: 2019 coolxv License: MIT + +# assets +Files: manual-assets/* +Copyright: UnionTech Software Technology Co., Ltd. +License: LGPL-3.0-or-later diff --git a/.tx/config b/.tx/config index 28042b2db..a393114d6 100644 --- a/.tx/config +++ b/.tx/config @@ -3,13 +3,13 @@ host = https://www.transifex.com minimum_perc = 80 mode = developer -[deepin-manual.deepin-manual] +[o:linuxdeepin:p:deepin-manual:r:deepin-manual] file_filter = translations/deepin-manual_.ts source_file = translations/deepin-manual.ts source_lang = en_US type = QT -[deepin-manual.desktopts] +[o:linuxdeepin:p:deepin-manual:r:desktopts] file_filter = translations/desktop/desktop_.ts source_file = translations/desktop/desktop.ts source_lang = en diff --git a/.tx/deepin.conf b/.tx/deepin.conf new file mode 100644 index 000000000..2d7ce1709 --- /dev/null +++ b/.tx/deepin.conf @@ -0,0 +1,2 @@ +[transifex] +branch = m23 diff --git a/debian/changelog b/debian/changelog index 313911a9a..8813a294c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,111 @@ +deepin-manual (6.0.15) unstable; urgency=medium + + * Update version 6.0.15 + + -- shuaijie Wed, 10 Jul 2024 21:44:01 +0800 + +deepin-manual (6.0.14) unstable; urgency=medium + + * fix: unable to open video on older version of the system. + + -- fengli Wed, 10 Apr 2024 14:17:01 +0800 + +deepin-manual (6.0.13) unstable; urgency=medium + + * fix: Main page font adjustment and tooltip style modification(Bug: 241593) + * fix: Update Quick Start Document + * feat: Add app store entrance to commonly used app library pages + * fix: In dual screen expansion mode, the help manual is maximized on the main screen before being restored, and the window will be directly displayed on the secondary screen(Bug: 244417) + + -- houchengqiu Wed, 13 Mar 2024 15:08:16 +0800 + +deepin-manual (6.0.12) unstable; urgency=medium + + * fix some bugs. + + -- fengli Wed, 21 Feb 2024 16:53:13 +0800 + +deepin-manual (6.0.11) unstable; urgency=medium + + * New version 6.0.11 + + -- fengli Mon, 05 Feb 2024 16:20:12 +0800 + +deepin-manual (6.0.10) unstable; urgency=medium + + * Add resource file + + -- fengli Thu, 01 Feb 2024 17:14:55 +0800 + +deepin-manual (6.0.9) unstable; urgency=medium + + * Update version 6.0.9 + + -- fengli Thu, 01 Feb 2024 14:15:33 +0800 + +deepin-manual (6.0.8) unstable; urgency=medium + + * feat: New Quick Start and Video Guide modules added + * fix: Quick Start and Video Guide modules problem repair + + -- fengli Fri, 26 Jan 2024 11:37:47 +0800 + +deepin-manual (6.0.7) stable; urgency=medium + + * chore: Sync by https://github.com/linuxdeepin/.github/commit/2e5e092ba3f86b16d1aabbabcf0bfd2ae65b19c8(Influence: none) + * chore: Sync by https://github.com/linuxdeepin/.github/commit/559e91167d4919644f37bbcf123eb0651c1528ea(Influence: none) + * fix: 修复系统启动后dmanHelper成为常驻进程的问题 + * feat: support dtk 5.6.17 + Thanks to Hillwood Yang + * fix: missing app list(Issue: https://github.com/linuxdeepin/developer-center/issues/6902) + * feat: add metainfo of dde + + -- myml Tue, 16 Jan 2024 13:55:52 +0800 + +deepin-manual (6.0.6) stable; urgency=medium + + * Update version to 6.0.6. community + + -- Deepin Packages Builder Tue, 25 Apr 2023 11:07:12 +0800 + +deepin-manual (6.0.5) stable; urgency=medium + + * Update Version 6.0.5 + + -- Deepin Packages Builder Thu, 30 Mar 2023 15:40:34 +0800 + +deepin-manual (6.0.4) stable; urgency=medium + + * Update Version 6.0.4 + + -- Deepin Packages Builder Fri, 10 Mar 2023 10:17:23 +0800 + +deepin-manual (6.0.3) stable; urgency=medium + + * Update Version 6.0.3 + + -- Deepin Packages Builder Tue, 7 Mar 2023 11:11:35 +0800 + +deepin-manual (6.0.2) stable; urgency=medium + + * Update Version 6.0.2 + + -- Deepin Packages Builder Thu, 16 Feb 2023 14:48:35 +0800 + +deepin-manual (6.0.1) stable; urgency=medium + + * V23 & V20 code merge to same branch + * Reinital version 6.0.1 + + -- Deepin Packages Builder Tue, 14 Feb 2023 15:17:35 +0800 + +deepin-manual (6.0.0) stable; urgency=medium + + * V23 code + * Adapt REUSE license + + -- Deepin Packages Builder Mon, 30 Jan 2023 17:36:35 +0800 + deepin-manual (5.5.5) stable; urgency=medium * Update manual diff --git a/linglong.yaml b/linglong.yaml new file mode 100644 index 000000000..3ffee7dc5 --- /dev/null +++ b/linglong.yaml @@ -0,0 +1,50 @@ +package: + id: org.deepin.manual + name: "deepin-manual" + version: 5.8.4 + kind: app + description: | + manual for deepin os. + +variables: + extra_args: | + -DVERSION=${VERSION} + +runtime: + id: org.deepin.Runtime + version: 23.0.0 + +depends: + - id: qtwebengine + version: 5.15.3 + type: runtime + - id: googletest + version: 1.8.1 + - id: xcb-util + type: runtime + - id: icu + version: 63.1 + type: runtime + - id: libevent + type: runtime + - id: re2 + type: runtime + - id: pciutils + type: runtime + version: 3.5.2.4 + - id: libvpx + type: runtime + +source: + kind: local + patch: patches/fix-linglong.patch +build: + kind: manual + manual: + configure: | + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} ${extra_args} .. + make -j6 + #make test + make -j install diff --git a/manual-assets/common-application-libraries/libraries/common/appstore.png b/manual-assets/common-application-libraries/libraries/common/appstore.png new file mode 100755 index 000000000..a4f89e91d Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/common/appstore.png differ diff --git a/manual-assets/common-application-libraries/libraries/common/common_application_libraries.svg b/manual-assets/common-application-libraries/libraries/common/common_application_libraries.svg new file mode 100755 index 000000000..e4d432c95 --- /dev/null +++ b/manual-assets/common-application-libraries/libraries/common/common_application_libraries.svg @@ -0,0 +1,29 @@ + + + icon/apps + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/manual-assets/common-application-libraries/libraries/common/computer.png b/manual-assets/common-application-libraries/libraries/common/computer.png new file mode 100755 index 000000000..2227f8db3 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/common/computer.png differ diff --git a/manual-assets/common-application-libraries/libraries/common/multitasking_view.png b/manual-assets/common-application-libraries/libraries/common/multitasking_view.png new file mode 100755 index 000000000..b3ff23528 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/common/multitasking_view.png differ diff --git a/manual-assets/common-application-libraries/libraries/common/text_recognition.png b/manual-assets/common-application-libraries/libraries/common/text_recognition.png new file mode 100755 index 000000000..b62b1f51f Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/common/text_recognition.png differ diff --git a/manual-assets/common-application-libraries/libraries/common/wifi.png b/manual-assets/common-application-libraries/libraries/common/wifi.png new file mode 100755 index 000000000..99ab656c9 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/common/wifi.png differ diff --git a/manual-assets/common-application-libraries/libraries/en_US/fig/community.png b/manual-assets/common-application-libraries/libraries/en_US/fig/community.png new file mode 100755 index 000000000..5dff086d3 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/en_US/fig/community.png differ diff --git a/manual-assets/common-application-libraries/libraries/en_US/fig/tip_assistant.jpg b/manual-assets/common-application-libraries/libraries/en_US/fig/tip_assistant.jpg new file mode 100755 index 000000000..d923a5427 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/en_US/fig/tip_assistant.jpg differ diff --git a/manual-assets/common-application-libraries/libraries/en_US/fig/welcome.png b/manual-assets/common-application-libraries/libraries/en_US/fig/welcome.png new file mode 100755 index 000000000..8af17886c Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/en_US/fig/welcome.png differ diff --git a/manual-assets/common-application-libraries/libraries/en_US/libraries.md b/manual-assets/common-application-libraries/libraries/en_US/libraries.md new file mode 100755 index 000000000..d7dffb2b9 --- /dev/null +++ b/manual-assets/common-application-libraries/libraries/en_US/libraries.md @@ -0,0 +1,104 @@ +# A library of commonly used applications|common-application-libraries| + +Welcome to UOS Desktop V20 Professional! The system has been adapted to **10** more than 100,000 popular applications in the market for you to download. In order to help you get started with the system faster, we have selected the following domestic alternative products for the common software of mainstream operating systems, you can refer to the following product list, go to the system **App Store** and other channels to download and use the application. + + + +## Input + +The "搜狗输入法“ and "百度拼音输入法" that commonly used by mainstream operating systems can continue to be used, or you can choose to use the following input methods. + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | --------------- | +| Input | 搜狗拼音输入法
万能拼音输入法
万能五笔
东方输入法
2345王牌输入法
极品五笔
QQ拼音输入法
智能云输入法
王码五笔输入法
手心输入法
火星文输入法
百度拼音输入法 | 搜狗输入法UOS版(预装)
讯飞输入法
华宇拼音输入法
小企鹅五笔拼音输入法
Sunpinyin-输入法 | App Store | + + + +## Office software + +You can use the following alternatives to the Office suite that you commonly use on major operating systems. + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------ | ----------------------------------------------------------------- | --------------- | +| Office documents | Microsoft Office | WPS Office
永中Office | App Store | +| PDF | Adobe Acrobat | WPS PDF
Master PDF编辑器
PdfMod-PDF文档编辑 | App Store | +| Mind mapping | XMind思维导图中文版 | 亿图脑图MindMaster思维导图
百度脑图网页版
MarkMind思维导图
draw.io流程图 | App Store | + + + +## Social Communications + +Instant messaging software and email software commonly used in mainstream operating systems can continue to be used. + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------ | ------------------------------------------------------------ | --------------- | +| Mailbox | Microsoft Outlook | UOS邮箱(预装)
QQ邮箱
WPS邮箱
Foxmail
网易邮箱大师 | App Store | +| Instant messaging | QT语音 | 微信
QQ
企业微信
腾讯会议
钉钉 | App Store | +| VoIP | 阿里通网络电话 | Twinkle-网络电话 | App Store | + + + +## Browser + +You can continue to use Google Chrome and Firefox, which are commonly used by major operating systems, or you can choose to use the following browsers. + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------------------------ | ------------------------------------------------------------ | --------------- | +| Browser | Google Chrome浏览器
Firefox火狐浏览器 | UOS浏览器(预装)
360安全浏览器
奇安信浏览器
QQ浏览器 | App Store | + + + +## Download tools + +You can continue to use "IDM and uTorrent", which are commonly used by major operating systems, or you can choose to use the following browser + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | -------------------------------------------- | -------------------------------------------------------- | --------------- | +| Downloader | IDM(Internet Download Manager)
uTorrent | UOS下载器(预装)
迅雷
Motrix
Uget-下载器 | App Store | + + + +## Web tools + +| The type of application | The type of application | The type of application | The type of application | +| ----------------------- | ----------------------- | ------------------------------------------------------------ | ----------------------- | +| Remote control | TeamViewer | UOS远程协助(预装)
向日葵远程控制
AnyDesk远程控制 | App Store | + + + +## Security protection + +| The type of application | The type of application | The type of application | The type of application | +| ----------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------- | +| Anti-virus software | Avira AntiVir
Avast Free Antivirus
卡巴斯基反病毒软件 | UOS安全中心(预装)
360终端安全防护系统
金山毒霸
SYL OS电脑管家
火绒终端安全管理系统
瑞星ESM防病毒系统 | App Store | + + + +## Compress and burn + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------------------ | ------------------------------------------------------------ | --------------- | +| Compress | WinRAR
WinZip
| UOS归档管理器(预装)
360压缩
7-Zip
Bandizip-压缩
Xarchive-压缩
PeaZip-压缩 | App Store | +| Burn | 虚拟光驱(DAEMON)
光盘刻录大师 | Nero-刻录
U盘ISO镜像刻录工具 | | + + + +## Dedicated software + +| The type of application | The name of the software | Domestic substitutions | How to download | +| ----------------------- | ------------------------ | --------------------------------------------------------------------- | --------------- | +| CAD | AutoCAD | 中望CAD
浩辰CAD
CAXA电子图板
CAD看图王
CAD快速看图
迷你CAD看图王 | App Store | + + + + + +## Join the community to answer your questions + +Welcome to scan the code on WeChat to join the official community of UOS and get intimate online services: **perfect use skills, fresh product information, interesting official activities**, etc. The group activity code are permanent validity. + +![community](./fig/community.png) + +You are welcome to scan the QR code on WeChat to open the UOS Tip Assistant mini program and view the tips online. + +![tip_assistant](./fig/tip_assistant.jpg) diff --git a/manual-assets/common-application-libraries/libraries/zh_CN/fig/community.png b/manual-assets/common-application-libraries/libraries/zh_CN/fig/community.png new file mode 100755 index 000000000..1b0329cde Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_CN/fig/community.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_CN/fig/tip_assistant.jpg b/manual-assets/common-application-libraries/libraries/zh_CN/fig/tip_assistant.jpg new file mode 100755 index 000000000..93f7c25a7 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_CN/fig/tip_assistant.jpg differ diff --git a/manual-assets/common-application-libraries/libraries/zh_CN/fig/welcome.png b/manual-assets/common-application-libraries/libraries/zh_CN/fig/welcome.png new file mode 100755 index 000000000..8af17886c Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_CN/fig/welcome.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_CN/libraries.md b/manual-assets/common-application-libraries/libraries/zh_CN/libraries.md new file mode 100755 index 000000000..ec465c937 --- /dev/null +++ b/manual-assets/common-application-libraries/libraries/zh_CN/libraries.md @@ -0,0 +1,104 @@ +# 常用应用库|common-application-libraries| + +欢迎使用统信桌面操作系统V20专业版!系统已适配 **10** 万余款市场流行应用任您下载。为了帮助您更快的上手系统,我们针对主流操作系统常用软件,精选以下国产替代产品,您可以对照下面产品列表,到系统 **应用商店** 等渠道下载并使用应用。 + + + +## 输入法 + +主流操作系统常用的“搜狗输入法、百度拼音输入法”均可以继续使用,也可以选择使用以下输入法。 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 输入法 | 搜狗拼音输入法
万能拼音输入法
万能五笔
东方输入法
2345王牌输入法
极品五笔
QQ拼音输入法
智能云输入法
王码五笔输入法
手心输入法
火星文输入法
百度拼音输入法 | 搜狗输入法UOS版(预装)
讯飞输入法
华宇拼音输入法
小企鹅五笔拼音输入法
Sunpinyin-输入法 | 应用商店 | + + + +## 办公软件 + +您在主流操作系统常用的Office套件,可以使用以下替代产品。 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ------------------- | ------------------------------------------------------------ | -------- | +| 办公文档 | Microsoft Office | WPS Office
永中Office | 应用商店 | +| PDF | Adobe Acrobat | WPS PDF
Master PDF编辑器
PdfMod-PDF文档编辑 | 应用商店 | +| 思维导图 | XMind思维导图中文版 | 亿图脑图MindMaster思维导图
百度脑图网页版
MarkMind思维导图
draw.io流程图 | 应用商店 | + + + +## 社交通讯 + +主流操作系统常用的即时通讯软件、邮箱软件均可以继续使用。 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ----------------- | ------------------------------------------------------------ | -------- | +| 邮箱 | Microsoft Outlook | UOS邮箱(预装)
QQ邮箱
WPS邮箱
Foxmail
网易邮箱大师 | 应用商店 | +| 即时通讯 | QT语音 | 微信
QQ
企业微信
腾讯会议
钉钉 | 应用商店 | +| 网络电话 | 阿里通网络电话 | Twinkle-网络电话 | 应用商店 | + + + +## 浏览器 + +主流操作系统常用的“Google Chrome浏览器、Firefox火狐浏览器”均可以继续使用,也可以选择使用以下浏览器。 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ------------------------------------------ | ------------------------------------------------------------ | -------- | +| 浏览器 | Google Chrome浏览器
Firefox火狐浏览器 | UOS浏览器(预装)
360安全浏览器
奇安信浏览器
QQ浏览器 | 应用商店 | + + + +## 下载工具 + +主流操作系统常用的“IDM、uTorrent”均可以继续使用,也可以选择使用以下浏览器。 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | -------------------------------------------- | -------------------------------------------------------- | -------- | +| 下载器 | IDM(Internet Download Manager)
uTorrent | UOS下载器(预装)
迅雷
Motrix
Uget-下载器 | 应用商店 | + + + +## 网络工具 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ---------- | ------------------------------------------------------------ | -------- | +| 远程控制 | TeamViewer | UOS远程协助(预装)
向日葵远程控制
AnyDesk远程控制 | 应用商店 | + + + +## 安全防护 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 安全杀毒 | Avira AntiVir
Avast Free Antivirus
卡巴斯基反病毒软件 | UOS安全中心(预装)
360终端安全防护系统
金山毒霸
SYL OS电脑管家
火绒终端安全管理系统
瑞星ESM防病毒系统 | 应用商店 | + + + +## 压缩刻录 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | ------------------------------------ | ------------------------------------------------------------ | -------- | +| 压缩 | WinRAR
WinZip
| UOS归档管理器(预装)
360压缩
7-Zip
Bandizip-压缩
Xarchive-压缩
PeaZip-压缩 | 应用商店 | +| 刻录 | 虚拟光驱(DAEMON)
光盘刻录大师 | Nero-刻录
U盘ISO镜像刻录工具 | | + + + +## 行业软件 + +| 应用类型 | 软件名称 | 国产替代产品 | 下载方式 | +| -------- | -------- | ------------------------------------------------------------ | -------- | +| CAD | AutoCAD | 中望CAD
浩辰CAD
CAXA电子图板
CAD看图王
CAD快速看图
迷你CAD看图王 | 应用商店 | + + + + + +## 加入社群为您答疑解惑 + +欢迎微信扫码加入统信官方社群,获取贴心的在线服务:**完善的使用技巧、新鲜的产品资讯、有趣的官方活动**,应有尽有,群活动码,永久有效。 + +![community](./fig/community.png) + +欢迎您微信扫码打开统信玩机助手小程序,在线查看玩机指南。 + +![tip_assistant](./fig/tip_assistant.jpg) diff --git a/manual-assets/common-application-libraries/libraries/zh_HK/fig/community.png b/manual-assets/common-application-libraries/libraries/zh_HK/fig/community.png new file mode 100755 index 000000000..940fc6568 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_HK/fig/community.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_HK/fig/tip_assistant.jpg b/manual-assets/common-application-libraries/libraries/zh_HK/fig/tip_assistant.jpg new file mode 100755 index 000000000..622053d28 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_HK/fig/tip_assistant.jpg differ diff --git a/manual-assets/common-application-libraries/libraries/zh_HK/fig/welcome.png b/manual-assets/common-application-libraries/libraries/zh_HK/fig/welcome.png new file mode 100755 index 000000000..8af17886c Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_HK/fig/welcome.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_HK/libraries.md b/manual-assets/common-application-libraries/libraries/zh_HK/libraries.md new file mode 100755 index 000000000..d31b861ee --- /dev/null +++ b/manual-assets/common-application-libraries/libraries/zh_HK/libraries.md @@ -0,0 +1,106 @@ +# 常用應用庫|common-application-libraries| + +歡迎使用統信桌面操作系統V20專業版!系統已適配 **10** 萬餘款市場流行應用任您下載。為了幫助您更快的上手系統,我們針對主流操作系統常用軟件,精選以下國產替代產品,您可以對照下面產品列表,到系統 **應用商店** 等渠道下載並使用應用。 + + + +## 輸入法 + +主流操作系統常用的“搜狗輸入法、百度拼音輸入法”均可以繼續使用,也可以選擇使用以下輸入法。 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 輸入法 | 搜狗拼音輸入法
萬能拼音輸入法
萬能五筆
東方輸入法
2345王牌輸入法
極品五筆
QQ拼音輸入法
智能雲輸入法
王碼五筆輸入法
手心輸入法
火星文輸入法
百度拼音輸入法 | 搜狗輸入法UOS版(預裝)
訊飛輸入法
華宇拼音輸入法
小企鵝五筆拼音輸入法
Sunpinyin-輸入法 | 應用商店 | + + + +## 辦公軟件 + +您在主流操作系統常用的Office套件,可以使用以下替代產品。 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| ---- | ---------------- | ----------------------------------------------------------------- | ---- | +| 辦公文檔 | Microsoft Office | WPS Office
永中Office | 應用商店 | +| PDF | Adobe Acrobat | WPS PDF
Master PDF編輯器
PdfMod-PDF文檔編輯 | 應用商店 | +| 思維導圖 | XMind思維導圖中文版 | 億圖腦圖MindMaster思維導圖
百度腦圖網頁版
MarkMind思維導圖
draw.io流程圖 | 應用商店 | + + + +## 社交通訊 + + 主流操作系統常用的即時通訊軟件、郵箱軟件均可以繼續使用。 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ----------------- | ------------------------------------------------------------ | -------- | +| 箱郵 | Microsoft Outlook | UOS郵箱(預裝)
QQ郵箱
WPS郵箱
Foxmail
網易郵箱大師 | 應用商店 | +| 即時通訊 | QT語音 | 微信
QQ
企业微信
腾讯会议
钉钉 | 應用商店 | +| 網絡電話 | 阿里通網絡電話 | Twinkle-網絡電話 | 應用商店 | + + + +## 瀏覽器 + +主流操作系統常用的“Google Chrome瀏覽器、Firefox火狐瀏覽器”均可以繼續使用,也可以選擇使用以下瀏覽器。 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------ | ------------------------------------------------------------ | -------- | +| 瀏覽器 | Google Chrome瀏覽器
Firefox火狐瀏覽器 | UOS瀏覽器(預裝)
360安全瀏覽器
奇安信瀏覽器
QQ瀏覽器 | 應用商店 | + + + + + +## 下載工具 + +主流操作系統常用的“IDM、uTorrent”均可以繼續使用,也可以選擇使用以下瀏覽器。 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | -------------------------------------------- | -------------------------------------------------------- | -------- | +| 下載器 | IDM(Internet Download Manager)
uTorrent | UOS下載器(預裝)
迅雷
Motrix
Uget-下載器 | 應用商店 | + + + +## 網絡工具 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ---------- | ------------------------------------------------------------ | -------- | +| 遠程控制 | TeamViewer | UOS遠程協助(預裝)
向日葵遠程控制
AnyDesk遠程控制 | 應用商店 | + + + +## 安全防護 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 安全殺毒 | Avira AntiVir
Avast Free Antivirus
卡巴斯基反病毒軟件 | UOS安全中心(預裝)
360終端安全防護系統
金山毒霸
SYL OS電腦管家
火絨終端安全管理系統
瑞星ESM防病毒系統 | 應用商店 | + + + +## 壓縮刻錄 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------ | ------------------------------------------------------------ | -------- | +| 壓縮 | WinRAR
WinZip
| UOS歸檔管理器(預裝)
360壓縮
7-Zip
Bandizip-壓縮
Xarchive-壓縮
PeaZip-壓縮 | 應用商店 | +| 刻錄 | 虛擬光驅(DAEMON)
光盤刻錄大師 | Nero-刻錄
USBISO鏡像刻錄工具 | | + + + +## 行業軟件 + +| 應用類型 | 軟件名稱 | 國產替代產品 | 下載方式 | +| ---- | ------- | --------------------------------------------------------------------- | ---- | +| CAD | AutoCAD | 中望CAD
浩辰CAD
CAXA電子圖板
CAD看圖王
CAD快速看圖
迷你CAD看圖王 | 應用商店 | + + + + + +## 加入社群為您答疑解惑 + +歡迎微信掃碼加入統信官方社群,獲取貼心的在線服務:**完善的使用技巧、新鮮的產品資訊、有趣的官方活動**,應有盡有,群活動碼,永久有效。 + +![community](./fig/community.png) + +歡迎您微信掃碼打開統信玩機助手小程序,在線查看玩機指南。 + +![tip_assistant](./fig/tip_assistant.jpg) diff --git a/manual-assets/common-application-libraries/libraries/zh_TW/fig/community.png b/manual-assets/common-application-libraries/libraries/zh_TW/fig/community.png new file mode 100755 index 000000000..b0b136cbf Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_TW/fig/community.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_TW/fig/tip_assistant.jpg b/manual-assets/common-application-libraries/libraries/zh_TW/fig/tip_assistant.jpg new file mode 100755 index 000000000..126f77252 Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_TW/fig/tip_assistant.jpg differ diff --git a/manual-assets/common-application-libraries/libraries/zh_TW/fig/welcome.png b/manual-assets/common-application-libraries/libraries/zh_TW/fig/welcome.png new file mode 100755 index 000000000..8af17886c Binary files /dev/null and b/manual-assets/common-application-libraries/libraries/zh_TW/fig/welcome.png differ diff --git a/manual-assets/common-application-libraries/libraries/zh_TW/libraries.md b/manual-assets/common-application-libraries/libraries/zh_TW/libraries.md new file mode 100755 index 000000000..8989f4c65 --- /dev/null +++ b/manual-assets/common-application-libraries/libraries/zh_TW/libraries.md @@ -0,0 +1,102 @@ +# 常用應用庫|common-application-libraries| + +歡迎使用統信桌面作業系統V20專業版!系統已適配 **10** 萬餘款市場流行應用任您下載。為了幫助您更快的上手系統,我們針對主流作業系統常用軟體,精選以下國產替代產品,您可以對照下面產品列表,到系統 **應用商店** 等渠道下載並使用應用。 + +## 輸入法 + +主流作業系統常用的“搜狗輸入法、百度拼音輸入法”均可以繼續使用,也可以選擇使用以下輸入法。 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 輸入法 | 搜狗拼音輸入法
萬能拼音輸入法
萬能五筆
東方輸入法
2345王牌輸入法
極品五筆
QQ拼音輸入法
智慧雲輸入法
王碼五筆輸入法
手心輸入法
火星文輸入法
百度拼音輸入法 | 搜狗輸入法UOS版(預裝)
訊飛輸入法
華宇拼音輸入法
小企鵝五筆拼音輸入法
Sunpinyin-輸入法 | 應用商店 | + + + +## 辦公軟體 + +您在主流作業系統常用的Office套件,可以使用以下替代產品。 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| ---- | ---------------- | --------------------------------------------------------------- | ---- | +| 辦公文件 | Microsoft Office | WPS Office
永中Office | 應用商店 | +| PDF | Adobe Acrobat | WPS PDF
Master PDF編輯器
PdfMod-PDF文件編輯 | 應用商店 | +| 心智圖 | XMind心智圖中文版 | 億圖腦圖MindMaster心智圖
百度腦圖網頁版
MarkMind心智圖
draw.io流程圖 | 應用商店 | + + + +## 社交通訊 + +主流作業系統常用的即時通訊軟體、信箱軟體均可以繼續使用。 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | ----------------- | ------------------------------------------------------------ | -------- | +| 信箱 | Microsoft Outlook | UOS信箱(預裝)
QQ信箱
WPS信箱
Foxmail
網易信箱大師 | 應用商店 | +| 即時通訊 | QT語音 | 微信
QQ
企业微信
腾讯会议
钉钉 | 應用商店 | +| 網路電話 | 阿里通網路電話 | Twinkle-網路電話 | 應用商店 | + + + +## 瀏覽器 + +主流作業系統常用的“Google Chrome瀏覽器、Firefox火狐瀏覽器”均可以繼續使用,也可以選擇使用以下瀏覽器。 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------ | ------------------------------------------------------------ | -------- | +| 瀏覽器 | Google Chrome瀏覽器
Firefox火狐瀏覽器 | UOS瀏覽器(預裝)
360安全瀏覽器
奇安信瀏覽器
QQ瀏覽器 | 應用商店 | + + + +## 下載工具 + +主流作業系統常用的“IDM、uTorrent”均可以繼續使用,也可以選擇使用以下瀏覽器。 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | -------------------------------------------- | -------------------------------------------------------- | -------- | +| 下載器 | IDM(Internet Download Manager)
uTorrent | UOS下載器(預裝)
迅雷
Motrix
Uget-下載器 | 應用商店 | + + + +## 網路工具 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | ---------- | ------------------------------------------------------------ | -------- | +| 遠端控制 | TeamViewer | UOS遠端協助(預裝)
向日葵遠端控制
AnyDesk遠端控制 | 應用商店 | + + + +## 安全防護 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | +| 安全殺毒 | Avira AntiVir
Avast Free Antivirus
卡巴斯基反病毒软件 | UOS安全中心(預裝)
360終端安全防護系統
金山毒霸
SYL OS電腦管家
火絨終端安全管理系統
瑞星ESM防病毒系統 | 應用商店 | + + + +## 壓縮燒錄 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| -------- | -------------------------------------- | ------------------------------------------------------------ | -------- | +| 壓縮 | WinRAR
WinZip
| UOS歸檔管理器(預裝)
360壓縮
7-Zip
Bandizip-壓縮
Xarchive-壓縮
PeaZip-壓縮 | 應用商店 | +| 燒錄 | 虛擬光碟機(DAEMON)
光碟燒錄大師 | Nero-燒錄
隨身碟ISO鏡像燒錄工具 | | + + + +## 行業軟體 + +| 應用類型 | 軟體名稱 | 國產替代產品 | 下載方式 | +| ---- | ------- | --------------------------------------------------------------------- | ---- | +| CAD | AutoCAD | 中望CAD
浩辰CAD
CAXA電子圖板
CAD看圖王
CAD快速看圖
迷你CAD看圖王 | 應用商店 | + + + + + +## 加入社群為您答疑解惑 + +歡迎微信掃碼加入統信官方社群,獲取貼心的線上服務:**完善的使用技巧、新鮮的產品資訊、有趣的官方活動**,應有盡有,群活動碼,永久有效。 + +![community](./fig/community.png) + +歡迎您微信掃碼打開統信玩機助手小程式,線上查看玩機指南。 + +![tip_assistant](./fig/tip_assistant.jpg) diff --git a/manual-assets/learn-basic-operations/basic-operations/common/appstore.png b/manual-assets/learn-basic-operations/basic-operations/common/appstore.png new file mode 100755 index 000000000..a4f89e91d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/common/appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/common/computer.png b/manual-assets/learn-basic-operations/basic-operations/common/computer.png new file mode 100755 index 000000000..2227f8db3 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/common/computer.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/common/learn_basic_operations.svg b/manual-assets/learn-basic-operations/basic-operations/common/learn_basic_operations.svg new file mode 100644 index 000000000..cb35edccf --- /dev/null +++ b/manual-assets/learn-basic-operations/basic-operations/common/learn_basic_operations.svg @@ -0,0 +1,58 @@ + + + UOS快速上手手册/24px + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/manual-assets/learn-basic-operations/basic-operations/common/multitasking_view.png b/manual-assets/learn-basic-operations/basic-operations/common/multitasking_view.png new file mode 100755 index 000000000..b3ff23528 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/common/multitasking_view.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/common/text_recognition.png b/manual-assets/learn-basic-operations/basic-operations/common/text_recognition.png new file mode 100755 index 000000000..b62b1f51f Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/common/text_recognition.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/common/wifi.png b/manual-assets/learn-basic-operations/basic-operations/common/wifi.png new file mode 100755 index 000000000..99ab656c9 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/common/wifi.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/basic-operations.md b/manual-assets/learn-basic-operations/basic-operations/en_US/basic-operations.md new file mode 100755 index 000000000..4eb9f322a --- /dev/null +++ b/manual-assets/learn-basic-operations/basic-operations/en_US/basic-operations.md @@ -0,0 +1,213 @@ +# How to get started with UOS|learn-basic-operations| + +![welcome](./fig/welcome.png) + +## I. Getting Started Quickly + +UOS Desktop offers the same home screen layout mode as Windows - Efficient Mode. If you want to have a better visual effect, you can choose the stylish mode. + +**Schematic diagram of desktop layout:** + +![desktop](./fig/desktop.png) + +### 1. Launcher(Start) + +Users familiar with Windows know that using any function will start from the Start, such as finding/opening applications. In UOS, there is a start menu (Launcher) just like Windows, you can do the same operation as Windows Start in the Launcher. For more information about the use of the Launcher, please refer to **Manual-Desktop Environment-Launcher** or hit "F1" to open the Manual. + +![luncher](./fig/luncher.png) + +### 2. Dock + +![docker](./fig/docker.png) + +Like the Taskbar under Windows,UOS Dock also contains several partitions such as Quick Launch, Tray, Plugin and so on. The Quick Launch bar can fix your frequently-used applications for easy one-click opening. + +The icon Tray area allows you to set Bluetooth, network and other shortcut settings directly,You can also manage the tray by dragging the tray area icon and storing it in the tray window. + +![pallet](./fig/pallet.png) + +The Plugin Area displays frequently used actions and can also be customized through Control Center - Personalization - Dock. Frequently used plug-ins such as screenshot recording, system monitor, global search, etc. can be resided,Some plugins can also be dragged to the shortcut panel for management, which is both beautiful and convenient. + +![quick_panel](./fig/quick_panel.png) + +### 3.Computer (This PC) + +**Computer under UOS** + +The same as Windows Explorer,UOS File Manager can manage files as well as the Desktop, and the Desktop defaults to display "Computer" img, which is equivalent to Windows' "This PC". + +![filemanager](./fig/filemanager.png) + +**Set up quick access to frequently used folders** + +You can adjust the sidebar and drag and drop to adjust the sorting of frequently used folders. Or you can fix the folders you need to see at any time to the sidebar navigation by "Pin to quick access" in the right-click menu. You can make the file manager more suitable for your personal use. + +![File_right_click](./fig/File_right_click.png) + +**Convenient right-click menu** + +Frequently used functions such as printing files, compressing files, and sending files quickly can be found in the right-click menu of the file. + +![right_click](./fig/right_click.png) + +More use of the file manager can be seen in **Manual - File Manager**, or [click on the link](https://www.bilibili.com/video/BV1dT411574j/?share_source=copy_web&vd_source= 76cf82177880a7aa76195eee437b80a6) to watch the video. + +### 4. App Store + +UOS cannot install windows application format (exe) downloaded directly from the internet, but provides a channel for safe and rich application downloads - **App Store** img。 + +You can download and install different versions of WPS, WeChat, Nail, Sogou Input Method and other apps that you need for your office environment, and it is recommended that you directly choose the apps with the "Recommended" logo to install. + +![appstore](./fig/appstore.png) + +## II. Common office functions + +### 1. Window management + +**Application split screen** + +When you need to view the contents of two app windows at the same time, you can trigger the app split-screen operation by dragging and dropping the app to the left and right edges of the screen, which will help improve your processing efficiency. + +![splitscreen](./fig/splitscreen.png) + +**Switching windows** + +By using the "Alt+Tab" shortcut, you can quickly switch between multiple app windows and find open apps just like in Windows. + +![alttab](./fig/alttab.png) + +**View all windows** + +If you have more windows open, you can use the taskbar to open the "Multitasking View" by clicking img to open "Multitasking View", or the shortcut key "Super (Win icon key) + S The shortcut key "Super (Win icon key) + S", together with the mouse, will allow you to select any application window for switching. + +![multitaking_view](./fig/multitaking_view.png) + +### 2. Extracting text content from screenshots + +When you have a favorite text in a picture, or some webpage content can not be copied, you can use the system comes with the screenshot recording screen to take a screenshot of it, and then in the toolbar click on the imgicon in the toolbar, you can extract the text from the screenshot and copy it to other places or download it locally, and then you can save it or share it with others. + +![screenshot](./fig/screenshot.png) + +### 3. Learn more about shortcut key operations + +**System shortcuts** + +| Copy | Cut | Paste | +| :----------------------------: | :---------------------: | :----------------------: | +| Ctrl+C | Ctrl+X | Ctrl+V | +| **Undo** | **Print** | **Close Window** | +| Ctrl+Z | Ctrl+P | Alt+W | +| **Switch windows** | **Global search** | **Lock screen** | +| Alt+Tab | Shift+空格 | Super(win)+L | +| **Switch Screen Display Mode** | **Graphic Recognition** | **Scrolling Screenshot** | +| Super(win)+P | Ctrl+Alt+C | Ctrl+Alt+I | +| **Screenshot** | **Recording** | **Shutdown Screen** | +| Ctrl+Alt+A | Ctrl+Alt+R | Ctrl+Alt+Delete | + +Note: UOS is compatible with the Windows keys, but calls them "Super Keys". + +**Application shortcuts** + +| Browser | | +| ----------------------------- | ----------------------------: | +| Reopen closed tabs | Ctrl+Shift+T | +| switch to next tab | Ctrl+Tab or Ctrl+PageDown | +| switch to previous tab | Ctrl+Shift+Tab or Ctrl+PageUp | +| close current tab | Ctrl+W or Ctrl+F4 | +| **Input Methods** | | +| Rotate to switch input method | Ctrl+Shift | +| Enable/disable input method | Ctrl+Space | +| Chinese and English Switching | Shift | + +Use the shortcut key "Ctrl + Shift + /" inside the application window to see more application shortcuts introduced. + +## III. Setting up your personalized desktop + +With the gradual familiarization with the UOS, do you want to create your own desktop, then start from the wallpaper settings. + +### 1. Wallpaper screensaver settings + +**Set wallpaper:** Click "Wallpaper and Screensaver" in the desktop context menu to select your favorite wallpaper at the bottom of the desktop, or customize your photo as wallpaper. For more personalized wallpapers, go to the App Store and search for wallpapers to download. + +此处缺少图片 + +SourceURL:file:///home/gogo/Downloads/Get started with UOS 待翻译 en.docx + +**Screensaver Settings:** The same entry point as the wallpaper settings, just click on the "Screensaver" settings can be, you can also click on the "Custom Screensaver" will be set to rotate a group of pictures as a screensaver, in the setup pop-up window can be set to rotate the rotation interval and random rotation. + +此处缺少图片 + +The Control Center also offers more setting features, which can be explored in Control Center - Personalization. + +### 2. External screen setup + +When using the extended mode, if you need to adjust the screen splicing, you can go to "Control Center - Display" to set. Use the mouse** to drag** the screen thumbnail to adjust the relative position of the screen, which corresponds to the position of the two screens in reality, so as to achieve a better using experience. + +![controlcenter_display](./fig/controlcenter_display.png) + +## IV. Frequently Asked Questions + +For more questions and answers, please visit [FAQ]( https://faq.uniontech.com/) + +### 1. How to clean up your system + +The Cleanup" function of Security Center can clean up invalid files and data to free up disk space. Open Security Center, check the type of data you want to clean up, click "Scan Now" to scan for junk files, then select what you want to clean up and click "Clean Up", which is easy to operate. + +![securitycenter_garbageremoval](./fig/securitycenter_garbageremoval.png) + +### 2. How do I monitor the status of my system + +During system operation, an application may take up too many resources and cause the system to lag. In this case, you can turn on System Monitor to end the process of the application that takes up too much resources and is not in use, so as to ensure the smoothness of the system. + +systemmonitorsystemmonitor_sidebar + +### 3. How to connect a printer + +In the Print Manager interface, click the Add button to enter the Add Printer interface. The application will automatically recognize and list the shared printers currently scanned on the network. After selecting a printer, the application will automatically recommend the best driver and click Install to complete the installation. Of course, you can search for printers on your local network manually or through URI search. + +For other ways to add printers, check out **Manual - Print Manager**. + +![printer](./fig/printer.png) + +### 4. How do I connect to the network + +If you can't open a web page in your browser, you need to check if you are connected to a wired or wireless network. You can click on the WiFi icon in the taskbar-tray area wifi, select the name of the WiFi you want to connect to and enter the password, or plug in a cable and enable a wired connection. + +In general, enterprise network access has its own security authentication scheme. If you need to configure network security authentication, you can go to Control Center-Network and configure wired network or wireless network as needed. To learn more, you can [click the link](https://www.bilibili.com/video/BV1ZT41157dp/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6) Watch the video. + +![controcenter_wifi](./fig/controlcenter_wifi.png) + +### 5. How to adjust the input method + +In Control Center - Keyboard and Language - Input Method Settings, click Edit button to select the input method you need to remove or drag to adjust the order of input methods. If accidentally removed by mistake, just click Add button, select the input method and confirm the addition, then you can get back the input method you deleted by mistake before. + +![controlcenter_input](./fig/controlcenter_input.png) + +## V. Join the community to answer your questions and solve your problems + +Welcome to WeChat sweeping code to join the official community of TUNISON, get intimate online services: **perfect use of skills, fresh product information, interesting official activities **, everything, group activity code, permanently valid. + +![community](./fig/community.png) + +You are welcome to scan the QR code on WeChat to open the UOS Tip Assistant mini program and view the tips online. + +![tip_assistant](./fig/tip_assistant.jpg) + + + + + + + + + + + + + + + + + + + diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/File_right_click.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/File_right_click.png new file mode 100755 index 000000000..04448b62a Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/File_right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver.png new file mode 100755 index 000000000..c5d162d37 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver_options.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver_options.png new file mode 100755 index 000000000..02b3069e2 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Screensaver_options.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper.png new file mode 100755 index 000000000..2c7a90439 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_appstore.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_appstore.png new file mode 100755 index 000000000..870c9698c Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_color.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_color.png new file mode 100755 index 000000000..5c8ca6d76 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/Wallpaper_color.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/alttab.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/alttab.png new file mode 100755 index 000000000..44f1224de Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/alttab.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/appstore.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/appstore.png new file mode 100755 index 000000000..909b61cdd Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/community.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/community.png new file mode 100755 index 000000000..5dff086d3 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/community.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_input.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_input.png new file mode 100755 index 000000000..71e21ad96 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_input.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_wifi.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_wifi.png new file mode 100755 index 000000000..537bc5a18 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/controlcenter_wifi.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/desktop.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/desktop.png new file mode 100755 index 000000000..d7fe51f17 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/desktop.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/docker.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/docker.png new file mode 100755 index 000000000..e831da0d4 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/docker.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/filemanager.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/filemanager.png new file mode 100755 index 000000000..bd6286d5e Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/filemanager.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/luncher.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/luncher.png new file mode 100755 index 000000000..f30c57200 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/luncher.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/multitaking_view.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/multitaking_view.png new file mode 100755 index 000000000..5d893f23d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/multitaking_view.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/pallet.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/pallet.png new file mode 100755 index 000000000..a61055d92 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/pallet.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/printer.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/printer.png new file mode 100755 index 000000000..5c4e03358 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/printer.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/quick_panel.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/quick_panel.png new file mode 100755 index 000000000..aed3701fc Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/quick_panel.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/right_click.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/right_click.png new file mode 100755 index 000000000..d803c6deb Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/screenshot.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/screenshot.png new file mode 100755 index 000000000..56caedfc3 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/screenshot.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/securitycenter_garbageremoval.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/securitycenter_garbageremoval.png new file mode 100755 index 000000000..14f670b27 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/securitycenter_garbageremoval.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/splitscreen.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/splitscreen.png new file mode 100755 index 000000000..53b32649d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/splitscreen.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor.png new file mode 100755 index 000000000..0641b1f03 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor_sidebar.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor_sidebar.png new file mode 100755 index 000000000..d7b6dfe12 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/systemmonitor_sidebar.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/tip_assistant.jpg b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/tip_assistant.jpg new file mode 100755 index 000000000..d923a5427 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/tip_assistant.jpg differ diff --git a/manual-assets/learn-basic-operations/basic-operations/en_US/fig/welcome.png b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/welcome.png new file mode 100755 index 000000000..3b79b18ec Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/en_US/fig/welcome.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/basic-operations.md b/manual-assets/learn-basic-operations/basic-operations/zh_CN/basic-operations.md new file mode 100755 index 000000000..0bd809744 --- /dev/null +++ b/manual-assets/learn-basic-operations/basic-operations/zh_CN/basic-operations.md @@ -0,0 +1,209 @@ +# 如何快速上手UOS|learn-basic-operations| + +![welcome](./fig/welcome.png) + +## 一、快速上手 + +统信UOS桌面提供与 Windows 相同的主屏布局模式-高效模式。如果希望有更好的视觉效果,可选择时尚模式。 + +**桌面布局示意图:** + +![desktop](./fig/desktop.png) + +### 1. 启动器(开始菜单) + +熟悉Windows的用户都知道,使用任何功能都会从开始菜单开始,例如查找/打开应用。在统信UOS中,也有和Windows一样的开始菜单(启动器),您可以在启动器里完成和Windows开始菜单一样的操作。更多启动器的使用可查看**帮助手册-桌面环境-启动器**,敲击“F1”按键打开帮助手册。 + +![luncher](./fig/luncher.png) + +### 2. 任务栏 + +![docker](./fig/docker.png) + +和Windows下的任务栏一样,统信UOS任务栏也包含了快捷启动、托盘、插件等多个分区。快捷启动栏可以固定您常用应用,方便一键打开。 + +图标托盘区可以直接设置蓝牙、网络等快捷设置,您也可以通过拖拽托盘区图标,将托盘收纳进托盘窗口进行管理。 + +![pallet](./fig/pallet.png) + +插件区会显示常用操作,还可以通过控制中心-个性化-任务栏中进行自定义设置。可驻留截图录屏、系统监视器、全局搜索等常用插件,也可将部分插件拖拽至快捷面板进行管理,既美观又方便。 + +![quick_panel](./fig/quick_panel.png) + +### 3. 文件管理器(我的电脑) + +**统信UOS下的“我的电脑”** + +同Windows的资源管理器,统信UOS文件管理器和桌面一样可对文件进行管理,桌面默认显示“计算机”img,等同于 Windows 的“此电脑”。 + +![filemanager](./fig/filemanager.png) + +**为常用文件夹设置快速入口** + +您可通过调整侧边栏,拖拽调整常用的文件夹排序方式。或将需要随时查看的文件夹,通过右键菜单中的“添加到快捷访问”,固定到侧边栏导航中。可让文件管理器更合适您个人的使用习惯。 + +![File_right_click](./fig/File_right_click.png) + +**便捷的右键菜单** + +打印文件、压缩文件、快捷发送文件等常用功能,都可以在文件的右键菜单中找到。 + +![right_click](./fig/right_click.png) + +更多文件管理器的使用可查看**帮助手册-文件管理器**,或[点击链接](https://www.bilibili.com/video/BV1dT411574j/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)观看视频。 + +### 4. 应用商店 + +统信UOS无法安装直接从网络上下载的windows应用程序格式(exe),但提供安全、丰富的应用程序下载的渠道——**应用商店**img。 + +可下载安装办公环境需要的 WPS、企业微信、钉钉、搜狗输入法等应用的不同版本,建议直接选择带“推荐”标识的应用安装。 + +![appstore](./fig/appstore.png) + +## 二、办公常用功能 + +### 1. 窗口管理 + +**应用分屏** + +当您需要同时查看两个应用窗口内容时,可以通过拖拽应用到屏幕左右边缘触发应用分屏操作,将有助于提高您的处理效率。 + +![splitscreen](./fig/splitscreen.png) + +**切换窗口** + +通过使用“Alt+Tab”快捷键,您可以和在Windows下一样,在多个应用窗口之间快速切换,快速找到已打开应用。 + +![alttab](./fig/alttab.png) + +**查看所有窗口** + +而您开启的窗口数量较多时,可以使用任务栏单击 img 打开“多任务视图”,或快捷键“Super(Win 图标按键)+ S”,配合鼠标就能选中任意应用窗口进行切换。 + +![multitaking_view](./fig/multitaking_view.png) + +### 2. 从截图中提取文字内容 + +当您遇到图片中有喜欢的文字,或某些网页内容无法复制时,您可以使用系统自带的截图录屏对其截图,随后在工具栏中点击img图标,就可以从截图中提取文字复制到其他地方或下载到本地,进而可以保存或分享给其他人。 + +![screenshot](./fig/screenshot.png) + +### 3. 了解更多快捷键操作 + +**系统快捷键** + +| 复制 | 剪切 | 粘贴 | +| :------------------: | :----------: | :-------------: | +| Ctrl+C | Ctrl+X | Ctrl+V | +| **撤销** | **打印** | **关闭窗口** | +| Ctrl+Z | Ctrl+P | Alt+W | +| **切换窗口** | **全局搜索** | **锁屏** | +| Alt+Tab | Shift+空格 | Super(win)+L | +| **切换屏幕显示模式** | **图文识别** | **滚动截图** | +| Super(win)+P | Ctrl+Alt+C | Ctrl+Alt+I | +| **截图** | **录屏** | **关机界面** | +| Ctrl+Alt+A | Ctrl+Alt+R | Ctrl+Alt+Delete | + +注:统信UOS能够兼容Windows键,但是将其称作“超级键”(Super键)。 + +**应用快捷键** + +| 浏览器 | | +| -------------------- | --------------------------: | +| 重新打开关闭的标签页 | Ctrl+Shift+T | +| 切换到下一个标签 | Ctrl+Tab或Ctrl+PageDown | +| 切换到上一个标签 | Ctrl+Shift+Tab或Ctrl+PageUp | +| 关闭当前标签 | Ctrl+W或Ctrl+F4 | +| **输入法** | | +| 轮序切换输入法 | Ctrl+Shift | +| 开启/关闭输入法 | Ctrl+空格 | +| 中英文切换 | Shift | + +在应用窗口内使用快捷键“Ctrl + Shift + / ”查看更多应用快捷键介绍。 + +## 三、设置您的个性化桌面 + +随着对统信UOS的逐渐熟悉,您是否想打造属于自己的桌面,那就从壁纸设置开始吧。 + +### 1. 壁纸屏保设置 + +**设置壁纸:**在桌面右键菜单中点击“壁纸与屏保”,进入控制中心选择您喜欢的壁纸,您可以切换选择图片壁纸或纯色壁纸,也可以自定义照片或颜色。如果想获取更多个性化壁纸,还可以前往应用商店搜索壁纸进行下载。 + +wallpeperwallpeper_colorwallpaper_appstore + +**屏保设置:**在控制中心-个性化-屏幕保护中,可以选择您喜欢的屏保。选择图片轮播屏保后,单击“屏保设置”可以将一组图片设置为轮播屏保,在设置弹窗中还可以设置轮播间隔和随机轮播。 + +screensaverscreensaver_options + +### 2. 外接屏幕设置 + +使用扩展模式时,如果您需要调整屏幕的拼接方式,可以前往“控制中心-显示”进行设置。使用鼠标**拖动**屏幕缩略图调整屏幕相对位置,与现实中两个屏幕的位置相对应,可以达到更好的使用体验。 + +![controlcenter_display](./fig/controlcenter_display.png) + +## 四、常见问题解答 + +更多问题解答,请访问 [FAQ]( https://faq.uniontech.com/) + +### 1. 如何清理系统垃圾 + +安全中心的“垃圾清理”功能,可以清理无效的文件及数据,以释放磁盘空间。打开安全中心,勾选要清理的数据类型,点击“扫描”后会进行垃圾文件扫描,然后选择要清理的内容,并点击“立即清理”,操作便捷。 + +![securitycenter_garbageremoval](./fig/securitycenter_garbageremoval.png) + +### 2. 如何监控系统状态 + +在系统运行过程中,可能某个应用占用太多资源导致系统卡顿。此时您可以打开系统监视器,结束占用过高且未在使用的应用软件进程,从而保障系统流畅。 + +systemmonitorsystemmonitor_sidebar + +### 3. 如何连接打印机 + +在打印管理器界面,点击添加按钮,进入添加打印机界面。应用将自动识别,并列出当前网络扫描到的共享打印机。选择打印后,应用会自动推荐最优驱动,点击安装完成后即可进行文档打印。当然您可以通过手动查找、URI查找精准查找局域网内的打印机。 + +如果需要了解其它添加打印机的方式,可查阅**帮助手册-打印管理器**。 + +![printer](./fig/printer.png) + +### 4. 如何连接网络 + +如果您在浏览器中无法打开网页,需检查是否已经连接有线网络或无线网络。您可在任务栏-托盘区域点击WiFi图标wifi,选择需要连接的WiFi名称并输入密码,或者插入网线并启用有线连接。 + +一般情况,企业网络访问有自己的安全认证方案,如需配置网络安全认证,可前往控制中心-网络,按需配置有线网络或无线网络即可。如需了解更多,可[点击链接](https://www.bilibili.com/video/BV1ZT41157dp/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)观看视频。 + +![controcenter_wifi](./fig/controlcenter_wifi.png) + +### 5. 如何调整输入法 + +在控制中心-键盘和语言-输入法设置中,点击编辑按钮,选择需要移除的输入法,或拖动调整输入法的顺序。如果不小心错误移除,只需点击添加按钮,选择输入法并确认添加,就能找回之前误删的输入法。 + +![controlcenter_input](./fig/controlcenter_input.png) + +## 五、加入社群为您答疑解惑 + +欢迎微信扫码加入统信官方社群,获取贴心的在线服务:**完善的使用技巧、新鲜的产品资讯、有趣的官方活动**,应有尽有,群活动码,永久有效。 + +![community](./fig/community.png) + +欢迎您微信扫码打开统信玩机助手小程序,在线查看玩机指南。 + +![tip_assistant](./fig/tip_assistant.jpg) + + + + + + + + + + + + + + + + + + + diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/File_right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/File_right_click.png new file mode 100755 index 000000000..7bf07a8dd Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/File_right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/alttab.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/alttab.png new file mode 100755 index 000000000..a7e1d1be1 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/alttab.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/appstore.png new file mode 100755 index 000000000..2447203c1 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/community.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/community.png new file mode 100755 index 000000000..1b0329cde Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/community.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_display.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_display.png new file mode 100755 index 000000000..969685fb5 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_display.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_input.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_input.png new file mode 100755 index 000000000..1de3b6e1c Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_input.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_wifi.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_wifi.png new file mode 100755 index 000000000..a151dd0bb Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/controlcenter_wifi.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/desktop.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/desktop.png new file mode 100755 index 000000000..e2517fac0 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/desktop.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/docker.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/docker.png new file mode 100755 index 000000000..603cc98ba Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/docker.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/filemanager.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/filemanager.png new file mode 100755 index 000000000..6774f862e Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/filemanager.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/luncher.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/luncher.png new file mode 100755 index 000000000..aba217d5b Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/luncher.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/multitaking_view.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/multitaking_view.png new file mode 100755 index 000000000..36e1c7550 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/multitaking_view.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/pallet.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/pallet.png new file mode 100755 index 000000000..a61055d92 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/pallet.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/printer.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/printer.png new file mode 100755 index 000000000..4aef94ced Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/printer.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/quick_panel.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/quick_panel.png new file mode 100755 index 000000000..5d501feff Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/quick_panel.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/right_click.png new file mode 100755 index 000000000..754659972 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver.png new file mode 100755 index 000000000..71d9698dd Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver_options.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver_options.png new file mode 100755 index 000000000..1090b275f Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screensaver_options.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screenshot.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screenshot.png new file mode 100755 index 000000000..15f81695f Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/screenshot.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/securitycenter_garbageremoval.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/securitycenter_garbageremoval.png new file mode 100755 index 000000000..4e6d3bbab Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/securitycenter_garbageremoval.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/splitscreen.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/splitscreen.png new file mode 100755 index 000000000..254b62517 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/splitscreen.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor.png new file mode 100755 index 000000000..a2c7db781 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor_sidebar.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor_sidebar.png new file mode 100755 index 000000000..ffaec560b Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/systemmonitor_sidebar.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/tip_assistant.jpg b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/tip_assistant.jpg new file mode 100755 index 000000000..93f7c25a7 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/tip_assistant.jpg differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper.png new file mode 100755 index 000000000..ee3a74f8e Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_appstore.png new file mode 100755 index 000000000..81cd00f5a Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_color.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_color.png new file mode 100755 index 000000000..6a73dc1e9 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/wallpaper_color.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/welcome.png b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/welcome.png new file mode 100755 index 000000000..939375498 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_CN/fig/welcome.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/basic-operations.md b/manual-assets/learn-basic-operations/basic-operations/zh_HK/basic-operations.md new file mode 100755 index 000000000..743c93d42 --- /dev/null +++ b/manual-assets/learn-basic-operations/basic-operations/zh_HK/basic-operations.md @@ -0,0 +1,192 @@ +# 如何快速上手UOS|learn-basic-operations| + +![welcome](./fig/welcome.png) + +## 一、快速上手 + +統信UOS桌面提供與 Windows 相同的主屏佈局模式-高效模式。如果希望有更好的視覺效果,可選擇時尚模式。 + +**桌面佈局示意圖:** + +![desktop](./fig/desktop.png) + +### 1. 啟動器(開始菜單) + +熟悉Windows的用戶都知道,使用任何功能都會從開始菜單開始,例如查找/打開應用。在統信UOS中,也有和Windows一樣的開始菜單(啟動器),您可以在啟動器裏完成和Windows開始菜單一樣的操作。更多啟動器的使用可查看**幫助手冊-桌面環境-啟動器**,敲擊“F1”按鍵打開幫助手冊。 + +![luncher](./fig/luncher.png) + +### 2. 任務欄 + +![docker](./fig/docker.png) + +和Windows下的任務欄一樣,統信UOS任務欄也包含了快捷啟動、托盤、插件等多個分區。快捷啟動欄可以固定您常用應用,方便一鍵打開。 + +圖標托盤區可以直接設置藍牙、網絡等快捷設置,您也可以通過拖拽托盤區圖標,將托盤收納進托盤窗口進行管理。 + +![pallet](./fig/pallet.png) + +插件區會顯示常用操作,還可以通過控制中心-個性化-任務欄中進行自定義設置。可駐留截圖錄屏、系統監視器、全局搜索等常用插件,也可將部分插件拖拽至快捷面板進行管理,既美觀又方便。 + +![quick_panel](./fig/quick_panel.png) + +### 3. 文件管理器(我的电脑) + +**統信UOS下的“我的電腦”** + +同Windows的資源管理器,統信UOS文件管理器和桌面一樣可對文件進行管理,桌面默認顯示“計算機”img,等同于 Windows 的“此电脑”。 + +![filemanager](./fig/filemanager.png) + +**為常用文件夾設定快速入口** + +您可通過調整側邊欄,拖拽調整常用的文件夾排序方式。或將需要隨時查看的文件夾,通過右鍵菜單中的“添加到快捷訪問”,固定到側邊欄導航中。可讓文件管理器更合適您個人的使用習慣。 + +![File_right_click](./fig/File_right_click.png) + +**便捷的右鍵菜單** + +打印文件、壓縮文件、快捷發送文件等常用功能,都可以在文件的右鍵菜單中找到。 + +![right_click](./fig/right_click.png) + +更多文件管理器的使用可查看**幫助手冊-文件管理器**,或[點擊鏈接](https://www.bilibili.com/video/BV1dT411574j/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)觀看影片。 + +### 4. 應用商店 + +統信UOS無法安裝直接從網絡上下載的windows應用程式格式(exe),但提供安全、豐富的應用程式下載的渠道——**應用商店**img。 + +可下載安裝辦公環境需要的 WPS、企業微信、釘釘、搜狗輸入法等應用的不同版本,建議直接選擇帶“推薦”標識的應用安裝。 + +![appstore](./fig/appstore.png) + +## 二、辦公常用功能 + +### 1. 窗口管理 + +**應用分屏** + +當您需要同時查看兩個應用窗口內容時,可以通過拖拽應用到螢幕左右邊緣觸發應用分屏操作,將有助於提高您的處理效率。 + +![splitscreen](./fig/splitscreen.png) + +**切換窗口** + +通過使用“Alt+Tab”快捷鍵,您可以和在Windows下一樣,在多個應用窗口之間快速切換,快速找到已打開應用。 + +![alttab](./fig/alttab.png) + +**查看所有窗口** + +而您開啟的窗口數量較多時,可以使用任務欄單擊 img 打開“多任務視圖”,或快捷鍵“Super(Win 圖標按鍵)+ S”,配合鼠標就能選中任意應用窗口進行切換。 + +![multitaking_view](./fig/multitaking_view.png) + +### 2. 從截圖中提取文字內容 + +當您遇到圖片中有喜歡的文字,或某些網頁內容無法複製時,您可以使用系統自帶的截圖錄屏對其截圖,隨後在工具欄中點擊img圖標,就可以從截圖中提取文字複製到其他地方或下載到本地,進而可以保存或分享給其他人。 + +![screenshot](./fig/screenshot.png) + +### 3. 了解更多快捷鍵操作 + +**系統快捷鍵** + +| 複製 | 剪切 | 黏貼 | +| :------------------: | :----------: | :-------------: | +| Ctrl+C | Ctrl+X | Ctrl+V | +| **撤銷** | **打印** | **關閉窗口** | +| Ctrl+Z | Ctrl+P | Alt+W | +| **切換窗口** | **全局搜索** | **鎖定螢幕** | +| Alt+Tab | Shift+空格 | Super(win)+L | +| **切換螢幕顯示模式** | **圖文識別** | **滾動截圖** | +| Super(win)+P | Ctrl+Alt+C | Ctrl+Alt+I | +| **截圖** | **錄屏** | **關機界面** | +| Ctrl+Alt+A | Ctrl+Alt+R | Ctrl+Alt+Delete | + +註:統信UOS能夠兼容Windows鍵,但是將其稱作“超級鍵”(Super鍵)。 + +**應用快捷鍵** + +| 瀏覽器 | | +| -------------------- | --------------------------: | +| 重新打開關閉的標籤頁 | Ctrl+Shift+T | +| 切換到下一個標籤 | Ctrl+Tab或Ctrl+PageDown | +| 切換到上一個標籤 | Ctrl+Shift+Tab或Ctrl+PageUp | +| 關閉當前標籤 | Ctrl+W或Ctrl+F4 | +| **輸入法** | | +| 輪序切換輸入法 | Ctrl+Shift | +| 開啟/關閉輸入法 | Ctrl+空格 | +| 中英文切換 | Shift | + +在應用窗口內使用快捷鍵“Ctrl + Shift + / ”查看更多應用快捷鍵介紹。 + +## 三、設置您的個性化桌面 + +隨着對統信UOS的逐漸熟悉,您是否想打造屬於自己的桌面,那就從壁紙設置開始吧。 + +### 1. 壁紙螢幕保護程式設置 + +**設置壁紙:**在桌面右鍵菜單中點擊“壁紙與螢幕保護程式”,便可在桌面底部選擇您喜歡的壁紙,或自定義您的照片為壁紙。如果想獲取更多個性化壁紙,還可以前往應用商店搜索壁紙進行下載。 + +此处缺少图片 + +**螢幕保護程式設置:**與壁紙設置入口相同,只需點擊“螢幕保護程式”設置即可,也可以單擊“自定義螢幕保護程式”將一組圖片設置為輪播螢幕保護程式,在設置彈窗中還可以設置輪播間隔和隨機輪播。 + +此处缺少图片 + +控制中心也提供了更多設定功能,可探索控制中心-個性化。 + +### 2. 外接螢幕設定 + +使用擴展模式時,如果您需要調整螢幕的拼接方式,可以前往“控制中心-顯示”進行設置。使用鼠標**拖動**螢幕縮略圖調整螢幕相對位置,與現實中兩個螢幕的位置相對應,可以達到更好的使用體驗。 + +![controlcenter_display](./fig/controlcenter_display.png) + +## 四、常見問題解答 + +更多問題解答,請訪問 [FAQ]( https://faq.uniontech.com/) + +### 1. 如何清理系統垃圾 + +安全中心的“垃圾清理”功能,可以清理無效的文件及數據,以釋放磁盤空間。打開安全中心,勾選要清理的數據類型,點擊“掃描”後會進行垃圾文件掃描,然後選擇要清理的內容,並點擊“立即清理”,操作便捷。 + +![securitycenter_garbageremoval](./fig/securitycenter_garbageremoval.png) + +### 2. 如何監控系統狀態 + +在系統運行過程中,可能某個應用佔用太多資源導致系統卡頓。此時您可以打開系統監視器,結束佔用過高且未在使用的應用軟件進程,從而保障系統流暢。 + +systemmonitorsystemmonitor_sidebar + +### 3. 如何連接打印機 + +在打印管理器界面,點擊添加按鈕,進入添加打印機界面。應用將自動識別,並列出當前網絡掃描到的共享打印機。選擇打印後,應用會自動推薦最優驅動,點擊安裝完成後即可進行文檔打印。當然您可以通過手動查找、URI查找精準查找局域網內的打印機。 + +如果需要了解其他添加打印機的方式,可查閱**幫助手冊-打印管理器**。 + +![printer](./fig/printer.png) + +### 4. 如何連接網絡 + +如果您在瀏覽器中無法打開網頁,需檢查是否已經連接有線網絡或無線網絡。您可在任務欄-托盤區域點擊WiFi圖標wifi,選擇需要連接的WiFi名稱並輸入密碼,或者插入網線並啟用有線連接。 + +一般情況,企業網絡訪問有自己的安全認證方案,如需配置網絡安全認證,可前往控制中心-網絡,按需配置有線網絡或無線網絡即可。如需了解更多,可[點擊鏈接](https://www.bilibili.com/video/BV1ZT41157dp/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)觀看影片。 + +![controcenter_wifi](./fig/controlcenter_wifi.png) + +### 5. 如何調整輸入法 + +在控制中心-鍵盤和語言-輸入法設定中,點擊編輯按鈕,選擇需要移除的輸入法,或拖動調整輸入法的順序。如果不小心錯誤移除,只需點擊添加按鈕,選擇輸入法並確認添加,就能找回之前誤刪的輸入法。 + +![controlcenter_input](./fig/controlcenter_input.png) + +## 五、加入社群為您答疑解惑 + +歡迎微信掃碼加入統信官方社群,獲取貼心的在線服務:**完善的使用技巧、新鮮的產品資訊、有趣的官方活動**,應有盡有,群活動碼,永久有效。 + +![community](./fig/community.png) + +歡迎您微信掃碼打開統信玩機助手小程序,在線查看玩機指南。 + +![tip_assistant](./fig/tip_assistant.jpg) diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/File_right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/File_right_click.png new file mode 100755 index 000000000..b32e0ee83 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/File_right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver.png new file mode 100755 index 000000000..4f5c10bbf Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver_options.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver_options.png new file mode 100755 index 000000000..474f1694f Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Screensaver_options.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper.png new file mode 100755 index 000000000..4715bbbbb Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_appstore.png new file mode 100755 index 000000000..26545d6a6 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_color.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_color.png new file mode 100755 index 000000000..0e5723a06 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/Wallpaper_color.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/alttab.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/alttab.png new file mode 100755 index 000000000..55672a80d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/alttab.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/appstore.png new file mode 100755 index 000000000..152e831e4 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/community.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/community.png new file mode 100755 index 000000000..940fc6568 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/community.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_display.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_display.png new file mode 100755 index 000000000..969685fb5 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_display.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_input.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_input.png new file mode 100755 index 000000000..6c21ffc4d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_input.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_wifi.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_wifi.png new file mode 100755 index 000000000..d659655c9 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/controlcenter_wifi.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/desktop.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/desktop.png new file mode 100755 index 000000000..80246b1a5 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/desktop.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/docker.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/docker.png new file mode 100755 index 000000000..603cc98ba Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/docker.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/filemanager.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/filemanager.png new file mode 100755 index 000000000..64eee223b Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/filemanager.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/luncher.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/luncher.png new file mode 100755 index 000000000..0cf2f507d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/luncher.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/multitaking_view.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/multitaking_view.png new file mode 100755 index 000000000..08d7abb30 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/multitaking_view.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/pallet.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/pallet.png new file mode 100755 index 000000000..a61055d92 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/pallet.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/printer.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/printer.png new file mode 100755 index 000000000..839bd0056 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/printer.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/quick_panel.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/quick_panel.png new file mode 100755 index 000000000..411d40b47 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/quick_panel.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/right_click.png new file mode 100755 index 000000000..1a72b49f1 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/screenshot.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/screenshot.png new file mode 100755 index 000000000..28272b256 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/screenshot.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/securitycenter_garbageremoval.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/securitycenter_garbageremoval.png new file mode 100755 index 000000000..639bb43a0 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/securitycenter_garbageremoval.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/splitscreen.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/splitscreen.png new file mode 100755 index 000000000..254b62517 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/splitscreen.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor.png new file mode 100755 index 000000000..614dfafde Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor_sidebar.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor_sidebar.png new file mode 100755 index 000000000..6f1534e5c Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/systemmonitor_sidebar.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/tip_assistant.jpg b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/tip_assistant.jpg new file mode 100755 index 000000000..622053d28 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/tip_assistant.jpg differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/welcome.png b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/welcome.png new file mode 100755 index 000000000..06e9459f3 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_HK/fig/welcome.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/basic-operations.md b/manual-assets/learn-basic-operations/basic-operations/zh_TW/basic-operations.md new file mode 100755 index 000000000..f5ce9907e --- /dev/null +++ b/manual-assets/learn-basic-operations/basic-operations/zh_TW/basic-operations.md @@ -0,0 +1,211 @@ +# 如何快速上手UOS|learn-basic-operations| + +![welcome](./fig/welcome.png) + +## 一、快速上手 + +統信UOS桌面提供與 Windows 相同的主屏布局模式-高效模式。如果希望有更好的視覺效果,可選擇時尚模式。 + +**桌面布局示意圖:** + +![desktop](./fig/desktop.png) + +### 1.啟動器(開始選單) + +熟悉Windows的使用者都知道,使用任何功能都會從開始選單開始,例如尋找/打開應用。在統信UOS中,也有和Windows一樣的開始選單(啟動器),您可以在啟動器裡完成和Windows開始選單一樣的操作。更多啟動器的使用可查看**幫助手冊-桌面環境-啟動器**,敲擊“F1”按鍵打開幫助手冊。 + +![luncher](./fig/luncher.png) + +### 2. 任務欄 + +![docker](./fig/docker.png) + +和Windows下的任務欄一樣,統信UOS任務欄也包含了快捷啟動、工具列、外掛程式等多個分區。快捷啟動欄可以固定您常用應用,方便一鍵打開。 + +圖示工具列區可以直接設定藍牙、網路等快捷設定,您也可以透過拖曳工具列區圖示,將工具列收納進工具列視窗進行管理。 + +![pallet](./fig/pallet.png) + +外掛程式區會顯示常用操作,還可以透過控制中心-個性化-任務欄中進行自訂設定。可駐留截圖錄屏、系統監視器、全域搜尋等常用外掛程式,也可將部分外掛程式拖曳至快捷面板進行管理,既美觀又方便。 + +![quick_panel](./fig/quick_panel.png) + +### 3. 文件管理器(我的电脑) + +**統信UOS下的“我的電腦”** + +同Windows的資源管理器,統信UOS檔案管理器和桌面一樣可對文件進行管理,桌面預設顯示“電腦”img,等同於 Windows 的“此電腦”。 + +![filemanager](./fig/filemanager.png) + +**為常用文件夾設定快速入口** + +您可透過調整側邊欄,拖曳調整常用的資料夾排序方式。或將需要隨時查看的資料夾,透過右鍵選單中的“添加到快捷訪問”,固定到側邊欄導航中。可讓檔案管理器更合適您個人的使用習慣。 + +![File_right_click](./fig/File_right_click.png) + +**便捷的右鍵選單** + +列印文件、壓縮文件、快捷發送文件等常用功能,都可以在文件的右鍵選單中找到。 + +![right_click](./fig/right_click.png) + +更多檔案管理器的使用可查看**幫助手冊-檔案管理器**,或[點擊連結](https://www.bilibili.com/video/BV1dT411574j/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)觀看影片。 + +### 4. 應用商店 + +統信UOS無法安裝直接從網路上下載的windows應用程式格式(exe),但提供安全、豐富的應用程式下載的渠道——**應用商店**img。 + +可下載安裝辦公環境需要的 WPS、企業微信、釘釘、搜狗輸入法等應用的不同版本,建議直接選擇帶“推薦”標識的應用安裝。 + +![appstore](./fig/appstore.png) + +## 二、辦公常用功能 + +### 1. 視窗管理 + +**應用分屏** + +當您需要同時查看兩個應用視窗內容時,可以透過拖曳應用到螢幕左右邊緣觸發應用分屏操作,將有助於提高您的處理效率。 + +![splitscreen](./fig/splitscreen.png) + +**切換視窗** + +透過使用“Alt+Tab”快捷鍵,您可以和在Windows下一樣,在多個應用視窗之間快速切換,快速找到已打開應用。 + +![alttab](./fig/alttab.png) + +**查看所有視窗** + +而您開啟的視窗數量較多時,可以使用任務欄單擊 img 打開“多任務檢視”,或快捷鍵“Super(Win 圖示按鍵)+ S”,配合滑鼠就能選中任意應用視窗進行切換。 + +![multitaking_view](./fig/multitaking_view.png) + +### 2. 從截圖中提取文字內容 + +當您遇到圖片中有喜歡的文字,或某些網頁內容無法複製時,您可以使用系統內建的截圖錄屏對其截圖,隨後在工具列中點擊img圖示,就可以從截圖中提取文字複製到其他地方或下載到本機,進而可以儲存或分享給其他人。 + +![screenshot](./fig/screenshot.png) + +### 3. 了解更多快捷鍵操作 + +**系統快捷鍵** + +| 複製 | 剪下 | 貼上 | +| :------------------: | :----------: | :-------------: | +| Ctrl+C | Ctrl+X | Ctrl+V | +| **復原** | **列印** | **關閉視窗** | +| Ctrl+Z | Ctrl+P | Alt+W | +| **切換視窗** | **全域搜尋** | **锁屏** | +| Alt+Tab | Shift+空格 | Super(win)+L | +| **切換螢幕顯示模式** | **圖文識別** | **滾動截圖** | +| Super(win)+P | Ctrl+Alt+C | Ctrl+Alt+I | +| **截圖** | **錄屏** | **關機介面** | +| Ctrl+Alt+A | Ctrl+Alt+R | Ctrl+Alt+Delete | + +註:統信UOS能夠相容Windows鍵,但是將其稱作“超級鍵”(Super鍵)。 + +**應用快捷鍵** + +| 瀏覽器 | | +| ------------------ | --------------------------: | +| 重新打開關閉的分頁 | Ctrl+Shift+T | +| 切換到下一個標籤 | Ctrl+Tab或Ctrl+PageDown | +| 切換到上一個標籤 | Ctrl+Shift+Tab或Ctrl+PageUp | +| 關閉目前標籤 | Ctrl+W或Ctrl+F4 | +| **輸入法** | | +| 輪序切換輸入法 | Ctrl+Shift | +| 開啟/關閉輸入法 | Ctrl+空格 | +| 中英文切換 | Shift | + +在應用視窗內使用快捷鍵“Ctrl + Shift + / ”查看更多應用快捷鍵介紹。 + +## 三、設定您的個性化桌面 + +隨著對統信UOS的逐漸熟悉,您是否想打造屬於自己的桌面,那就從桌布設定開始吧。 + +### 1. 桌布螢幕保護程式設定 + +**設定桌布:**在桌面右鍵選單中點擊“桌布與螢幕保護程式”,便可在桌面底部選擇您喜歡的桌布,或自訂您的照片為桌布。如果想獲取更多個性化桌布,還可以前往應用商店搜尋桌布進行下載。 + +此处缺少图片 + +**螢幕保護程式設定:**與桌布設定入口相同,只需點擊“螢幕保護程式”設定即可,也可以單擊“自訂螢幕保護程式”將一組圖片設定為輪播螢幕保護程式,在設定跳出視窗中還可以設定輪播間隔和隨機輪播。 + +此处缺少图片 + +控制中心也提供了更多設定功能,可探索控制中心-個性化。 + +### 2. 外接螢幕設定 + +使用擴展模式時,如果您需要調整螢幕的拼接方式,可以前往“控制中心-顯示”進行設定。使用滑鼠**拖動**螢幕縮圖調整螢幕相對位置,與現實中兩個螢幕的位置相對應,可以達到更好的使用體驗。 + +![controlcenter_display](./fig/controlcenter_display.png) + +## 四、常見問題解答 + +更多問題解答,請訪問 [FAQ]( https://faq.uniontech.com/) + +### 1. 如何清理系統垃圾 + +安全中心的“垃圾清理”功能,可以清理無效的文件及資料,以釋放磁碟空間。打開安全中心,勾選要清理的資料類型,點擊“掃描”後會進行垃圾文件掃描,然後選擇要清理的內容,並點擊“立即清理”,操作便捷。 + +![securitycenter_garbageremoval](./fig/securitycenter_garbageremoval.png) + +### 2. 如何監控系統狀態? + +在系統執行過程中,可能某個應用占用太多資源導致系統卡頓。此時您可以打開系統監視器,結束占用過高且未在使用的應用軟體行程,從而保障系統流暢。 + +systemmonitorsystemmonitor_sidebar + +### 3. 如何連接印表機 + +在列印管理器介面,點擊添加按鈕,進入添加印表機介面。應用將自動識別,並列出目前網路掃描到的共享印表機。選擇列印後,應用會自動推薦最優驅動,點擊安裝完成後即可進行文件列印。當然您可以透過手動尋找、URI尋找精準尋找區域網路內的印表機。 + +如果需要了解其它添加印表機的方式,可查閱**幫助手冊-列印管理器**。 + +![printer](./fig/printer.png) + +### 4. 如何連接網路? + +如果您在瀏覽器中無法打開網頁,需檢查是否已經連接有線網路或無線網路。您可在任務欄-工具列區域點擊WiFi圖示wifi,選擇需要連接的WiFi名稱並輸入密碼,或者插入網路線並啟用有線連接。 + +一般情況,企業網路訪問有自己的安全認證方案,如需配置網路安全認證,可前往控制中心-網路,按需配置有線網路或無線網路即可。如需了解更多,可[點擊連結](https://www.bilibili.com/video/BV1ZT41157dp/?share_source=copy_web&vd_source=76cf82177880a7aa76195eee437b80a6)觀看影片。 + +![controcenter_wifi](./fig/controlcenter_wifi.png) + +### 5. 如何調整輸入法 + +在控制中心-鍵盤和語言-輸入法設定中,點擊編輯按鈕,選擇需要移除的輸入法,或拖動調整輸入法的順序。如果不小心錯誤移除,只需點擊添加按鈕,選擇輸入法並確認添加,就能找回之前誤刪的輸入法。 + +![controlcenter_input](./fig/controlcenter_input.png) + +## 五、加入社群為您答疑解惑 + +歡迎微信掃碼加入統信官方社群,獲取貼心的線上服務:**完善的使用技巧、新鮮的產品資訊、有趣的官方活動**,應有盡有,群活動碼,永久有效。 + +![community](./fig/community.png) + +歡迎您微信掃碼打開統信玩機助手小程式,線上查看玩機指南。 + +![tip_assistant](./fig/tip_assistant.jpg) + + + + + + + + + + + + + + + + + + + diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/File_right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/File_right_click.png new file mode 100755 index 000000000..b32e0ee83 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/File_right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver.png new file mode 100755 index 000000000..4f5c10bbf Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver_options.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver_options.png new file mode 100755 index 000000000..474f1694f Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Screensaver_options.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper.png new file mode 100755 index 000000000..4715bbbbb Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_appstore.png new file mode 100755 index 000000000..26545d6a6 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_color.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_color.png new file mode 100755 index 000000000..0e5723a06 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/Wallpaper_color.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/alttab.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/alttab.png new file mode 100755 index 000000000..55672a80d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/alttab.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/appstore.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/appstore.png new file mode 100755 index 000000000..152e831e4 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/appstore.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/community.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/community.png new file mode 100755 index 000000000..b0b136cbf Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/community.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_display.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_display.png new file mode 100755 index 000000000..969685fb5 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_display.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_input.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_input.png new file mode 100755 index 000000000..6c21ffc4d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_input.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_wifi.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_wifi.png new file mode 100755 index 000000000..d659655c9 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/controlcenter_wifi.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/desktop.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/desktop.png new file mode 100755 index 000000000..80246b1a5 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/desktop.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/docker.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/docker.png new file mode 100755 index 000000000..603cc98ba Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/docker.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/filemanager.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/filemanager.png new file mode 100755 index 000000000..64eee223b Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/filemanager.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/luncher.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/luncher.png new file mode 100755 index 000000000..0cf2f507d Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/luncher.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/multitaking_view.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/multitaking_view.png new file mode 100755 index 000000000..08d7abb30 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/multitaking_view.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/pallet.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/pallet.png new file mode 100755 index 000000000..a61055d92 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/pallet.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/printer.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/printer.png new file mode 100755 index 000000000..839bd0056 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/printer.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/quick_panel.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/quick_panel.png new file mode 100755 index 000000000..66d0cc227 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/quick_panel.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/right_click.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/right_click.png new file mode 100755 index 000000000..1a72b49f1 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/right_click.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/screenshot.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/screenshot.png new file mode 100755 index 000000000..28272b256 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/screenshot.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/securitycenter_garbageremoval.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/securitycenter_garbageremoval.png new file mode 100755 index 000000000..639bb43a0 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/securitycenter_garbageremoval.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/splitscreen.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/splitscreen.png new file mode 100755 index 000000000..254b62517 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/splitscreen.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor.png new file mode 100755 index 000000000..614dfafde Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor_sidebar.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor_sidebar.png new file mode 100755 index 000000000..6f1534e5c Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/systemmonitor_sidebar.png differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/tip_assistant.jpg b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/tip_assistant.jpg new file mode 100755 index 000000000..126f77252 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/tip_assistant.jpg differ diff --git a/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/welcome.png b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/welcome.png new file mode 100755 index 000000000..99d5bdd36 Binary files /dev/null and b/manual-assets/learn-basic-operations/basic-operations/zh_TW/fig/welcome.png differ diff --git a/manual-assets/video-guide/videos/01.png b/manual-assets/video-guide/videos/01.png new file mode 100644 index 000000000..e045158cc Binary files /dev/null and b/manual-assets/video-guide/videos/01.png differ diff --git a/manual-assets/video-guide/videos/02.png b/manual-assets/video-guide/videos/02.png new file mode 100644 index 000000000..9cb747444 Binary files /dev/null and b/manual-assets/video-guide/videos/02.png differ diff --git a/manual-assets/video-guide/videos/03.png b/manual-assets/video-guide/videos/03.png new file mode 100644 index 000000000..0ebe65da0 Binary files /dev/null and b/manual-assets/video-guide/videos/03.png differ diff --git a/manual-assets/video-guide/videos/04.png b/manual-assets/video-guide/videos/04.png new file mode 100644 index 000000000..b10cda49d Binary files /dev/null and b/manual-assets/video-guide/videos/04.png differ diff --git a/manual-assets/video-guide/videos/05.png b/manual-assets/video-guide/videos/05.png new file mode 100644 index 000000000..8f61d55fe Binary files /dev/null and b/manual-assets/video-guide/videos/05.png differ diff --git a/manual-assets/video-guide/videos/06.png b/manual-assets/video-guide/videos/06.png new file mode 100644 index 000000000..f1dfb5d03 Binary files /dev/null and b/manual-assets/video-guide/videos/06.png differ diff --git a/manual-assets/video-guide/videos/07.png b/manual-assets/video-guide/videos/07.png new file mode 100644 index 000000000..43a6b6c38 Binary files /dev/null and b/manual-assets/video-guide/videos/07.png differ diff --git a/manual-assets/video-guide/videos/08.png b/manual-assets/video-guide/videos/08.png new file mode 100644 index 000000000..09a474932 Binary files /dev/null and b/manual-assets/video-guide/videos/08.png differ diff --git a/manual-assets/video-guide/videos/config.json b/manual-assets/video-guide/videos/config.json new file mode 100644 index 000000000..2850ef8f1 --- /dev/null +++ b/manual-assets/video-guide/videos/config.json @@ -0,0 +1,69 @@ +{ + "url": "https://faq.uniontech.com/video/function/8577", + "videos": [ + { + "name[en_US]": "Introduction to Uniontech Desktopp Operating System", + "name[zh_CN]": "统信桌面操作系统介绍", + "name[zh_HK]": "統信桌面作業系統介紹", + "name[zh_TW]": "統信桌⾯作業系統介紹", + "url": "https://faq.uniontech.com/video/function/1850", + "cover": "01.png" + }, + { + "name[en_US]": "Introduction to System Control Center", + "name[zh_CN]": "系统控制中心介绍", + "name[zh_HK]": "系統控制中心介紹", + "name[zh_TW]": "繫統控制中心介紹", + "url": "https://faq.uniontech.com/video/function/3dbe", + "cover": "02.png" + }, + { + "name[en_US]": "Introduction to System File Manager", + "name[zh_CN]": "系统文件管理器介绍", + "name[zh_HK]": "系統文件管理器介紹", + "name[zh_TW]": "繫統文件管理器介紹", + "url": "https://faq.uniontech.com/video/function/9650", + "cover": "03.png" + }, + { + "name[en_US]": "Introduction to System Input Method Settings", + "name[zh_CN]": "系统输入法设置介绍", + "name[zh_HK]": "系統輸入法設置介紹", + "name[zh_TW]": "繫統輸入法設定介紹", + "url": "https://faq.uniontech.com/video/function/5aa2", + "cover": "04.png" + }, + { + "name[en_US]": "Introduction to System Printer Installation", + "name[zh_CN]": "系统打印机安装介绍", + "name[zh_HK]": "系統打印機安裝介紹", + "name[zh_TW]": "繫統印錶機安裝介紹", + "url": "https://faq.uniontech.com/video/function/40a1", + "cover": "05.png" + }, + { + "name[en_US]": "Introduction to System Font Installation", + "name[zh_CN]": "系统字体安装介绍", + "name[zh_HK]": "系統字體安裝介紹", + "name[zh_TW]": "繫統字體安裝介紹", + "url": "https://faq.uniontech.com/video/function/aa23", + "cover": "06.png" + }, + { + "name[en_US]": "Introduction to System Screenshot Function", + "name[zh_CN]": "系统截图功能介绍", + "name[zh_HK]": "系統截圖功能介紹", + "name[zh_TW]": "繫統截圖功能介紹", + "url": "https://faq.uniontech.com/video/function/1590", + "cover": "07.png" + }, + { + "name[en_US]": "Introduction to System CD Burning", + "name[zh_CN]": "系统光盘刻录介绍", + "name[zh_HK]": "系統光盤刻錄介紹", + "name[zh_TW]": "繫統光盤刻錄介紹", + "url": "https://faq.uniontech.com/video/function/e160", + "cover": "08.png" + } + ] +} \ No newline at end of file diff --git a/patches/fix-linglong.patch b/patches/fix-linglong.patch new file mode 100644 index 000000000..9295288b1 --- /dev/null +++ b/patches/fix-linglong.patch @@ -0,0 +1,44 @@ +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 3b022571..cb821553 100755 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -7,6 +7,18 @@ project(deepin-manual C CXX) + set(CMAKE_INSTALL_PREFIX /usr) + add_definitions(-DDMAN_MANUAL_DIR="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets") + ++####### 玲珑构建配置 ++# 设置玲珑构建安装目录到CMAKE_INSTALL_PREFIX ++set(CMAKE_INSTALL_PREFIX $ENV{PREFIX}) ++# 玲珑构建编译开关 ++add_definitions(-DLINGLONG_BUILD) ++# qwebengine玲珑路径 ++add_definitions(-DDMAN_QWEBENGINE_DIR="${CMAKE_INSTALL_PREFIX}/lib") ++# webengine资源玲珑路径 ++add_definitions(-DDMAN_WEBENGINERES_DIR="${CMAKE_INSTALL_PREFIX}/share/qt5/resources") ++# webengine翻译玲珑路径 ++add_definitions(-DDMAN_WEBENGINETS_DIR="${CMAKE_INSTALL_PREFIX}/share/qt5/translations") ++ + if (CMAKE_BUILD_TYPE MATCHES Debug) + add_definitions(-DDMAN_SEARCH_DB="${CMAKE_SOURCE_DIR}/manual-assets") + add_definitions(-DDMAN_WEB_DIR="${CMAKE_CURRENT_SOURCE_DIR}/web_dist") +diff --git a/src/dbus/com.deepin.Manual.Open.service b/src/dbus/com.deepin.Manual.Open.service +index 912a73ee..23ba3492 100755 +--- a/src/dbus/com.deepin.Manual.Open.service ++++ b/src/dbus/com.deepin.Manual.Open.service +@@ -1,3 +1,4 @@ + [D-BUS Service] + Name=com.deepin.Manual.Open +-Exec=/usr/bin/dman --dbus ++Exec=/usr/bin/ll-cli run org.deepin.manual --exec "dman --dbus" ++ +diff --git a/src/dbus/com.deepin.Manual.Search.service b/src/dbus/com.deepin.Manual.Search.service +index 1729b5b5..457ee4c3 100755 +--- a/src/dbus/com.deepin.Manual.Search.service ++++ b/src/dbus/com.deepin.Manual.Search.service +@@ -1,3 +1,3 @@ + [D-BUS Service] + Name=com.deepin.Manual.Search +-Exec=/usr/bin/dmanHelper +\ No newline at end of file ++Exec=/usr/bin/ll-cli run org.deepin.manual --exec "dmanHelper" +\ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 898187876..1f69b2954 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,26 +1,21 @@ -# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: CC0-1.0 - project(deepin-manual C CXX) #set(CMAKE_C_COMPILER /usr/bin/clang) #set(CMAKE_CXX_COMPILER /usr/bin/clang++) - +#assets目录在usr下 set(CMAKE_INSTALL_PREFIX /usr) - +add_definitions(-DDMAN_MANUAL_DIR="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets") if (CMAKE_BUILD_TYPE MATCHES Debug) add_definitions(-DDMAN_SEARCH_DB="${CMAKE_SOURCE_DIR}/manual-assets") add_definitions(-DDMAN_WEB_DIR="${CMAKE_CURRENT_SOURCE_DIR}/web_dist") # add_definitions(-DDMAN_MANUAL_DIR="${CMAKE_SOURCE_DIR}/manual-assets") - add_definitions(-DDMAN_MANUAL_DIR="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets") else() add_definitions(-DDMAN_SEARCH_DB="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets") add_definitions(-DDMAN_WEB_DIR="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/web_dist") - add_definitions(-DDMAN_MANUAL_DIR="${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets") endif () + #禁止Debug日志输出 #add_definitions(-DQT_NO_DEBUG_OUTPUT) @@ -354,7 +349,11 @@ install(FILES ${QM_FILES} # DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/) install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/web_dist - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual) + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual) +install(DIRECTORY ${CMAKE_SOURCE_DIR}/manual-assets/learn-basic-operations + ${CMAKE_SOURCE_DIR}/manual-assets/common-application-libraries + ${CMAKE_SOURCE_DIR}/manual-assets/video-guide + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/system) string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_SYSTEM_PROCESSOR) diff --git a/src/app/dman.cpp b/src/app/dman.cpp old mode 100644 new mode 100755 index 58af71b6e..340fa504d --- a/src/app/dman.cpp +++ b/src/app/dman.cpp @@ -34,9 +34,28 @@ int main(int argc, char **argv) //禁用GPU qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-gpu"); +#ifdef LINGLONG_BUILD + //玲珑环境添加WebEngine + QString webEngineProcessPath = DMAN_QWEBENGINE_DIR"" + QLibraryInfo::location(QLibraryInfo::LibrariesPath).mid( + QLibraryInfo::location(QLibraryInfo::LibrariesPath).lastIndexOf("/")) + QString("/qt5/libexec/QtWebEngineProcess"); + QFile file(webEngineProcessPath); + if (file.exists()) + qputenv("QTWEBENGINEPROCESS_PATH", webEngineProcessPath.toLocal8Bit()); + else + qWarning() << "qputenv QTWEBENGINEPROCESS_PATH fail"; + + QFile fileTs(DMAN_WEBENGINERES_DIR); + QFile fileRes(DMAN_WEBENGINETS_DIR); + if (fileTs.exists() && fileRes.exists()) + qputenv("QTWEBENGINERESOURCE_PATH", (DMAN_WEBENGINETS_DIR":" + QString(DMAN_WEBENGINERES_DIR)).toStdString().c_str()); + else + qWarning() << "qputenv QTWEBENGINERESOURCE_PATH fail"; + qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--single-process"); +#else if (!Utils::judgeWayLand()) { qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--single-process"); } +#endif //所有进程类型禁用沙箱..此配置开启禁用gpu后无效 // qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--no-sandbox"); @@ -117,7 +136,7 @@ int main(int argc, char **argv) //埋点记录启动数据 QJsonObject objStartEvent{ {"tid", Eventlogutils::StartUp}, - {"vsersion", VERSION}, + {"version", VERSION}, {"mode", 1}, }; Eventlogutils::GetInstance()->writeLogs(objStartEvent); diff --git a/src/app/dman_helper.cpp b/src/app/dman_helper.cpp index f0e48471e..bb76c267e 100644 --- a/src/app/dman_helper.cpp +++ b/src/app/dman_helper.cpp @@ -9,7 +9,7 @@ #include "dbus/dmanwatcher.h" #include - +#include "base/utils.h" #include #include #include @@ -19,11 +19,38 @@ int main(int argc, char **argv) { //欧拉版root用户登录时会报no-sandbox错误的问题,增加此参数后使qtwebengine进程与主进程合并 - qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--single-process"); + QApplication app(argc, argv); + qputenv("DXCB_FAKE_PLATFORM_NAME_XCB", "true"); + //禁用GPU + qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-gpu"); // qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "7777"); +#ifdef LINGLONG_BUILD + //玲珑环境添加WebEngine + QString webEngineProcessPath = DMAN_QWEBENGINE_DIR"" + QLibraryInfo::location(QLibraryInfo::LibrariesPath).mid( + QLibraryInfo::location(QLibraryInfo::LibrariesPath).lastIndexOf("/")) + QString("/qt5/libexec/QtWebEngineProcess"); + QFile file(webEngineProcessPath); + if (file.exists()) + qputenv("QTWEBENGINEPROCESS_PATH", webEngineProcessPath.toLocal8Bit()); + else + qWarning() << "qputenv QTWEBENGINEPROCESS_PATH fail"; + + QFile fileTs(DMAN_WEBENGINERES_DIR); + QFile fileRes(DMAN_WEBENGINETS_DIR); + if (fileTs.exists() && fileRes.exists()) + qputenv("QTWEBENGINERESOURCE_PATH", (DMAN_WEBENGINETS_DIR":" + QString(DMAN_WEBENGINERES_DIR)).toStdString().c_str()); + else + qWarning() << "qputenv QTWEBENGINERESOURCE_PATH fail"; + + qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--single-process"); +#else + if (!Utils::judgeWayLand()) { + qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--single-process"); + } +#endif + // 后端服务dmanHelper自检,若前端dman应用不存在,则后端dmanHelper退出 DManWatcher watcher; ManualSearchProxy search_obj; @@ -37,11 +64,10 @@ int main(int argc, char **argv) ctx.setFormat(fmt); ctx.create(); if (!ctx.isValid()) { - fmt.setRenderableType(QSurfaceFormat::OpenGLES); + fmt.setRenderableType(QSurfaceFormat::OpenGLES); } fmt.setDefaultFormat(fmt); fmt.setProfile(QSurfaceFormat::CoreProfile); - qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-gpu"); Dtk::Core::DLogManager::registerFileAppender(); Dtk::Core::DLogManager::registerConsoleAppender(); diff --git a/src/app/generate_search_db.cpp b/src/app/generate_search_db.cpp index c6751e795..b4489bbfd 100644 --- a/src/app/generate_search_db.cpp +++ b/src/app/generate_search_db.cpp @@ -3,6 +3,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include +#include +#include +#include +#include +#include #include "base/command.h" #include "controller/search_db.h" diff --git a/src/app/image_viewer_demo.cpp b/src/app/image_viewer_demo.cpp index e2d386067..a3641b635 100644 --- a/src/app/image_viewer_demo.cpp +++ b/src/app/image_viewer_demo.cpp @@ -14,4 +14,4 @@ int main(int argc, char **argv) viewer.open("/tmp/a.jpg"); return app.exec(); -} \ No newline at end of file +} diff --git a/src/base/command.cpp b/src/base/command.cpp index e77dac9a6..65d004a45 100644 --- a/src/base/command.cpp +++ b/src/base/command.cpp @@ -5,6 +5,9 @@ #include "base/command.h" #include +#include +#include +#include namespace dman { diff --git a/src/base/consts.cpp b/src/base/consts.cpp index 29c1dfe7d..bfdaec848 100644 --- a/src/base/consts.cpp +++ b/src/base/consts.cpp @@ -14,3 +14,5 @@ const char kConfigWindowWidth[] = "window_width"; const char kConfigWindowHeight[] = "window_height"; const char kConfigWindowInfo[] = "window_info"; const char kConfigAppList[] = "AppList"; + +const char kVideoConfigPath[] = DMAN_MANUAL_DIR"/system/video-guide/videos/config.json"; diff --git a/src/base/consts.h b/src/base/consts.h index b242f54dd..f2b8dbf28 100644 --- a/src/base/consts.h +++ b/src/base/consts.h @@ -18,5 +18,10 @@ extern const char kConfigWindowHeight[]; extern const char kConfigWindowInfo[]; extern const char kConfigAppList[]; +extern const char kVideoConfigPath[]; + +const char kLearnBasicOperations[] = "learn-basic-operations"; +const char kCommonApplicationLibraries[] = "common-application-libraries"; + #endif // DEEPIN_MANUAL_BASE_CONSTS_H diff --git a/src/base/utils.cpp b/src/base/utils.cpp old mode 100644 new mode 100755 index a881e56a0..2c1770300 --- a/src/base/utils.cpp +++ b/src/base/utils.cpp @@ -4,15 +4,22 @@ #include "utils.h" +#include +DCORE_USE_NAMESPACE + #include #include +#include "base/consts.h" + QHash Utils::m_imgCacheHash; QHash Utils::m_fontNameCache; QString Utils::cpuModeName; -const char kLauncherService[] = "com.deepin.dde.daemon.Launcher"; -const char kLauncherIface[] = "/com/deepin/dde/daemon/Launcher"; +const char kLauncherServiceV20[] = "com.deepin.dde.daemon.Launcher"; +const char kLauncherIfaceV20[] = "/com/deepin/dde/daemon/Launcher"; +const char kLauncherServiceV23[] = "org.deepin.dde.daemon.Launcher1"; +const char kLauncherIfaceV23[] = "/org/deepin/dde/daemon/Launcher1"; //标题映射表 const int langCount = 5; @@ -20,26 +27,32 @@ const int langCount = 5; QString languageArr[][langCount] = { //dde model {"controlcenter", "控制中心", "Control Center", "控制中心", "控制中心"}, - {"accounts", "帐户设置", "Accounts", "賬號設置", "帳戶設定"}, + {"", "首页介绍", "Homepage Introduction", "首頁介紹", "首頁介紹"}, + {"authentication", "生物认证", "Biometric Authentication", "生物認證", "生物認證"}, + {"passkey", "安全密钥", "Security key", "安全密鑰", "安全金鑰"}, + {"accounts", "帐户设置", "Accounts", "帳戶設定", "帳戶設定"}, {"cloudsync", "Union ID", "Union ID", "Union ID", "Union ID"}, - {"display", "显示设置", "Display", "顯示設置", "螢幕設定"}, - {"defapp", "默认程序设置", "Default Applications", "默認程序設置", "預設程式"}, - {"personalization", "个性化设置", "Personalization Settings", "個性化設置", "個性化設定"}, - {"network", "网络设置", "Network Settings", "網絡設置", "網路設定"}, - {"notification", "通知设置", "Notification Settings", "通知設置", "通知設定"}, - {"sound", "声音设置", "Sound Settings", "聲音設置", "聲音設定"}, - {"bluetooth", "蓝牙设置", "Bluetooth Settings", "藍牙設置", "藍牙設定"}, - {"datetime", "时间日期", "Date and Time", "日期與時刻", "時間日期"}, + {"display", "显示设置", "Display", "螢幕設定", "螢幕設定"}, + {"defapp", "默认程序设置", "Default Applications", "預設程式", "預設程式"}, + {"personalization", "个性化设置", "Personalization Settings", "個性化設定", "個性化設定"}, + {"network", "网络设置", "Network Settings", "網路設定", "網路設定"}, + {"notification", "通知设置", "Notification Settings", "通知設定", "通知設定"}, + {"sound", "声音设置", "Sound Settings", "聲音設定", "聲音設定"}, + {"bluetooth", "蓝牙设置", "Bluetooth Settings", "藍牙設定", "藍牙設定"}, + {"datetime", "时间和格式", "Date and Format", "時間和格式", "時間和格式"}, {"power", "电源管理", "Power Management", "電源管理", "電源管理"}, - {"mouse", "鼠标和触控板", "Mouse and Touchpad", "鼠標和觸控板", "滑鼠和觸控板"}, + {"mouse", "鼠标和触控板", "Mouse and Touchpad", "滑鼠和觸控板", "滑鼠和觸控板"}, {"tablet", "数位板", "Drawing Tablet", "數位板", "數位板"}, {"keyboard", "键盘和语言", "Keyboard and Language", "鍵盤和語言", "鍵盤和語言"}, {"voice", "辅助功能", "Assistive Tools", "輔助功能", "輔助功能"}, - {"update", "系统更新", "Update Settings", "更新", "檢查更新"}, - {"systeminfo", "系统信息", "System Info", "系統訊息", "系統資訊"}, + {"privacy", "隐私和安全", "Privacy and Security", "私隱和安全", "隱私和安全"}, + {"update", "系统更新", "Update Settings", "檢查更新", "檢查更新"}, + {"systeminfo", "系统信息", "System Info", "系統資訊", "系統資訊"}, {"License activator", "授权管理", "Authorization Management", "授權管理", "授權管理"}, - {"commoninfo", "通用设置", "General Settings", "通用設置", "一般設定"}, - {"touchscreen", "触控屏设置", "Touch Screen", "觸控屏設置", "觸控屏設定"}}; + {"Backup and Restore", "备份还原", "Backup and Restore", "備份還原", "備份還原"}, + {"commoninfo", "通用设置", "General Settings", "一般設定", "一般設定"}, + {"touchscreen", "触控屏设置", "Touch Screen", "觸控屏設定", "觸控屏設定"}, +}; struct ReplyStruct { QString m_desktop; @@ -49,6 +62,7 @@ struct ReplyStruct { qint64 m_categoryId; qint64 m_installedTime; + QStringList m_appmessage; }; Q_DECLARE_METATYPE(ReplyStruct) @@ -63,7 +77,10 @@ QDBusArgument &operator<<(QDBusArgument &argument, const ReplyStruct &info) { argument.beginStructure(); argument << info.m_desktop << info.m_name << info.m_key << info.m_iconKey; - argument << info.m_categoryId << info.m_installedTime; + if (DSysInfo::majorVersion() == "23") + argument << info.m_categoryId << info.m_installedTime << info.m_appmessage; + else + argument << info.m_categoryId << info.m_installedTime; argument.endStructure(); return argument; } @@ -78,7 +95,10 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, ReplyStruct &info { argument.beginStructure(); argument >> info.m_desktop >> info.m_name >> info.m_key >> info.m_iconKey; - argument >> info.m_categoryId >> info.m_installedTime; + if (DSysInfo::majorVersion() == "23") + argument >> info.m_categoryId >> info.m_installedTime >> info.m_appmessage; + else + argument >> info.m_categoryId >> info.m_installedTime; argument.endStructure(); return argument; } @@ -164,13 +184,14 @@ QList Utils::launcherInterface() qRegisterMetaType>("a"); qDBusRegisterMetaType>(); - QDBusInterface iface(kLauncherService, - kLauncherIface, - kLauncherService, - QDBusConnection::sessionBus()); + bool bV23 = DSysInfo::majorVersion() == "23"; + QString sLauncherService = bV23 ? kLauncherServiceV23 : kLauncherServiceV20; + QString sLauncherIface = bV23 ? kLauncherIfaceV23 : kLauncherIfaceV20; + QDBusInterface iface(sLauncherService, sLauncherIface, sLauncherService, QDBusConnection::sessionBus()); //root权限下此dbus接口无效... if (!iface.isValid()) { qDebug() << qPrintable(QDBusConnection::sessionBus().lastError().message()); + qDebug() << QString("majorVersion:%1, servie:%2 iface:%3").arg(DSysInfo::majorVersion()).arg(sLauncherService).arg(sLauncherIface); return applist; // exit(1); } @@ -196,6 +217,7 @@ QList Utils::launcherInterface() return applist; } else { qDebug() << "GetAllItemInfos fail! " << reply.error().message(); + qDebug() << QString("majorVersion:%1, servie:%2 iface:%3").arg(DSysInfo::majorVersion()).arg(sLauncherService).arg(sLauncherIface); return applist; } } @@ -207,17 +229,53 @@ QList Utils::launcherInterface() */ bool Utils::judgeWayLand() { - auto env = QProcessEnvironment::systemEnvironment(); + auto env = QProcessEnvironment::systemEnvironment(); - QString XDG_SESSION_TYPE = env.value(QStringLiteral("XDG_SESSION_TYPE")); + QString XDG_SESSION_TYPE = env.value(QStringLiteral("XDG_SESSION_TYPE")); - QString WAYLAND_DISPLAY = env.value(QStringLiteral("WAYLAND_DISPLAY")); + QString WAYLAND_DISPLAY = env.value(QStringLiteral("WAYLAND_DISPLAY")); + + if (XDG_SESSION_TYPE == QLatin1String("wayland") || WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive)) { + return true; + } - if (XDG_SESSION_TYPE == QLatin1String("wayland") || WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive)){ - return true; - } + return false; +} - return false; +QStringList Utils::getMdsourcePath() +{ + QStringList sourcePath; + QStringList pathlist = getEnvsourcePath(); + for (int i = 0; i < pathlist.size(); ++i) { + sourcePath.push_back(pathlist[i] + "/deepin-manual/manual-assets"); + } + sourcePath.push_back(DMAN_MANUAL_DIR); + qDebug() << " all MD source path : " << sourcePath.last(); + return sourcePath; +} + +QStringList Utils::getEnvsourcePath() +{ + QStringList pathlist = QString(qgetenv("XDG_DATA_DIRS")).split(':'); + if (pathlist.size() == 1 && pathlist[0].isEmpty()) + pathlist[0] = "/usr/share"; + qDebug() << " all source path : " << pathlist; + return pathlist; +} + +QString Utils::getDesktopFilePath(const QString &desktopname) +{ + // 遍历XDG_DATA_DIRS中的路径,找寻指定desktop文件 + QStringList pathList = getEnvsourcePath(); + foreach (auto path, pathList) { + QString filepath = path + QString("/applications/%1.desktop").arg(desktopname); + QFile file(filepath); + if (file.exists()) { + return filepath; + } + } + + return ""; } /** @@ -226,75 +284,46 @@ bool Utils::judgeWayLand() */ QStringList Utils::getSystemManualList() { - const QHash kAppNameMap = { - {"org.deepin.flatdeb.deepin-calendar", "dde-calendar"}, - {"org.deepin.flatdeb.deepin-music", "deepin-music"}, - {"org.deepin.flatdeb.deepin-screenshot", "deepin-screenshot"}, - {"org.deepin.flatdeb.deepin-voice-recorder", "deepin-voice-recorder"}, - {"org.deepin.flatdeb.deepin-image-viewer", "deepin-image-viewer"}, - {"deepin-cloud-scan-configurator", "deepin-cloud-scan"}, - {"org.deepin.flatdeb.deepin-movie", "deepin-movie"}, - {"org.deepin.flatdeb.deepin-screen-recorder", "deepin-screen-recorder"}, - {"org.deepin.flatdeb.deepin-calculator", "deepin-calculator"}, - {"com.deepin.editor", "deepin-editor"}, - }; - QStringList app_list_; - //调用dbus服务获取系统安装应用 - const AppInfoList list = launcherInterface(); - const QStringList applicationList = QDir(QString("%1/application/").arg(DMAN_MANUAL_DIR)).entryList(); - const QStringList systemList = QDir(QString("%1/system/").arg(DMAN_MANUAL_DIR)).entryList(); - - QString oldMdPath = DMAN_MANUAL_DIR; - -#if (DTK_VERSION > DTK_VERSION_CHECK(5, 4, 12, 0)) - if (Dtk::Core::DSysInfo::UosServer == Dtk::Core::DSysInfo::uosType()) { - oldMdPath += "/server"; - } else if (Dtk::Core::DSysInfo::UosHome == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/personal"; - } else if (Dtk::Core::DSysInfo::UosEducation == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/education"; - } else if (Dtk::Core::DSysInfo::UosCommunity == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/community"; - } else { - oldMdPath += "/professional"; - } -#else - Dtk::Core::DSysInfo::DeepinType nType = Dtk::Core::DSysInfo::deepinType(); - if (Dtk::Core::DSysInfo::DeepinServer == nType) { - oldMdPath += "/server"; - } else if (Dtk::Core::DSysInfo::DeepinPersonal == nType) { - oldMdPath += "/personal"; - } else { - if (Dtk::Core::DSysInfo::isCommunityEdition()) { + QStringList strMANUAL_DIR_list = Utils::getMdsourcePath(); + foreach (auto strMANUAL_DIR, strMANUAL_DIR_list) { + const QStringList applicationList = QDir(QString("%1/application/").arg(strMANUAL_DIR)).entryList(QDir::Dirs|QDir::NoDotAndDotDot); + const QStringList systemList = QDir(QString("%1/system/").arg(strMANUAL_DIR)).entryList(QDir::Dirs|QDir::NoDotAndDotDot); + QString oldMdPath = strMANUAL_DIR; + if (Dtk::Core::DSysInfo::UosServer == Dtk::Core::DSysInfo::uosType()) { + oldMdPath += "/server"; + } else if (Dtk::Core::DSysInfo::UosHome == Dtk::Core::DSysInfo::uosEditionType()) { + oldMdPath += "/personal"; + } else if (Dtk::Core::DSysInfo::UosEducation == Dtk::Core::DSysInfo::uosEditionType()) { + oldMdPath += "/education"; + } else if (Dtk::Core::DSysInfo::UosCommunity == Dtk::Core::DSysInfo::uosEditionType()) { oldMdPath += "/community"; } else { oldMdPath += "/professional"; } - } - -#endif - const QStringList oldAppList = QDir(oldMdPath).entryList(); + const QStringList oldAppList = QDir(oldMdPath).entryList(QDir::Dirs|QDir::NoDotAndDotDot); + for(auto app:applicationList){ + if (app_list_.indexOf(app) == -1) { + app_list_.append(app); + } + } + if (systemList.contains("dde") || oldAppList.contains("dde")) { + if (app_list_.indexOf("dde") == -1) { + app_list_.append("dde"); + } + } - QMultiMap appMap; - for (int var = 0; var < list.size(); ++var) { - appMap.insert(list.at(var).installed_time, list.at(var)); - } - //安装时间相同时,按名称排序 - QList listApp = sortAppList(appMap); - - //比对存在帮助md文件的应用 - for (int i = 0; i < listApp.size(); ++i) { - const QString app_name = kAppNameMap.value(listApp.at(i).key, listApp.at(i).key); - if ((applicationList.contains(app_name) || oldAppList.contains(app_name)) && app_list_.indexOf(app_name) == -1) { - app_list_.append(app_name); + // 非应用文档,直接添加 + if (systemList.contains(kLearnBasicOperations) || oldAppList.contains(kLearnBasicOperations)) { + if (app_list_.indexOf(kLearnBasicOperations) == -1) + app_list_.append(kLearnBasicOperations); } + if (systemList.contains(kCommonApplicationLibraries) || oldAppList.contains(kCommonApplicationLibraries)) { + if (app_list_.indexOf(kCommonApplicationLibraries) == -1) + app_list_.append(kCommonApplicationLibraries); + } + qDebug() << "exist app list: " << app_list_ << ", count:" << app_list_.size(); } - app_list_.append("DeepinAIAssistant"); //语音助手无法通过launcherInterface获取目前只能手动添加 - if (systemList.contains("dde") || oldAppList.contains("dde")) { - app_list_.append("dde"); - } - qDebug() << "exist app list: " << app_list_ << ", count:" << app_list_.size(); return app_list_; } @@ -304,10 +333,9 @@ QStringList Utils::getSystemManualList() * @return * @note 获取系统版本信息 */ -QString Utils::getSystemManualDir() +QStringList Utils::getSystemManualDir() { - QString strMANUAL_DIR = DMAN_MANUAL_DIR; - return strMANUAL_DIR; + return Utils::getMdsourcePath(); } /** @@ -393,6 +421,16 @@ bool Utils::hasSelperSupport() return false; } +bool Utils::hasAppStore() +{ + const QStringList list = getSystemManualList(); + if (list.contains("deepin-app-store")) { + return true; + } else { + return false; + } +} + //p表示桌面专业版,h表示个人版,d表示社区版 //s表示默认服务器版,e表示服务器企业版,eu表示服务器欧拉版,i表示服务器行业版,klu表示KelvinU项目版本,pgv表示PanguV项目版本。 QStringList Utils::systemToOmit(Dtk::Core::DSysInfo::UosEdition type) diff --git a/src/base/utils.h b/src/base/utils.h old mode 100644 new mode 100755 index 0755de6ad..025336103 --- a/src/base/utils.h +++ b/src/base/utils.h @@ -38,9 +38,10 @@ class Utils : public QObject static QList launcherInterface(); //获取系统应用中有帮助手册的应用列表 static QStringList getSystemManualList(); - static QString getSystemManualDir(); + static QStringList getSystemManualDir(); static QList sortAppList(QMultiMap map); static bool hasSelperSupport(); + static bool hasAppStore(); static QStringList systemToOmit(Dtk::Core::DSysInfo::UosEdition); static bool activeWindow(quintptr winId); static QString regexp_label(const QString &strtext, const QString &strpatter); @@ -50,7 +51,12 @@ class Utils : public QObject static bool judgeLoongson(); //判断是否Wayland static bool judgeWayLand(); - + //获取md文件路径 + static QStringList getMdsourcePath(); + //获取环境变量 + static QStringList getEnvsourcePath(); + //获取desktop文件路径 + static QString getDesktopFilePath(const QString &desktopname); }; class ExApplicationHelper : public DGuiApplicationHelper diff --git a/src/controller/argument_parser.cpp b/src/controller/argument_parser.cpp index b229fa415..13b6f8291 100644 --- a/src/controller/argument_parser.cpp +++ b/src/controller/argument_parser.cpp @@ -129,7 +129,7 @@ void ArgumentParser::onOpenAppRequested(const QString &app_name, const QString & //应用F1和帮助打开帮助手册 数据埋点统计 QJsonObject objStartEvent; objStartEvent.insert("tid", Eventlogutils::DbusStartUp); - objStartEvent.insert("vsersion", qApp->applicationVersion()); + objStartEvent.insert("version", qApp->applicationVersion()); objStartEvent.insert("appname", app_name); objStartEvent.insert("titlename", title_name); qInfo() << __FUNCTION__ << QJsonDocument(objStartEvent).toJson(QJsonDocument::Compact); diff --git a/src/controller/config_manager.cpp b/src/controller/config_manager.cpp index d6db0d9ca..514ed198c 100644 --- a/src/controller/config_manager.cpp +++ b/src/controller/config_manager.cpp @@ -6,6 +6,7 @@ #include #include +#include ConfigManager *ConfigManager::_pInstance = nullptr; @@ -15,6 +16,11 @@ ConfigManager::ConfigManager(QObject *parent) m_winInfoConfig = new QSettings(getWinInfoConfigPath(), QSettings::IniFormat, this); } +ConfigManager::~ConfigManager() +{ + qDebug() << "~configmanager...."; +} + /** @@ -30,6 +36,14 @@ ConfigManager *ConfigManager::getInstance() return _pInstance; } +void ConfigManager::releaseInstance() +{ + if (_pInstance) + delete _pInstance; + + _pInstance = nullptr; +} + /** * @brief ConfigManager::getWinInfoConfigPath * @return 返回配置文件目录 diff --git a/src/controller/config_manager.h b/src/controller/config_manager.h index 1fedee8fd..53ad88827 100644 --- a/src/controller/config_manager.h +++ b/src/controller/config_manager.h @@ -13,11 +13,14 @@ class ConfigManager : public QObject Q_OBJECT public: static ConfigManager *getInstance(); + static void releaseInstance(); QString getWinInfoConfigPath(); QSettings *getSettings(); private: explicit ConfigManager(QObject *parent = nullptr); + ~ConfigManager(); + static ConfigManager *_pInstance; QSettings *m_winInfoConfig = nullptr; }; diff --git a/src/controller/filewatcher.cpp b/src/controller/filewatcher.cpp index 1b0c88e74..cda966766 100644 --- a/src/controller/filewatcher.cpp +++ b/src/controller/filewatcher.cpp @@ -4,6 +4,7 @@ #include "filewatcher.h" #include "base/utils.h" +#include "base/consts.h" #include #include @@ -72,73 +73,85 @@ void fileWatcher::monitorFile() QStringList listMonitorFile; QStringList listModule; - QString assetsPath = Utils::getSystemManualDir(); - listModule.append(assetsPath); - //新文案结构 /usr/share/deepin-manual/manual-assets/[application | system]/appName/appNameT/land/*_appNameT.md - for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - //监控资源文件夹 - if (type == "system" || type == "application") { - QString typePath = assetsPath + "/" + type; - listModule.append(typePath); + QStringList assetsPathList = Utils::getSystemManualDir(); + foreach (auto assetsPath, assetsPathList) { + listModule.append(assetsPath); + //新文案结构 /usr/share/deepin-manual/manual-assets/[application | system]/appName/appNameT/land/*_appNameT.md + for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { //监控资源文件夹 - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - //./manual-assets/application(system)/appName - QString modulePath = typePath + "/" + module; - listModule.append(modulePath); - QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); - - if (listAppNameT.count() != 1) { - qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); - continue; - } - //./manual-assets/application(system)/appName/appNameT - QString appPath = modulePath + "/" + listAppNameT.at(0); - listModule.append(appPath); - for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (lang == "zh_CN" || lang == "en_US") { - //./manual-assets/application(system)/appName/appNameT/lang - QString langPath = appPath + "/" + lang; - listModule.append(langPath); - for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { - if (mdFile.endsWith("md")) { - //./manual-assets/application(system)/appName/appNameT/lang/md - QString strMd = langPath + "/" + mdFile; - listMonitorFile.append(strMd); + if (type == "system" || type == "application") { + QString typePath = assetsPath + "/" + type; + listModule.append(typePath); + //监控资源文件夹 + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + //./manual-assets/application(system)/appName + QString modulePath = typePath + "/" + module; + listModule.append(modulePath); + QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); + + if (listAppNameT.count() != 1) { + qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); + continue; + } + //./manual-assets/application(system)/appName/appNameT + QString appPath = modulePath + "/" + listAppNameT.at(0); + listModule.append(appPath); + for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (lang == "zh_CN" || lang == "en_US") { + //./manual-assets/application(system)/appName/appNameT/lang + QString langPath = appPath + "/" + lang; + listModule.append(langPath); + for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { + if (mdFile.endsWith("md")) { + //./manual-assets/application(system)/appName/appNameT/lang/md + QString strMd = langPath + "/" + mdFile; + QFileInfo fileinfo(strMd); + if (fileinfo.isSymLink()) { + listMonitorFile.append(fileinfo.symLinkTarget()); + } else { + listMonitorFile.append(strMd); + } + } } } } } } } - } //旧文案结构兼容 /usr/share/deepin-manual/manual-assets/[professional | server]/appName/lang/index.md #if 1 - for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (systemType.contains(system)) { - QString typePath = assetsPath + "/" + system; - listModule.append(typePath); - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - QString modulePath = typePath + "/" + module; + for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (systemType.contains(system)) { + QString typePath = assetsPath + "/" + system; listModule.append(typePath); - for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (lang == "zh_CN" || lang == "en_US") { - QString strMd = modulePath + "/" + lang + "/index.md"; - listMonitorFile.append(strMd); + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + QString modulePath = typePath + "/" + module; + listModule.append(typePath); + for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (lang == "zh_CN" || lang == "en_US") { + QString strMd = modulePath + "/" + lang + "/index.md"; + QFileInfo fileinfo(strMd); + if (fileinfo.isSymLink()) { + listMonitorFile.append(fileinfo.symLinkTarget()); + } else { + listMonitorFile.append(strMd); + } + } } } } } - } #endif - //监控模块资源文件夹 - if (!listModule.isEmpty()) { - watcherObj->addPaths(listModule); - } - //监控资源文件 - if (!listMonitorFile.isEmpty()) { - watcherObj->addPaths(listMonitorFile); + //监控模块资源文件夹 + if (!listModule.isEmpty()) { + watcherObj->addPaths(listModule); + } + //监控资源文件 + if (!listMonitorFile.isEmpty()) { + watcherObj->addPaths(listMonitorFile); + } } qDebug() << Q_FUNC_INFO << "WatchAllFiles... ..."; } @@ -171,35 +184,37 @@ void fileWatcher::onChangeDirSlot(const QString &path) void fileWatcher::onTimerOut() { QMap mapNow; - QString assetsPath = Utils::getSystemManualDir(); + QStringList assetsPathList = Utils::getSystemManualDir(); + foreach (auto assetsPath, assetsPathList) { - for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (type == "system" || type == "application") { - QString typePath = assetsPath + "/" + type; - //监控资源文件夹 - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - //./manual-assets/application(system)/appName - QString modulePath = typePath + "/" + module; - QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); - - if (listAppNameT.count() != 1) { - qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); - continue; - } - //./manual-assets/application(system)/appName/appNameT - QString appPath = modulePath + "/" + listAppNameT.at(0); - for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (lang == "zh_CN" || lang == "en_US") { - //./manual-assets/application(system)/appName/appNameT/lang - QString langPath = appPath + "/" + lang; - for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { - if (mdFile.endsWith("md")) { - //./manual-assets/application(system)/appName/appNameT/lang/md - QString strMd = langPath + "/" + mdFile; - QFileInfo fileInfo(strMd); - if (fileInfo.exists()) { - QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); - mapNow.insert(strMd, modifyTime); + for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (type == "system" || type == "application") { + QString typePath = assetsPath + "/" + type; + //监控资源文件夹 + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + //./manual-assets/application(system)/appName + QString modulePath = typePath + "/" + module; + QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); + + if (listAppNameT.count() != 1) { + qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); + continue; + } + //./manual-assets/application(system)/appName/appNameT + QString appPath = modulePath + "/" + listAppNameT.at(0); + for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (lang == "zh_CN" || lang == "en_US") { + //./manual-assets/application(system)/appName/appNameT/lang + QString langPath = appPath + "/" + lang; + for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { + if (mdFile.endsWith("md")) { + //./manual-assets/application(system)/appName/appNameT/lang/md + QString strMd = langPath + "/" + mdFile; + QFileInfo fileInfo(strMd); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(strMd, modifyTime); + } } } } @@ -207,29 +222,34 @@ void fileWatcher::onTimerOut() } } } - } //旧文案结构兼容 /usr/share/deepin-manual/manual-assets/[professional | server]/appName/lang/index.md #if 1 - for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (systemType.contains(system)) { - QString typePath = assetsPath + "/" + system; - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - QString modulePath = typePath + "/" + module; - for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (lang == "zh_CN" || lang == "en_US") { - QString strMd = modulePath + "/" + lang + "/index.md"; - QFileInfo fileInfo(strMd); - if (fileInfo.exists()) { - QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); - mapNow.insert(strMd, modifyTime); + for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (systemType.contains(system)) { + QString typePath = assetsPath + "/" + system; + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + QString modulePath = typePath + "/" + module; + for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (lang == "zh_CN" || lang == "en_US") { + QString strMd = modulePath + "/" + lang + "/index.md"; + QFileInfo fileInfo(strMd); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(strMd, modifyTime); + } } } } } } - } #endif + } + QFileInfo fileInfo(kVideoConfigPath); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(kVideoConfigPath, modifyTime); + } QStringList deleteList; QStringList addList; diff --git a/src/controller/helpermanager.cpp b/src/controller/helpermanager.cpp index d27510992..e872bc1c1 100644 --- a/src/controller/helpermanager.cpp +++ b/src/controller/helpermanager.cpp @@ -62,34 +62,36 @@ void helperManager::getModuleInfo() //获取数据库中所有文件更新时间 QMap mapFile = dbObj->selectAllFileTime(); QMap mapNow; - QString assetsPath = Utils::getSystemManualDir(); - for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (type == "system" || type == "application") { - QString typePath = assetsPath + "/" + type; - //监控资源文件夹 - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - //./manual-assets/application(system)/appName - QString modulePath = typePath + "/" + module; - QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); - - if (listAppNameT.count() != 1) { - qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); - continue; - } - //./manual-assets/application(system)/appName/appNameT - QString appPath = modulePath + "/" + listAppNameT.at(0); - for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (0 != lang.compare("common")) { - //./manual-assets/application(system)/appName/appNameT/lang - QString langPath = appPath + "/" + lang; - for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { - if (mdFile.endsWith("md")) { - //./manual-assets/application(system)/appName/appNameT/lang/md - QString strMd = langPath + "/" + mdFile; - QFileInfo fileInfo(strMd); - if (fileInfo.exists()) { - QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); - mapNow.insert(strMd, modifyTime); + QStringList assetsPathList = Utils::getSystemManualDir(); + foreach (auto assetsPath, assetsPathList) { + for (const QString &type : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (type == "system" || type == "application") { + QString typePath = assetsPath + "/" + type; + //监控资源文件夹 + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + //./manual-assets/application(system)/appName + QString modulePath = typePath + "/" + module; + QStringList listAppNameT = QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); + + if (listAppNameT.count() != 1) { + qCritical() << Q_FUNC_INFO << modulePath << ":there are more folders..:" << listAppNameT.count(); + continue; + } + //./manual-assets/application(system)/appName/appNameT + QString appPath = modulePath + "/" + listAppNameT.at(0); + for (QString &lang : QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (0 != lang.compare("common")) { + //./manual-assets/application(system)/appName/appNameT/lang + QString langPath = appPath + "/" + lang; + for (QString &mdFile : QDir(langPath).entryList(QDir::Files)) { + if (mdFile.endsWith("md")) { + //./manual-assets/application(system)/appName/appNameT/lang/md + QString strMd = langPath + "/" + mdFile; + QFileInfo fileInfo(strMd); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(strMd, modifyTime); + } } } } @@ -97,30 +99,36 @@ void helperManager::getModuleInfo() } } } - } //旧文案结构兼容 /usr/share/deepin-manual/manual-assets/[professional | server]/appName/lang/index.md #if 1 - for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (systemType.contains(system)) { - QString typePath = assetsPath + "/" + system; - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - QString modulePath = typePath + "/" + module; - for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - // 除了common目录其它其它都是各语言对应文档目录 - if (0 != lang.compare("common")) { - QString strMd = modulePath + "/" + lang + "/index.md"; - QFileInfo fileInfo(strMd); - if (fileInfo.exists()) { - QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); - mapNow.insert(strMd, modifyTime); + for (const QString &system : QDir(assetsPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (systemType.contains(system)) { + QString typePath = assetsPath + "/" + system; + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + QString modulePath = typePath + "/" + module; + for (QString &lang : QDir(modulePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + // 除了common目录其它其它都是各语言对应文档目录 + if (0 != lang.compare("common")) { + QString strMd = modulePath + "/" + lang + "/index.md"; + QFileInfo fileInfo(strMd); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(strMd, modifyTime); + } } } } } } - } #endif + } + + QFileInfo fileInfo(kVideoConfigPath); + if (fileInfo.exists()) { + QString modifyTime = fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss.zzz"); + mapNow.insert(kVideoConfigPath, modifyTime); + } QStringList deleteList; QStringList addList; @@ -153,18 +161,85 @@ void helperManager::handleDb(const QStringList &deleteList, const QStringList &a QStringList appList; QStringList langList; for (const QString &path : deleteList) { - QStringList list = path.split("/"); - if (list.count() >= 4) { - langList.append(list.at(list.count() - 2)); - appList.append(list.at(list.count() - 4)); + if (path.contains("video-guide")) { + appList << "video-guide" << "video-guide"; + langList << "en_US" << "zh_CN"; + } else { + QStringList list = path.split("/"); + if (list.count() >= 4) { + langList.append(list.at(list.count() - 2)); + appList.append(list.at(list.count() - 4)); + } } } + dbObj->deleteSearchInfo(appList, langList); } - QStringList list = handlePriority(addList); + QStringList tmpAddList = addList; + int videoIndex = tmpAddList.indexOf(kVideoConfigPath); + if (videoIndex >= 0) { //视频配置文件单独拿出来处理 +// tmpAddList.removeAt(videoIndex); + QFile file(kVideoConfigPath); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open video config file."; + } else { + QByteArray jsonData = file.readAll(); + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); + if (jsonDoc.isNull()) { + qDebug() << "Failed to parse JSON of video config file."; + } else { + QJsonObject jsonObj = jsonDoc.object(); + + QMap anchors; + QStringList anchorIdList; + QMap anchorInitialList; + QMap anchorSpellList; + QStringList contents; + + for (QString key : jsonObj.keys()) { + QJsonValue jsValue = jsonObj.value(key); + if (jsValue.isArray() && key == "videos") { + QJsonArray jsArray = jsValue.toArray(); + QJsonArray resultArray; + for (int i = 0; i < jsArray.count(); i++) { + if (jsArray[i].isObject()) { + QJsonObject obj = jsArray[i].toObject(); + if (obj["name[en_US]"].isString() && obj["name[zh_CN]"].isString()) { + anchors["en_US"].append(obj["name[en_US]"].toString()); + anchors["zh_CN"].append(obj["name[zh_CN]"].toString()); + anchors["zh_HK"].append(obj["name[zh_HK]"].toString()); + anchors["zh_TW"].append(obj["name[zh_TW]"].toString()); + + anchorInitialList["en_US"].append(""); + anchorInitialList["zh_CN"].append(""); + anchorInitialList["zh_HK"].append(""); + anchorInitialList["zh_TW"].append(""); + + anchorSpellList["en_US"].append(obj["name[en_US]"].toString().remove(" ")); + anchorSpellList["zh_CN"].append(Dtk::Core::Chinese2Pinyin(obj["name[zh_CN]"].toString()).remove(QRegExp("[1-9]"))); + anchorSpellList["zh_HK"].append(""); + anchorSpellList["zh_TW"].append(""); + + anchorIdList.append(QString("h%0").arg(i)); + contents.append(obj["url"].toString()); + } + } + } + } + for(QString lang_key : anchors.keys()) { + if (anchorInitialList.keys().contains(lang_key) && anchorSpellList.keys().contains(lang_key)) + dbObj->addSearchEntry("video-guide", lang_key, anchors[lang_key], anchorInitialList[lang_key], anchorSpellList[lang_key], anchorIdList, contents); + } + } + } + } + } + + QStringList list = handlePriority(tmpAddList); + if (!list.isEmpty() && !addTime.isEmpty()) { - dbObj->insertFilesTimeEntry(addList, addTime); + dbObj->insertFilesTimeEntry(tmpAddList, addTime); //通过JS层函数来完成md转html, 然后解析html内所有文本内容 if (jsObj && m_webView) { QString strChange = list.join(","); @@ -229,7 +304,7 @@ QStringList helperManager::handlePriority(const QStringList &list) QStringList splitList = mdPath.split("/"); //新文案结构 /usr/share/deepin-manual/manual-assets/[application | system]/appName/appNameT/land/*_appNameT.md - if (splitList.count() == 10 && ("application" == splitList.at(5) || "system" == splitList.at(5))) { + if (splitList.contains("application") || splitList.contains("system")) { QString moduleLang = splitList.at(splitList.count() - 4) + splitList.at(splitList.count() - 2); QString mdFile = splitList.at(splitList.count() - 1); QStringList listTemp = mdFile.split("_"); diff --git a/src/controller/search_db.cpp b/src/controller/search_db.cpp index 7755d06c5..bb33ddcef 100644 --- a/src/controller/search_db.cpp +++ b/src/controller/search_db.cpp @@ -236,7 +236,12 @@ void SearchDb::addSearchEntry(const QString &app_name, const QString &lang, //正则替换所有的svg路径 QRegExp exp("src=\"([^>]*svg)\""); exp.setMinimal(true); + QRegExp expPng("src=\"..\/common([^>]*png)\""); + expPng.setMinimal(true); + content = content.replace(exp, QString("src=\"%1/%2\"").arg(strTemp).arg("\\1")); + if (content.contains("common")/* && !content.contains("fig")*/) + content = content.replace(expPng, QString("src=\"%1/../common%2\"").arg(strTemp).arg("\\1")); newContents.replace(i, content); } } @@ -366,7 +371,7 @@ void SearchDb::handleSearchAnchor(const QString &keyword) while (query.next() && (result.size() < kResultLimitation)) { qDebug() << "handleSearchAnchor===> " << query.value(0).toString() << strlistApp; //只将当前预装应用中的内容输出。 - if (strlistApp.contains(query.value(0).toString())) { + if (strlistApp.contains(query.value(0).toString())/* || query.value(0).toString().contains("video-guide")*/) { //搜索结果优先显示应用名称 if (query.value(3) == "h0") { result.prepend(SearchAnchorResult { @@ -623,8 +628,7 @@ void SearchDb::handleSearchContent(const QString &keyword) } } } - const QString sql = - QString(kSearchSelectContent).replace(":lang", lang).replace(":content", keyword); + const QString sql = QString(kSearchSelectContent).replace(":lang", lang).replace(":content", keyword); listStruct.clear(); nH0OfList = 0; @@ -643,7 +647,7 @@ void SearchDb::handleSearchContent(const QString &keyword) const QString anchor = query.value(1).toString(); const QString anchorId = query.value(2).toString(); const QString content = query.value(3).toString(); - if (!strlistApp.contains(app_name)) { + if (!strlistApp.contains(app_name) && !app_name.contains("video-guide")) { continue; } @@ -653,6 +657,10 @@ void SearchDb::handleSearchContent(const QString &keyword) QString highlightContent = highlightKeyword(tmpContent, keyword); + if (app_name.contains("video-guide")) + highlightContent = tmpContent; + + //如果关键字在img路径中,返回后退出本次循环. if (highlightContent.isEmpty() && !anchor.contains(keyword)) continue; @@ -664,9 +672,13 @@ void SearchDb::handleSearchContent(const QString &keyword) //新结构 QRegExp expFit(""); expFit.setMinimal(true); + //相对路径 + QRegExp expRelative(""); + expRelative.setMinimal(true); highlightContent.remove(expFit); highlightContent.remove(expJpg); + highlightContent.remove(expRelative); //处理内容是否省略.. omitHighlight(highlightContent, keyword); diff --git a/src/controller/window_manager.cpp b/src/controller/window_manager.cpp index 44136a8f1..7b9f7fb18 100644 --- a/src/controller/window_manager.cpp +++ b/src/controller/window_manager.cpp @@ -34,6 +34,7 @@ WindowManager::~WindowManager() SendMsg("closeDmanHelper"); updateDb(); restartDmanHelper(); + ConfigManager::releaseInstance(); delete window; } @@ -151,12 +152,6 @@ void WindowManager::SendMsg(const QString &msg) //将进程号+窗口WinId拼接后发给dman-search后台进程 发送信号SendWinInfo->RecvMsg isSuccess = dbusConn.send(dbusMsg); } - - if (isSuccess) { - qDebug() << Q_FUNC_INFO << " sendMsg success"; - } else { - qDebug() << Q_FUNC_INFO << "sendMsg failed"; - } } /** @@ -181,7 +176,6 @@ void WindowManager::setWindow(WebWindow *window) //设置window窗口属性 window->resize(saveWidth, saveHeight); window->setMinimumSize(kWinMinWidth, kWinMinHeight); - window->move((QApplication::desktop()->width() - saveWidth) / 2, (QApplication::desktop()->height() - saveHeight) / 2); } void WindowManager::updateDb() diff --git a/src/dbus/CMakeLists.txt b/src/dbus/CMakeLists.txt index ce7837393..b1ad9f17c 100755 --- a/src/dbus/CMakeLists.txt +++ b/src/dbus/CMakeLists.txt @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: CC0-1.0 - +if(DEFINED ENV{PREFIX}) + set(CMAKE_INSTALL_PREFIX $ENV{PREFIX}) +else() + set(CMAKE_INSTALL_PREFIX /usr) +endif() install(FILES com.deepin.Manual.Open.service com.deepin.Manual.Search.service - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/dbus-1/services/) + DESTINATION share/dbus-1/services/) diff --git a/src/dbus/dbus_consts.cpp b/src/dbus/dbus_consts.cpp index b900f8781..c59b404d8 100644 --- a/src/dbus/dbus_consts.cpp +++ b/src/dbus/dbus_consts.cpp @@ -8,8 +8,11 @@ const char kManualOpenService[] = "com.deepin.Manual.Open"; const char kManualOpenIface[] = "/com/deepin/Manual/Open"; const char kManualSearchService[] = "com.deepin.Manual.Search"; const char kManualSearchIface[] = "/com/deepin/Manual/Search"; -const char kLauncherService[] = "com.deepin.dde.daemon.Launcher"; -const char kLauncherIface[] = "/com/deepin/dde/daemon/Launcher"; +const char kLauncherServiceV20[] = "com.deepin.dde.daemon.Launcher"; +const char kLauncherIfaceV20[] = "/com/deepin/dde/daemon/Launcher"; +const char kLauncherServiceV23[] = "org.deepin.dde.daemon.Launcher1"; +const char kLauncherIfaceV23[] = "/org/deepin/dde/daemon/Launcher1"; + const char kManualWinManagerService[] = "com.deepin.Manual.WinManager"; const char kManualWinManagerIface[] = "/com/deepin/Manual/WinManager"; diff --git a/src/dbus/dbus_consts.h b/src/dbus/dbus_consts.h index 7fcd8b9d3..431f2b046 100644 --- a/src/dbus/dbus_consts.h +++ b/src/dbus/dbus_consts.h @@ -9,8 +9,10 @@ extern const char kManualOpenService[]; extern const char kManualOpenIface[]; extern const char kManualSearchService[]; extern const char kManualSearchIface[]; -extern const char kLauncherService[]; -extern const char kLauncherIface[]; +extern const char kLauncherServiceV20[]; +extern const char kLauncherIfaceV20[]; +extern const char kLauncherServiceV23[]; +extern const char kLauncherIfaceV23[]; extern const char kManualWinManagerService[]; extern const char kManualWinManagerIface[]; diff --git a/src/dbus/generate-iface.sh b/src/dbus/generate-iface.sh index e3888bdd1..b98f11523 100644 --- a/src/dbus/generate-iface.sh +++ b/src/dbus/generate-iface.sh @@ -19,4 +19,4 @@ qdbusxml2cpp com.deepin.dde.daemon.Launcher.xml \ qdbusxml2cpp com.deepin.Manual.Open.xml \ -p manual_open_interface \ - -c ManualOpenInterface \ No newline at end of file + -c ManualOpenInterface diff --git a/src/dbus/launcher_interface.cpp b/src/dbus/launcher_interface.cpp index 49f5bd7e8..ee4369464 100644 --- a/src/dbus/launcher_interface.cpp +++ b/src/dbus/launcher_interface.cpp @@ -1,6 +1,6 @@ /* * This file was generated by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp com.deepin.dde.daemon.Launcher.xml -p launcher_interface -i dbus/dbusvariant/app_info.h -c LauncherInterface + * Command line was: qdbusxml2cpp org.deepin.dde.daemon.Launcher.xml -p launcher_interface -i dbus/dbusvariant/app_info.h -c LauncherInterface * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * diff --git a/src/dbus/launcher_interface.h b/src/dbus/launcher_interface.h index de98a8fab..6ab5cc7b9 100644 --- a/src/dbus/launcher_interface.h +++ b/src/dbus/launcher_interface.h @@ -1,6 +1,6 @@ /* * This file was generated by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp com.deepin.dde.daemon.Launcher.xml -p launcher_interface -i dbus/dbusvariant/app_info.h -c LauncherInterface + * Command line was: qdbusxml2cpp org.deepin.dde.daemon.Launcher1.xml -p launcher_interface -i dbus/dbusvariant/app_info.h -c LauncherInterface * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * @@ -13,8 +13,10 @@ #include "dbus/dbusvariant/app_info.h" +#include + /* - * Proxy class for interface com.deepin.dde.daemon.Launcher + * Proxy class for interface org.deepin.dde.daemon.Launcher1 */ class LauncherInterface : public QDBusAbstractInterface { @@ -22,6 +24,9 @@ class LauncherInterface : public QDBusAbstractInterface public: static inline const char *staticInterfaceName() { + if (Dtk::Core::DSysInfo::majorVersion() == "23") + return "org.deepin.dde.daemon.Launcher1"; + return "com.deepin.dde.daemon.Launcher"; } diff --git a/src/dbus/manual_search_proxy.cpp b/src/dbus/manual_search_proxy.cpp index dd689cc7b..02576217b 100644 --- a/src/dbus/manual_search_proxy.cpp +++ b/src/dbus/manual_search_proxy.cpp @@ -98,23 +98,24 @@ void ManualSearchProxy::OnNewWindowOpen(const QString &data) bool ManualSearchProxy::ManualExists(const QString &app_name) { QStringList moduleList; - QString strManualPath = DMAN_MANUAL_DIR; - for (const QString &type : QDir(strManualPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - if (type == "system" || type == "application") { - QString typePath = strManualPath + "/" + type; - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - moduleList.append(module); + QStringList strManualPathList = Utils::getMdsourcePath(); + foreach (auto strManualPath, strManualPathList) { + for (const QString &type : QDir(strManualPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + if (type == "system" || type == "application") { + QString typePath = strManualPath + "/" + type; + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + moduleList.append(module); + } } - } #if 1 //旧文案结构兼容 - if (systemType.contains(type)) { - QString typePath = strManualPath + "/" + type; - for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { - moduleList.append(module); + if (systemType.contains(type)) { + QString typePath = strManualPath + "/" + type; + for (QString &module : QDir(typePath).entryList(QDir::NoDotAndDotDot | QDir::Dirs)) { + moduleList.append(module); + } } - } #endif + } } - return moduleList.contains(app_name); } diff --git a/src/dbus/org.deepin.dde.daemon.Launcher1.xml b/src/dbus/org.deepin.dde.daemon.Launcher1.xml new file mode 100755 index 000000000..d821a6568 --- /dev/null +++ b/src/dbus/org.deepin.dde.daemon.Launcher1.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/src/resources/CMakeLists.txt b/src/resources/CMakeLists.txt index e47de9c6c..4e891741f 100755 --- a/src/resources/CMakeLists.txt +++ b/src/resources/CMakeLists.txt @@ -1,9 +1,13 @@ -# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: CC0-1.0 +if(DEFINED ENV{PREFIX}) + set(CMAKE_INSTALL_PREFIX $ENV{PREFIX}) +else() + set(CMAKE_INSTALL_PREFIX /usr) +endif() install(FILES deepin-manual.desktop - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications/) + DESTINATION share/applications/) install(FILES themes/common/images/deepin-manual.svg - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/) \ No newline at end of file + DESTINATION share/icons/hicolor/scalable/apps/) + +install(FILES org.deepin.manual.metainfo.xml DESTINATION share/metainfo) \ No newline at end of file diff --git a/src/resources/org.deepin.manual.metainfo.xml b/src/resources/org.deepin.manual.metainfo.xml new file mode 100644 index 000000000..d3fe4e19b --- /dev/null +++ b/src/resources/org.deepin.manual.metainfo.xml @@ -0,0 +1,29 @@ + + + org.deepin.manual + deepin-manual.desktop + DDE + DDE + CC0-1.0 + GPL-3.0+ + + + DDE + Qt + + Deepin Manual + 深度帮助手册 + Manual provides user guides of the system and applications. + 手册旨在帮助用户了解操作系统及其应用程序,提供具体的使用说明和功能说明。 + deepin-manual + +

Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions.

+

深度帮助手册覆盖深度操作系统与深度原生应用,主要以系统/应用操作介绍、技巧为主,旨在将帮助大家进一步了解系统和应用。

+
+ https://github.com/linuxdeepin/developer-center/issues/ + https://github.com/linuxdeepin/developer-center/issues/ + https://bbs.deepin.org/ + + + +
\ No newline at end of file diff --git a/src/view/i18n_proxy.cpp b/src/view/i18n_proxy.cpp index 567b1ebe4..0ebb66329 100644 --- a/src/view/i18n_proxy.cpp +++ b/src/view/i18n_proxy.cpp @@ -18,17 +18,20 @@ I18nProxy::~I18nProxy() QVariantHash I18nProxy::getSentences() const { QVariantHash result { + {"QuickStart", QObject::tr("Quick Start")}, + {"VideoGuide", QObject::tr("Video Guide")}, {"System", QObject::tr("System")}, {"Applications", QObject::tr("Applications")}, - // { "NoResult",QObject::tr( - // "Sorry, there are no search results for \"%1\"") }, {"NoResult", QObject::tr("No search results")}, - // { "WikiSearch", QObject::tr( - // "Change your keywords and try again, or search for it in Deepin Wiki") }, {"ToIndexPage", QObject::tr("Home")}, - // { "SearchInWiki", QObject::tr("Deepin Wiki") }, {"ResultNumSuffix", QObject::tr(" result")}, //单数结果后缀 - {"ResultNumSuffixs", QObject::tr(" results")}}; + {"ResultNumSuffixs", QObject::tr(" results")}, + {"ClicktoView", QObject::tr("Click to view ")}, + {"ViewAll", QObject::tr("View all")}, + {"Support", QObject::tr("Support")}, + {"AppStore", QObject::tr("App Store")} + }; + return result; } diff --git a/src/view/image_viewer_proxy.cpp b/src/view/image_viewer_proxy.cpp index dbe9d2ca6..910069008 100644 --- a/src/view/image_viewer_proxy.cpp +++ b/src/view/image_viewer_proxy.cpp @@ -6,6 +6,7 @@ #include "view/widget/image_viewer.h" #include +#include ImageViewerProxy::ImageViewerProxy(ImageViewer *viewer, QObject *parent) diff --git a/src/view/manual_proxy.cpp b/src/view/manual_proxy.cpp index 0ef4fd88d..375837709 100644 --- a/src/view/manual_proxy.cpp +++ b/src/view/manual_proxy.cpp @@ -10,6 +10,7 @@ #include #include +#include ManualProxy::ManualProxy(QObject *parent) : QObject(parent) @@ -31,10 +32,9 @@ ManualProxy::~ManualProxy() * @return 帮助手册的版本信息 专业版 、服务器版 * 获取帮助手册版本信息 */ -QString ManualProxy::getSystemManualDir() +QStringList ManualProxy::getSystemManualDir() { - QString str = Utils::getSystemManualDir(); - return str; + return Utils::getSystemManualDir();; } /** @@ -78,7 +78,6 @@ void ManualProxy::setApplicationState(const QString &appName) qDebug() << setting->fileName() << ": " << strApp << " not find"; } setting->endGroup(); - setting->sync(); } /** @@ -115,6 +114,12 @@ bool ManualProxy::hasSelperSupport() return b; } +bool ManualProxy::hasAppStore() +{ + bool b = Utils::hasAppStore(); + return b; +} + /** * @brief ManualProxy::finishChannel * 完成channel对象与Qt对象绑定后调用WebWindow中的onChannelFinish方法 @@ -133,6 +138,11 @@ void ManualProxy::supportClick() emit supportBeClick(); } +void ManualProxy::appStoreClick() +{ + emit appStoreBeClick(); +} + bool ManualProxy::bIsLongSon() { return Utils::judgeLoongson(); @@ -148,88 +158,87 @@ QString ManualProxy::appToPath(const QString &appName) { qDebug() << __FUNCTION__ << "========>" << appName; QStringList omitType = Utils::systemToOmit(Dtk::Core::DSysInfo::uosEditionType()); - const QString assetPath = Utils::getSystemManualDir(); QStringList mdList; - QString appPath; - if (appName == "dde") { - appPath = assetPath + "/system/" + appName; - } else { - appPath = assetPath + "/application/" + appName; - } - - if (QDir(appPath).exists()) { - QStringList list = QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); - QString appNameT; - if (list.count() == 1) { - appNameT = list.at(0); - } else if (list.count() > 1) { - qWarning() << Q_FUNC_INFO << assetPath << "dir greater than one:" << list; - appNameT = list.at(1); + QStringList assetsPathList = Utils::getSystemManualDir(); + foreach (auto assetPath, assetsPathList) { + QString appPath; + if (appName == "dde" || appName == kLearnBasicOperations || appName == kCommonApplicationLibraries || appName == "video-guide") { + appPath = assetPath + "/system/" + appName; } else { - appNameT = "error"; - qWarning() << Q_FUNC_INFO << " no dir"; + appPath = assetPath + "/application/" + appName; } - appPath.append("/").append(appNameT).append("/"); - appPath = getAppLocalDir(appPath); - if (omitType.length() > 1) { - mdList.append(appPath + "/" + QString("%1_%2.md").arg(omitType.at(0)).arg(appNameT)); - mdList.append(appPath + "/" + QString("%1_%2.md").arg(omitType.at(1)).arg(appNameT)); - } else { - if (omitType.size() > 0) { + if (QDir(appPath).exists()) { + QStringList list = QDir(appPath).entryList(QDir::NoDotAndDotDot | QDir::Dirs); + QString appNameT; + if (list.count() == 1) { + appNameT = list.at(0); + } else if (list.count() > 1) { + qWarning() << Q_FUNC_INFO << assetPath << "dir greater than one:" << list; + appNameT = list.at(1); + } else { + appNameT = "error"; + qWarning() << Q_FUNC_INFO << " no dir"; + } + appPath.append("/").append(appNameT).append("/"); + appPath = getAppLocalDir(appPath); + + if (omitType.length() > 1) { mdList.append(appPath + "/" + QString("%1_%2.md").arg(omitType.at(0)).arg(appNameT)); + mdList.append(appPath + "/" + QString("%1_%2.md").arg(omitType.at(1)).arg(appNameT)); + } else { + if (omitType.size() > 0) { + mdList.append(appPath + "/" + QString("%1_%2.md").arg(omitType.at(0)).arg(appNameT)); + } } + //根据文档命名规则不带前缀文档为所有文档的兜底文档 + mdList.append(appPath + "/" + QString("%1.md").arg(appNameT)); } - //根据文档命名规则不带前缀文档为所有文档的兜底文档 - mdList.append(appPath + "/" + QString("%1.md").arg(appNameT)); - } - QString oldMdPath = assetPath; + QString oldMdPath = assetPath; #if (DTK_VERSION > DTK_VERSION_CHECK(5, 4, 12, 0)) - if (Dtk::Core::DSysInfo::UosServer == Dtk::Core::DSysInfo::uosType()) { - oldMdPath += "/server"; - } else if (Dtk::Core::DSysInfo::UosHome == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/personal"; - } else if (Dtk::Core::DSysInfo::UosEducation == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/education"; - } else if (Dtk::Core::DSysInfo::UosCommunity == Dtk::Core::DSysInfo::uosEditionType()) { - oldMdPath += "/community"; - } else { - oldMdPath += "/professional"; - } -#else - Dtk::Core::DSysInfo::DeepinType nType = Dtk::Core::DSysInfo::deepinType(); - if (Dtk::Core::DSysInfo::DeepinServer == nType) { - oldMdPath += "/server"; - } else if (Dtk::Core::DSysInfo::DeepinPersonal == nType) { - oldMdPath += "/personal"; - } else { - if (Dtk::Core::DSysInfo::isCommunityEdition()) { + if (Dtk::Core::DSysInfo::UosServer == Dtk::Core::DSysInfo::uosType()) { + oldMdPath += "/server"; + } else if (Dtk::Core::DSysInfo::UosHome == Dtk::Core::DSysInfo::uosEditionType()) { + oldMdPath += "/personal"; + } else if (Dtk::Core::DSysInfo::UosEducation == Dtk::Core::DSysInfo::uosEditionType()) { + oldMdPath += "/education"; + } else if (Dtk::Core::DSysInfo::UosCommunity == Dtk::Core::DSysInfo::uosEditionType()) { oldMdPath += "/community"; } else { oldMdPath += "/professional"; } - } +#else + Dtk::Core::DSysInfo::DeepinType nType = Dtk::Core::DSysInfo::deepinType(); + if (Dtk::Core::DSysInfo::DeepinServer == nType) { + oldMdPath += "/server"; + } else if (Dtk::Core::DSysInfo::DeepinPersonal == nType) { + oldMdPath += "/personal"; + } else { + if (Dtk::Core::DSysInfo::isCommunityEdition()) { + oldMdPath += "/community"; + } else { + oldMdPath += "/professional"; + } + } #endif - oldMdPath.append("/").append(appName).append("/"); - oldMdPath = getAppLocalDir(oldMdPath); - mdList.append(oldMdPath.append("/index.md")); - - qInfo() << mdList; - //初始化赋值,如果为空字符,web层路径请求依旧能onload成功... - QString ret = "error"; - if (QFile(mdList[0]).exists()) { - ret = mdList[0]; - } else if (mdList.length() > 1 && QFile(mdList[1]).exists()) { - ret = mdList[1]; - } else if (mdList.length() > 2 && QFile(mdList[2]).exists()) { - ret = mdList[2]; - } else if (mdList.length() > 3 && QFile(mdList[3]).exists()) { - ret = mdList[3]; - } else { + oldMdPath.append("/").append(appName).append("/"); + oldMdPath = getAppLocalDir(oldMdPath); + mdList.append(oldMdPath.append("/index.md")); + } + qInfo() << "appToPath" << "find markdown file list" << mdList; + QString ret; + for (auto md : mdList) { + if (QFile(md).exists()) { + ret = md; + } + } + if (ret.isEmpty()) { qWarning() << Q_FUNC_INFO << " no exist file:" << appName; + // TODO(wurongjie) 在之前的代码中返回了error,暂不知作用 + return "error"; } qInfo() << "========>" << ret; return ret; @@ -245,6 +254,7 @@ QString ManualProxy::translateTitle(const QString &titleUS) //根据应用desktop文件解析图标名称并获取图标路径 QString ManualProxy::getAppIconPath(const QString &desktopname) { + qDebug() << "getAppIconPath: desktopname:" << desktopname; //首次获取默认图标主题,如果获取失败默认bloom if (strIconTheme.isEmpty()) { QFile file("/usr/share/glib-2.0/schemas/com.deepin.dde.appearance.gschema.xml"); @@ -258,13 +268,15 @@ QString ManualProxy::getAppIconPath(const QString &desktopname) } } - QString filepath = QString("/usr/share/applications/%1.desktop").arg(desktopname); + QString filepath = Utils::getDesktopFilePath(desktopname); QFile file(filepath); QString strIcon = desktopname; if (file.exists()) { Dtk::Core::DDesktopEntry entry(filepath); strIcon = entry.stringValue("Icon"); qDebug() << strIcon; + } else { + qDebug() << QString("filepath:%1 not exit.. desktopname:%2").arg(filepath).arg(desktopname); } QString strIconPath; @@ -307,20 +319,99 @@ QString ManualProxy::getAppIconPath(const QString &desktopname) QString ManualProxy::getLocalAppName(const QString &desktopname) { QString strdisplayname = desktopname; - if (0 == desktopname.compare("dde", Qt::CaseInsensitive)) { + if (0 == desktopname.compare(kLearnBasicOperations, Qt::CaseInsensitive)) { + strdisplayname = tr("Learn Basic Operations"); + } else if (0 == desktopname.compare(kCommonApplicationLibraries, Qt::CaseInsensitive)) { + strdisplayname = tr("Common Application Libraries"); + } else if (0 == desktopname.compare("dde", Qt::CaseInsensitive)) { strdisplayname = tr("Desktop Environment"); } else { - QString filepath = QString("/usr/share/applications/%1.desktop").arg(desktopname); - QFile file(filepath); - if (file.exists()) { - Dtk::Core::DDesktopEntry entry(filepath); - strdisplayname = entry.genericName(); - strdisplayname = strdisplayname.isEmpty() ? entry.ddeDisplayName() : strdisplayname; + QStringList pathList = Utils::getEnvsourcePath(); + foreach (auto path, pathList) { + QString filepath = path + QString("/applications/%1.desktop").arg(desktopname); + QFile file(filepath); + if (file.exists()) { + Dtk::Core::DDesktopEntry entry(filepath); + strdisplayname = entry.genericName(); + strdisplayname = strdisplayname.isEmpty() ? entry.ddeDisplayName() : strdisplayname; + return strdisplayname; + } } } return strdisplayname; } +QVariant ManualProxy::getVideoGuideInfo() +{ + QFile file(kVideoConfigPath); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open file"; + return QVariantList(); + } + + QString locale = QLocale().name(); + //藏语维语使用简体中文 + if (locale == "ug_CN" || locale == "bo_CN") { + locale = "zh_CN"; + } else if (locale == "en_US" || locale == "en_GB") { + locale = "en_US"; + } + + QByteArray jsonData = file.readAll(); + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); + if (jsonDoc.isNull()) { + qDebug() << "Failed to parse JSON"; + return QVariantList(); + } + +// locale = "en_US"; //test + QJsonObject jsonObj = jsonDoc.object(); + + for (QString key : jsonObj.keys()) { + QJsonValue jsValue = jsonObj.value(key); + + if (jsValue.isString() && key == "url") { + videoUrl = jsValue.toString(); + } else if (jsValue.isArray() && key == "videos") { + QJsonArray jsArray = jsValue.toArray(); + QJsonArray resultArray; + + for (int i = 0; i < jsArray.count(); i++) { + if (jsArray[i].isObject()) { + QJsonObject obj = jsArray[i].toObject(); + QJsonObject tmpObj { + {"cover", QString(DMAN_MANUAL_DIR"/system/video-guide/videos/" + obj["cover"].toString())}, + {"url", obj["url"]} + }; + + if (locale == "zh_CN") { + tmpObj.insert("name", obj["name[zh_CN]"]); + } else if(locale == "zh_HK") { + tmpObj.insert("name", obj["name[zh_HK]"]); + } else if(locale == "zh_TW") { + tmpObj.insert("name", obj["name[zh_TW]"]); + } else { + tmpObj.insert("name", obj["name[en_US]"]); + } + + resultArray.append(tmpObj); + } + } + + return resultArray.toVariantList(); + } + } + + return QVariantList(); +} + +void ManualProxy::openVideo(QString url) +{ + if(url.isEmpty()) { + url = videoUrl; + } + QDesktopServices::openUrl(url); +} /** * @brief ManualProxy::saveAppList @@ -343,7 +434,6 @@ void ManualProxy::saveAppList(const QStringList &list) } QStringList l = setting->allKeys(); setting->endGroup(); - setting->sync(); qDebug() << "app config allKeys count : " << l.size(); } @@ -359,7 +449,7 @@ QString ManualProxy::getAppLocalDir(const QString &appPath) if (!dir.exists()) { //藏语维语使用简体中文 if (0 == strlocal.compare("ug_CN") || 0 == strlocal.compare("bo_CN") - || 0 == strlocal.compare("zh_HK") || 0 == strlocal.compare("zh_TW")) { + || 0 == strlocal.compare("zh_HK") || 0 == strlocal.compare("zh_TW")) { AppLocalDir = QString(appPath).append("zh_CN"); } else { AppLocalDir = QString(appPath).append("en_US"); diff --git a/src/view/manual_proxy.h b/src/view/manual_proxy.h index 1f86a7ca0..a081851bb 100644 --- a/src/view/manual_proxy.h +++ b/src/view/manual_proxy.h @@ -19,6 +19,7 @@ class ManualProxy : public QObject void channelInit(); void searchEditTextisEmpty(); void supportBeClick(); + void appStoreBeClick(); //发送页面加载完成时间 void startFinish(qint64); void updateLabel(); @@ -26,14 +27,16 @@ class ManualProxy : public QObject void languageChanged(); public slots: - QString getSystemManualDir(); + QStringList getSystemManualDir(); QStringList getSystemManualList(); void setApplicationState(const QString &appName); QStringList getUsedAppList(); bool hasSelperSupport(); + bool hasAppStore(); void finishChannel(); void supportClick(); + void appStoreClick(); bool bIsLongSon(); void showUpdateLabel(); QString appToPath(const QString &appName); @@ -42,6 +45,9 @@ public slots: QString translateTitle(const QString &titleUS); + QVariant getVideoGuideInfo(); + void openVideo(QString url = ""); + private: void saveAppList(const QStringList &list); QString getAppLocalDir(const QString &appPath); @@ -50,6 +56,7 @@ public slots: QStringList app_list_; QString strIconTheme; QIconLoader *piconload; + QString videoUrl; }; #endif // DEEPIN_MANUAL_VIEW_MANUAL_PROXY_H diff --git a/src/view/search_proxy.cpp b/src/view/search_proxy.cpp index 4061809b0..134948655 100644 --- a/src/view/search_proxy.cpp +++ b/src/view/search_proxy.cpp @@ -5,6 +5,7 @@ #include "view/search_proxy.h" #include +#include SearchProxy::SearchProxy(QObject *parent) : QObject(parent) diff --git a/src/view/web_window.cpp b/src/view/web_window.cpp index d2cd9acc1..2d0511901 100644 --- a/src/view/web_window.cpp +++ b/src/view/web_window.cpp @@ -33,7 +33,7 @@ #include #include #include - +#include #define SEARCH_EDIT_WIDTH 350 // 一般情况下搜索窗口的大小 #define SEARCH_EDIT_HEIGHT 44 // 一般情况下搜索窗口的大小 #define LIMIT_SEARCH_EDIT_WIDTH 750 // 当主窗口 @@ -117,6 +117,8 @@ WebWindow::~WebWindow() search_edit_->deleteLater(); search_edit_ = nullptr; } + + qDebug() << "WebWindow::~WebWindow() done."; } /** @@ -221,14 +223,14 @@ void WebWindow::slot_ThemeChanged() { DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType(); QColor fillColor = DGuiApplicationHelper::instance()->applicationPalette().highlight().color(); - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { if (themeType == DGuiApplicationHelper::DarkType) { web_view_->page()->setBackgroundColor(QColor(37, 37, 37)); } else { web_view_->page()->setBackgroundColor(QColor(248, 248, 248)); } - }else { + } else { if (themeType == DGuiApplicationHelper::DarkType) { web_view_->page()->setBackgroundColor(QColor(0x28, 0x28, 0x28)); QPalette pa = palette(); @@ -251,8 +253,8 @@ void WebWindow::slot_ThemeChanged() void WebWindow::HelpSupportTriggered(bool bActiontrigger) { QDBusInterface interface("com.deepin.dde.ServiceAndSupport", - "/com/deepin/dde/ServiceAndSupport", - "com.deepin.dde.ServiceAndSupport"); + "/com/deepin/dde/ServiceAndSupport", + "com.deepin.dde.ServiceAndSupport"); // selfSupport = 0, //自助支持 // messageConsultation = 1, //留言咨询 @@ -266,10 +268,34 @@ void WebWindow::HelpSupportTriggered(bool bActiontrigger) if (reply.isValid()) { qDebug() << "call com.deepin.dde.ServiceAndSupport success"; } else { - qDebug() << "call com.deepin.dde.ServiceAndSupport failed"; + qDebug() << "call com.deepin.dde.ServiceAndSupport failed, " << interface.lastError(); + // 打开失败,尝试再次打开 + QTimer::singleShot(100, this, [bActiontrigger](){ + QDBusInterface interface("com.deepin.dde.ServiceAndSupport", + "/com/deepin/dde/ServiceAndSupport", + "com.deepin.dde.ServiceAndSupport"); + uint8_t supporttype = 0; + if (!bActiontrigger) { + supporttype = 2; + } + QDBusReply reply = interface.call("ServiceSession", supporttype); + if (!reply.isValid()) { + qDebug() << "call failed again"; + } + }); } } +void WebWindow::appStoreTriggered() +{ + if (!Utils::hasAppStore()) + return; + + QProcess process; + process.startDetached("deepin-home-appstore-client"); + process.waitForFinished(); +} + void WebWindow::slotUpdateLabel() { sendMessage(QIcon(":/common/images/ok.svg"), QObject::tr("The content was updated")); @@ -298,26 +324,26 @@ void WebWindow::resizeEvent(QResizeEvent *event) // 当窗口缩小时,搜索控件会被压缩,现调整为动态变化 int detal = LIMIT_SEARCH_EDIT_WIDTH - event->size().width(); - if(detal <= 0){ + if (detal <= 0) { search_edit_->setFixedWidth(SEARCH_EDIT_WIDTH); - }else if(detal != LIMIT_SEARCH_EDIT_WIDTH){ + } else if (detal != LIMIT_SEARCH_EDIT_WIDTH) { search_edit_->setFixedWidth(SEARCH_EDIT_WIDTH - detal); } - if(completion_window_->isVisible()){ + if (completion_window_->isVisible()) { completion_window_->autoResize(); // Move to below of search edit. const QPoint local_point(this->rect().width() / 2 - search_edit_->width() / 2, titlebar()->height() - 3); - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { const QPoint global_point(this->mapToGlobal(local_point)); completion_window_->move(global_point); - }else { + } else { completion_window_->move(local_point); } } - if(web_view_){ + if (web_view_) { slot_ThemeChanged(); } } @@ -365,14 +391,13 @@ QVariant WebWindow::inputMethodQuery(Qt::InputMethodQuery prop) const bool WebWindow::eventFilter(QObject *watched, QEvent *event) { //warland环境下watched的objectname不是QMainWindowClassWindow,先去除验证 - DIconButton* btn = findChild("DTitlebarDWindowMaxButton"); - if (event->type() == QEvent::MouseButtonRelease && qApp->activeWindow() == this && !btn->isDown()) { + if (event->type() == QEvent::MouseButtonRelease && qApp->activeWindow() == this) { QRect rect = hasWidgetRect(search_edit_); if (web_view_ && web_view_->selectedText().isEmpty() && !rect.contains(QCursor::pos())) { this->setFocus(); } } - if (event->type() == QEvent::KeyPress && qApp->activeWindow() == this ) { + if (event->type() == QEvent::KeyPress && qApp->activeWindow() == this) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_V && keyEvent->modifiers().testFlag(Qt::ControlModifier)) { @@ -388,7 +413,7 @@ bool WebWindow::eventFilter(QObject *watched, QEvent *event) || (keyEvent->key() <= Qt::Key_9 && keyEvent->key() >= Qt::Key_0) || (keyEvent->key() == Qt::Key_Space)) && keyEvent->modifiers() == Qt::NoModifier) { - search_edit_->lineEdit()->setFocus(); + search_edit_->lineEdit()->setFocus(); } else if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { if (search_edit_->lineEdit()->hasFocus()) { //搜索框内容为空时,按回车键回到未搜索页面 @@ -411,7 +436,7 @@ bool WebWindow::eventFilter(QObject *watched, QEvent *event) QMouseEvent *mouseEvent = static_cast(event); - if(nullptr != mouseEvent){ + if (nullptr != mouseEvent) { switch (mouseEvent->button()) { case Qt::BackButton: { qDebug() << "eventFilter back"; @@ -431,7 +456,7 @@ bool WebWindow::eventFilter(QObject *watched, QEvent *event) } //wayland 当搜索结果隐藏之后,将无法触发鼠标点击事件无法跳转内容 - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { if (!hasWidgetRect(search_edit_).contains(mapFromGlobal(QCursor::pos()))) { completion_window_->hide(); } @@ -442,7 +467,7 @@ bool WebWindow::eventFilter(QObject *watched, QEvent *event) if (event->type() == QEvent::FontChange && watched == this) { if (this->settings_proxy_) { qDebug() << "eventFilter QEvent::FontChange"; - auto fontInfo = this->fontInfo(); + QFontInfo fontInfo = this->fontInfo(); emit this->settings_proxy_->fontChangeRequested(fontInfo.family(), fontInfo.pixelSize()); } @@ -509,6 +534,9 @@ void WebWindow::onManualSearchByKeyword(const QString &keyword) */ void WebWindow::onAppearanceChanged(QString, QMap map, QStringList) { + if (image_viewer_) + image_viewer_->hide(); + //20210630codereview if (map.isEmpty()) { return; @@ -532,6 +560,16 @@ void WebWindow::onAppearanceChanged(QString, QMap map, QStrin } } +void WebWindow::onTimeoutLock(const QString &serviceName, QVariantMap key2value, QStringList) +{ + Q_UNUSED(serviceName); + + if (key2value.value("Locked").value()) { + if (image_viewer_) + image_viewer_->hide(); + } +} + /** * @brief WebWindow::initUI * @note 初始化窗口 @@ -539,9 +577,9 @@ void WebWindow::onAppearanceChanged(QString, QMap map, QStrin void WebWindow::initUI() { //搜索结果框可移至主窗口创建完成后 - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { completion_window_ = new SearchCompletionWindow(); - }else { + } else { completion_window_ = new SearchCompletionWindow(this); completion_window_->hide(); } @@ -589,14 +627,16 @@ void WebWindow::initUI() QAction *pHelpSupport = new QAction(QObject::tr("Support")); pMenu->addAction(pHelpSupport); this->titlebar()->setMenu(pMenu); - connect(pHelpSupport, &QAction::triggered, this, [this] { this->HelpSupportTriggered(true); }); + connect(pHelpSupport, &QAction::triggered, this, [this] { + this->HelpSupportTriggered(true); + }); } this->titlebar()->addWidget(buttonFrame, Qt::AlignLeft); this->titlebar()->addWidget(search_edit_, Qt::AlignCenter); this->titlebar()->setSeparatorVisible(false); this->titlebar()->setIcon(QIcon::fromTheme("deepin-manual")); - if(Utils::judgeWayLand()){ + if (Utils::judgeWayLand()) { this->titlebar()->setAutoFillBackground(false); this->titlebar()->setBackgroundRole(QPalette::Window); } @@ -646,7 +686,7 @@ void WebWindow::initWebView() web_view_->setAttribute(Qt::WA_KeyCompression, true); web_view_->setAttribute(Qt::WA_InputMethodEnabled, true); - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { web_view_->setAttribute(Qt::WA_NativeWindow, true); } QNetworkProxyFactory::setUseSystemConfiguration(false); @@ -673,6 +713,7 @@ void WebWindow::initWebView() connect(manual_proxy_, &ManualProxy::WidgetLower, this, &WebWindow::lower); connect(manual_proxy_, &ManualProxy::updateLabel, this, &WebWindow::slotUpdateLabel); connect(manual_proxy_, &ManualProxy::supportBeClick, this, [this] { this->HelpSupportTriggered(); }); + connect(manual_proxy_, &ManualProxy::appStoreBeClick, this, [this] { this->appStoreTriggered(); }); //web主页html路径 const QFileInfo info(kIndexPage); @@ -704,9 +745,14 @@ void WebWindow::saveWindowSize() setting->setValue(kConfigWindowHeight, height()); setting->endGroup(); } - +/** + * @brief WebWindow::updateDb 更新数据库 + */ void WebWindow::updateDb() { + if (!search_manager_) + return; + //更新数据库 emit search_manager_->updateDb(); } @@ -723,9 +769,11 @@ void WebWindow::initShortcuts() scWndReize->setContext(Qt::WindowShortcut); scWndReize->setAutoRepeat(false); connect(scWndReize, &QShortcut::activated, this, [this] { - if (this->windowState() & Qt::WindowMaximized){ + if (this->windowState() & Qt::WindowMaximized) + { this->showNormal(); - } else if (this->windowState() == Qt::WindowNoState){ + } else if (this->windowState() == Qt::WindowNoState) + { this->showMaximized(); } }); @@ -757,6 +805,11 @@ void WebWindow::initDBus() } else { qDebug() << "connectToBus()::connect() PropertiesChanged success"; } + + // 锁屏通知,显示隐藏图片界面,才能保证图片界面正常隐藏,否则图片界面会一直阻塞主线程鼠标事件传递 + QDBusConnection::sessionBus().connect("com.deepin.SessionManager", "/com/deepin/SessionManager", + "org.freedesktop.DBus.Properties", "PropertiesChanged", this, + SLOT(onTimeoutLock(QString, QVariantMap, QStringList))); } /** @@ -1029,10 +1082,10 @@ void WebWindow::onSearchAnchorResult(const QString &keyword, const SearchAnchorR // Move to below of search edit. const QPoint local_point(this->rect().width() / 2 - search_edit_->width() / 2, titlebar()->height() - 3); - if(!Utils::judgeWayLand()){ + if (!Utils::judgeWayLand()) { const QPoint global_point(this->mapToGlobal(local_point)); completion_window_->move(global_point); - }else { + } else { completion_window_->move(local_point); } diff --git a/src/view/web_window.h b/src/view/web_window.h index a84a5194a..954fbfa06 100644 --- a/src/view/web_window.h +++ b/src/view/web_window.h @@ -82,6 +82,7 @@ public slots: void settingContextMenu(); QRect hasWidgetRect(QWidget *); void HelpSupportTriggered(bool bActiontrigger = false); + void appStoreTriggered(); QString app_name_; QString keyword_; @@ -120,6 +121,8 @@ private slots: void onSetKeyword(const QString &keyword); void onManualSearchByKeyword(const QString &keyword); void onAppearanceChanged(QString, QMap, QStringList); + // 是否锁屏 + void onTimeoutLock(const QString &, QVariantMap, QStringList); }; #endif // DEEPIN_MANUAL_VIEW_WEB_WINDOW_H diff --git a/src/web/toManual/index.html b/src/web/toManual/index.html index a16a03e3c..23e67fc80 100644 --- a/src/web/toManual/index.html +++ b/src/web/toManual/index.html @@ -14,4 +14,4 @@ - \ No newline at end of file + diff --git a/src/web/toManual/js/App.js b/src/web/toManual/js/App.js index 30149ce66..67bc86da8 100755 --- a/src/web/toManual/js/App.js +++ b/src/web/toManual/js/App.js @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import React from 'react'; +import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { render } from 'react-dom'; import { Router as Router, Switch, Route, Link } from 'react-router-dom'; @@ -23,13 +23,14 @@ global.lastUrlBeforeSearch = '/'; global.lastHistoryIndex = 0; global.lastAction = 'PUSH'; global.isShowHelperSupport = false; +global.isShowAppStore = false; global.scrollBehavior = 'smooth'; global.bIsReload = false; // global.gHistoryGo = 0; global.readFile = (fileName, callback) => { - console.log("global.readFile..."); + console.log("global.readFile...", fileName); let xhr = new XMLHttpRequest(); xhr.open('GET', fileName); xhr.onload = () => { @@ -40,6 +41,68 @@ global.readFile = (fileName, callback) => { xhr.send(); }; +const Support = ({ text }) => { + const [isHovered, setIsHovered] = useState(false); + const [tooltipText, setTooltipText] = useState(text); + + // useEffect(() => { + // setTooltipText(text); + // }, [text]); + + useEffect(() => { + if (isHovered) { + setTooltipText(global.i18n['Support']); + } + }, [isHovered]); + + useEffect(() => { + if (!isHovered) { + setTooltipText(''); + } + }, [isHovered]); + + return ( + global.isShowHelperSupport ?
global.qtObjects.manual.supportClick()} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + style={{ userSelect: 'none' }} + > + + {isHovered &&
{tooltipText}
} +
:
+ ); +}; + +const AppStore = ({ text }) => { + const [isHovered, setIsHovered] = useState(false); + const [tooltipText, setTooltipText] = useState(text); + + useEffect(() => { + if (isHovered) { + setTooltipText(global.i18n['AppStore']); + } + }, [isHovered]); + + useEffect(() => { + if (!isHovered) { + setTooltipText(''); + } + }, [isHovered]); + + return ( + global.isShowAppStore ?
global.qtObjects.manual.appStoreClick()} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + style={{ userSelect: 'none' }} + > + + {isHovered &&
{tooltipText}
} +
:
+ ); +}; + class App extends React.Component { constructor(props, context) { super(props, context); @@ -49,7 +112,7 @@ class App extends React.Component { searchResult: [], mismatch: false, historyGO: 0 - // changeAppList:[] + // changeAppList:[] }; new QWebChannel(qt.webChannelTransport, this.initQt.bind(this)); } @@ -70,6 +133,9 @@ class App extends React.Component { global.qtObjects.manual.hasSelperSupport(bFlag => { global.isShowHelperSupport = bFlag; }); + global.qtObjects.manual.hasAppStore(bFlag => { + global.isShowAppStore = bFlag; + }); global.qtObjects.manual.bIsLongSon(isLongSon => { if (isLongSon) { @@ -152,7 +218,7 @@ class App extends React.Component { global.setTheme(themeType); } onContentResult(appName, titleList, idList, contentList) { - console.log('搜索结果', appName, titleList, idList, contentList); + console.log('app 搜索结果', appName, titleList, idList, contentList); let { searchResult } = this.state; let filePath; // if (appName == "dde") @@ -163,14 +229,17 @@ class App extends React.Component { // { // filePath = `${global.path}/application/${appName}/${global.lang}/index.md`; // } - var myPromise = new Promise(function(resolve, reject) { - global.qtObjects.manual.appToPath(appName, function(filepath) { + var myPromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.appToPath(appName, function (filepath) { filePath = filepath; resolve() }) }); myPromise.then(() => { + if (appName === "video-guide") { + filePath = "video-guide"; + } searchResult.push({ file: filePath, idList, @@ -289,6 +358,15 @@ class App extends React.Component { let { searchResult, mismatch } = this.state; return { searchResult, mismatch }; } + + isbase64(str) { + if (str == '' || str.trim == '') { return false; } + try { return btoa(atob(str)) == str } + catch (err) { + return false; + } + } + componentWillReceiveProps(nextProps) { console.log("app componentWillReceiveProps", this.context.router.history); console.log("this location: " + this.context.router.history.location); @@ -296,19 +374,22 @@ class App extends React.Component { var pathList = pathName.split("/"); var cKeyword = ''; - //search页===>/search/:keyword - //open页=====>/open/:file/:hash?/:key? + if (pathName.includes("common-application-libraries")) + document.documentElement.style.setProperty(`--app-store-visibility`, 'visible'); + else + document.documentElement.style.setProperty(`--app-store-visibility`, 'hidden'); + + //search页===>/search/:keyword + //open页=====>/open/:file/:hash?/:key? if (pathList.length == 3) { cKeyword = pathList[2]; } else if (pathList.length == 5) { cKeyword = pathList[4]; } - // global.qtObjects.search.getKeyword(decodeURIComponent(cKeyword)); - if (cKeyword == '%') { - global.qtObjects.search.getKeyword(cKeyword); + if (this.isbase64(cKeyword)) { + global.qtObjects.search.getKeyword(decodeURIComponent(atob(cKeyword))); } else { - console.log("decode URIComponent componentWillReceiveProps"); global.qtObjects.search.getKeyword(decodeURIComponent(cKeyword)); } @@ -358,7 +439,7 @@ class App extends React.Component { hash = 'h1' } file = encodeURIComponent(file); - console.log("globla.open..........."); + // console.log("globla.open........... ", file); hash = encodeURIComponent(hash); global.hash = hash; @@ -393,8 +474,8 @@ class App extends React.Component { // filePath = `${global.path}/application/${file}/${global.lang}/index.md` // } - var myPromise = new Promise(function(resolve, reject) { - global.qtObjects.manual.appToPath(file, function(filepath) { + var myPromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.appToPath(file, function (filepath) { filePath = filepath; resolve() }) @@ -406,10 +487,9 @@ class App extends React.Component { let d = document.createElement('div'); d.innerHTML = html; let dlist = d.querySelectorAll(`[text="${title}"]`); - if(dlist.length == 0) - { - var translatePromise = new Promise(function(resolve, reject) { - global.qtObjects.manual.translateTitle(title, function(titleTr) { + if (dlist.length == 0) { + var translatePromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.translateTitle(title, function (titleTr) { title = titleTr; resolve() }) @@ -418,21 +498,21 @@ class App extends React.Component { translatePromise.then(() => { dlist = d.querySelectorAll(`[text="${title}"]`); let hashID = 'h0'; - for (let i = 0; i < dlist.length; i++) { - hashID = dlist[i].id; + for (let i = 0; i < dlist.length; i++) { + hashID = dlist[i].id; } global.open(file, hashID); }); } - else - { + else { let hashID = 'h0'; - for (let i = 0; i < dlist.length; i++) { - hashID = dlist[i].id; + for (let i = 0; i < dlist.length; i++) { + hashID = dlist[i].id; } - global.open(file, hashID);} - - + global.open(file, hashID); + } + + }) }); } else { @@ -477,10 +557,29 @@ class App extends React.Component { if (toR.length == 1) toR = '0' + toR; if (toG.length == 1) toG = '0' + toG; if (toB.length == 1) toB = '0' + toB; - var toRGB = "#" + toR + toG + toB; console.log('hover color:', toRGB); document.documentElement.style.setProperty(`--nav-hash-hover-color`, toRGB); + + var pR = parseInt(r, 16); + var pG = parseInt(g, 16); + var pB = parseInt(b, 16); + pR -= 16; + pG -= 16; + pB -= 16; + if (pR > 255) pR = 255; + if (pG > 255) pG = 255; + if (pB > 255) pB = 255; + toR = pR.toString(16); + toG = pG.toString(16); + toB = pB.toString(16); + if (toR.length == 1) toR = '0' + toR; + if (toG.length == 1) toG = '0' + toG; + if (toB.length == 1) toB = '0' + toB; + toRGB = "#" + toR + toG + toB; + document.documentElement.style.setProperty(`--nav-hash-press-color`, toRGB); + // toRGB = "rgba(" + pR + ", " + pG + ", " + pB + ", " + "0.4)"; + // document.documentElement.style.setProperty(`--active-shadow-color`, toRGB); } global.setWordFontfamily = (strFontFamily) => { @@ -506,8 +605,8 @@ class App extends React.Component { document.documentElement.style.setProperty(`--body-color-white2black`, '#000000'); document.documentElement.style.setProperty(`--app-word-color`, '#C0C6D4'); document.documentElement.style.setProperty(`--nav-background-color`, '#282828'); - document.documentElement.style.setProperty(`--nav-h2-word-color`, '#C0C6D4'); - document.documentElement.style.setProperty(`--nav-h3-word-color`, '#C0C0C0'); + document.documentElement.style.setProperty(`--nav-h2-word-color`, 'rgba(255, 255, 255, 0.85)'); + document.documentElement.style.setProperty(`--nav-h3-word-color`, 'rgba(255, 255, 255, 0.7)'); document.documentElement.style.setProperty('--nav-hove-word-color', '#C0C6D4'); document.documentElement.style.setProperty('--nav-hove-border-color', 'rgba(0, 0, 0, 0.3)'); //document.documentElement.style.setProperty(`--nav-hash-word-color`, '#0059D2'); //btnlist 改这行 @@ -528,7 +627,7 @@ class App extends React.Component { document.documentElement.style.setProperty(`--scrollbar-div-background-color`, 'rgba(255,255,255,0.2)'); document.documentElement.style.setProperty(`--scrollbar-div-hover-background-color`, 'rgba(255,255,255,0.25)'); document.documentElement.style.setProperty(`--scrollbar-div-select-background-color`, 'rgba(255,255,255,0.3)'); - document.documentElement.style.setProperty(`--index-h2-color`, 'rgba(255,255,255,0.05)'); + document.documentElement.style.setProperty(`--index-h2-color`, 'rgba(255,255,255,0.1)'); document.documentElement.style.setProperty(`--search-button-background-color-start`, '#484848'); document.documentElement.style.setProperty(`--search-button-background-color-end`, '#414141'); document.documentElement.style.setProperty(`--search-button-hover-color-start`, '#676767'); @@ -536,8 +635,9 @@ class App extends React.Component { document.documentElement.style.setProperty(`--search-WikiSearch-color`, '#6D7C88'); document.documentElement.style.setProperty(`--search-itemTitle-word-color`, '#C0C6D4'); document.documentElement.style.setProperty(`--search-context-word-color`, '#6D7C88'); - document.documentElement.style.setProperty(`--tips-background-color`, '#2A2A2A'); - document.documentElement.style.setProperty(`--tips-border-color`, 'rgba(0, 0, 0,0.3)'); + document.documentElement.style.setProperty(`--tips-background-color`, 'rgba(42, 42, 42, 0.8)'); + document.documentElement.style.setProperty(`--tips-border-color`, 'rgba(0, 0, 0, 0.3)'); + document.documentElement.style.setProperty('--tips-shadow-color', 'rgba(0, 0, 0, 0.2)'); } else if ("LightType" == themeType) { console.log('LightType'); document.documentElement.style.setProperty(`--nav-hover-color`, 'rgba(0,0,0,0.1)'); @@ -545,10 +645,10 @@ class App extends React.Component { document.documentElement.style.setProperty(`--body-color-white2black`, '#FFFFFF'); document.documentElement.style.setProperty(`--app-word-color`, '#414D68'); document.documentElement.style.setProperty(`--nav-background-color`, '#FFFFFF'); - document.documentElement.style.setProperty(`--nav-h2-word-color`, '#001A2E'); - document.documentElement.style.setProperty(`--nav-h3-word-color`, '#001A2E'); + document.documentElement.style.setProperty(`--nav-h2-word-color`, 'rgba(0, 0, 0, 0.85)'); + document.documentElement.style.setProperty(`--nav-h3-word-color`, 'rgba(0, 0, 0, 0.7)'); document.documentElement.style.setProperty('--nav-hove-word-color', '#000000'); - document.documentElement.style.setProperty('--nav-hove-border-color', 'rgba(0, 0, 0, 0.05)'); + document.documentElement.style.setProperty('--nav-hove-border-color', 'rgba(0, 0, 0, 0.05)'); // document.documentElement.style.setProperty(`--nav-hash-word-color`, '#ca0c16'); //btn list 改这一行 document.documentElement.style.setProperty(`--article-read-word-color`, '#000000'); document.documentElement.style.setProperty(`--article-read-h2-word-color`, '#2CA7F8'); @@ -557,7 +657,7 @@ class App extends React.Component { document.documentElement.style.setProperty(`--article-table-cell-border-color`, 'rgba(0, 0, 0, 0.05)'); document.documentElement.style.setProperty(`--index-item-background-color`, '#FFFFFF'); document.documentElement.style.setProperty(`--index-item-hover-color`, 'rgba(0,0,0,0.05)'); - document.documentElement.style.setProperty(`--index-item-span-word-color`, '#414D68'); + document.documentElement.style.setProperty(`--index-item-span-word-color`, 'rgba(0, 0, 0, 0.7)'); document.documentElement.style.setProperty(`--search-noresult-word-color`, '#000000'); document.documentElement.style.setProperty(`--search-button-word-color`, '#414D68'); document.documentElement.style.setProperty(`--search-button-hover-word-color`, '#001B2E'); @@ -575,11 +675,19 @@ class App extends React.Component { document.documentElement.style.setProperty(`--search-WikiSearch-color`, '#7a7a7a'); document.documentElement.style.setProperty(`--search-itemTitle-word-color`, '#000000'); document.documentElement.style.setProperty(`--search-context-word-color`, '#000000'); - document.documentElement.style.setProperty(`--tips-background-color`, '#F7F7F7'); - document.documentElement.style.setProperty(`--tips-border-color`, 'rgba(0,0,0,0.05)'); + document.documentElement.style.setProperty(`--tips-background-color`, 'rgba(247, 247, 247, 0.6)'); + document.documentElement.style.setProperty(`--tips-border-color`, 'rgba(0, 0, 0, 0.05)'); + document.documentElement.style.setProperty('--tips-shadow-color', 'rgba(0, 0, 0, 0.2)'); } else { console.log('Null'); } + + const windowWidth = window.innerWidth; + var leftDistance = windowWidth - 70 + 'px'; + if (windowWidth > 1630 + 234) { + leftDistance = (windowWidth - 1630) / 2 + 1630 + 50 + 'px'; + } + document.documentElement.style.setProperty(`--support-position`, leftDistance); } let Base64 = { @@ -595,7 +703,7 @@ class App extends React.Component { decode(str) { // Going backwards: from bytestream, to percent-encoding, to original string. console.log("decode URIComponent decode"); - return decodeURIComponent(atob(str).split('').map(function(c) { + return decodeURIComponent(atob(str).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } @@ -618,7 +726,7 @@ class App extends React.Component { this.setState({ searchResult: [] }); this.context.router.history.push( - '/search/' + encodeURIComponent(decodeKeyword) + '/search/' + btoa(encodeURIComponent(decodeKeyword)) ); return; @@ -637,7 +745,7 @@ class App extends React.Component { this.setState({ searchResult: [] }); this.context.router.history.push( - '/search/' + encodeURIComponent(decodeKeyword) + '/search/' + btoa(encodeURIComponent(decodeKeyword)) ); }; @@ -656,6 +764,8 @@ class App extends React.Component { this.context.router.history.goBack(); }; this.componentDidUpdate(); + + document.documentElement.style.setProperty(`--app-store-visibility`, 'hidden'); } componentDidUpdate() { if (global.qtObjects) { @@ -671,27 +781,20 @@ class App extends React.Component { } } render() { - return ( < - div > { - this.state.init && ( < - Switch > - < - Route exact path = "/" - component = { Index } - /> < - Route path = "/index" - component = { Index } - /> < - Route path = "/open/:file/:hash?/:key?" - component = { Main } - /> < - Route path = "/search/:keyword" - component = { Search } - /> < - /Switch> - ) - } < - /div> + return ( +
+ {this.state.init && ( + + + + + + + )} + + + +
); } } @@ -703,11 +806,19 @@ App.childContextTypes = { mismatch: PropTypes.bool }; -render( < - Router history = { createMemoryHistory('/') } > - < - App / > - < - /Router>, +window.addEventListener('resize', function () { + const windowWidth = window.innerWidth; + var leftDistance = windowWidth - 70 + 'px'; + + if (windowWidth > 1630 + 234) { + leftDistance = (windowWidth - 1630) / 2 + 1630 + 50 + 'px'; + } + document.documentElement.style.setProperty(`--support-position`, leftDistance); +}); + +render( + + + , document.getElementById('app') ); diff --git a/src/web/toManual/js/article.jsx b/src/web/toManual/js/article.jsx index c24dfd7af..a3b9609af 100755 --- a/src/web/toManual/js/article.jsx +++ b/src/web/toManual/js/article.jsx @@ -16,21 +16,21 @@ export default class Article extends Component { preview: null, smoothScroll: false, fillblank: null, - bIsTimerOut:true + bIsTimerOut: true }; - + this.scroll = this.scroll.bind(this); - this.click = this.click.bind(this); + this.click = this.click.bind(this); this.contentMenu = this.contentMenu.bind(this) var timerObj; - var bIsMount=false; + var bIsMount = false; } //滚动到锚点 scrollToHash() { - console.log("article scrollToHash ",this.hash); + console.log("article scrollToHash ", this.hash); let tempHash = this.hash; - + const hashNode = document.getElementById(tempHash); console.log("article scrollToHash temphash: " + tempHash + " " + hashNode); @@ -39,20 +39,19 @@ export default class Article extends Component { } if (hashNode) { - console.log(" article scrollToHash===============>",this.bIsMount); + console.log(" article scrollToHash===============>", this.bIsMount); clearTimeout(this.timerObj); this.setState({ smoothScroll: true }); var timeVar = 800; - if (this.bIsMount) - { - timeVar = 3*1000; + if (this.bIsMount) { + timeVar = 3 * 1000; this.bIsMount = false; } this.timerObj = setTimeout(() => { - this.setState({ smoothScroll: false }); - },timeVar); + this.setState({ smoothScroll: false }); + }, timeVar); scrollIntoView(hashNode, { behavior: 'smooth', block: 'start' }).then(() => { @@ -61,7 +60,7 @@ export default class Article extends Component { // this.setState({ smoothScroll: false }); //scrollIntoView函数存在异步,如果tempHash != this.hash时,说明存在异步操作,直接return. - if(tempHash != this.hash) return; + if (tempHash != this.hash) return; console.log("scrollIntoView finish.."); //find parent h3 title of h4 title @@ -69,10 +68,10 @@ export default class Article extends Component { var currH3Hash = ''; for (let i = 0; i < hList.length; i++) { if (hList[i].tagName == 'H3') { - currH3Hash = hList[i].id; + currH3Hash = hList[i].id; } if (tempHash == hList[i].id && (hList[i].tagName == 'H4' || hList[i].tagName == 'H5')) { - console.log("article: scroll hlist:" + hList[i].tagName + "," + hList[i].id); + console.log("article: scroll hlist:" + hList[i].tagName + "," + hList[i].id); console.log("currH3Hash:" + currH3Hash); this.hash = currH3Hash; this.props.setHash(currH3Hash); @@ -82,14 +81,13 @@ export default class Article extends Component { } }); } else { - if (this.props.hlist.length > 0) - { + if (this.props.hlist.length > 0) { this.props.setHash(this.props.hlist[0].id); } } } - componentWillMount(){ + componentWillMount() { console.log("article componentWillMount"); } @@ -99,8 +97,8 @@ export default class Article extends Component { this.componentDidUpdate(); } - shouldComponentUpdate(nextProps,nextState){ - console.log("article shouldComponentUpdate====",this.hash , "prop hash:" ,this.props.hash); + shouldComponentUpdate(nextProps, nextState) { + console.log("article shouldComponentUpdate====", this.hash, "prop hash:", this.props.hash); // if (this.hash == this.props.hash) // { // return false; @@ -109,7 +107,7 @@ export default class Article extends Component { } componentWillReceiveProps(nextProps) { - console.log("article componentWillReceiveProps nextfile",nextProps.nextProps,' prop.file:',this.props.file); + console.log("article componentWillReceiveProps nextfile", nextProps.nextProps, ' prop.file:', this.props.file); if (nextProps.file != this.props.file) { this.hash = ''; this.load = false; @@ -120,7 +118,7 @@ export default class Article extends Component { componentWillUpdate() { console.log("article componentWillUpdate.."); var alink_arr = document.getElementsByTagName('a'); - for(var i=0; i"+ this.props.hash); + console.log("article componentDidUpdate.." + this.hash + " props hash->" + this.props.hash); if (this.hash != this.props.hash) { this.hash = this.props.hash; this.scrollToHash(); @@ -138,20 +136,20 @@ export default class Article extends Component { let read = article.querySelector('#read'); read.focus(); let imgList = [...article.querySelectorAll('img')]; - + let loadCount = 0; let promiseAll = []; imgList.map(el => { promiseAll.push(new Promise((resolve, reject) => { - el.onload = function() { - console.log("------img onload---------"); - resolve(el); - }; - el.onerror = function() { - console.log("------img onerror---------"); - resolve(el); - } - })) + el.onload = function () { + console.log("------img onload---------"); + resolve(el); + }; + el.onerror = function () { + console.log("------img onerror---------"); + resolve(el); + } + })) }); Promise.all(promiseAll).then(() => { // 全部图片加载完成 @@ -181,20 +179,18 @@ export default class Article extends Component { return id; } - handleWheelScroll(e){ + handleWheelScroll(e) { global.isMouseScrollArticle = true; } handleKeyDown(e) { - if (38 == e.keyCode || 40 == e.keyCode) - { + if (38 == e.keyCode || 40 == e.keyCode) { global.isMouseScrollArticle = true; } } handleKeyUp(e) { - if (38 == e.keyCode || 40 == e.keyCode) - { + if (38 == e.keyCode || 40 == e.keyCode) { global.isMouseScrollArticle = true; } } @@ -232,13 +228,12 @@ export default class Article extends Component { } hash = hList[i].id; } - console.log("article: scroll this.hash:" + this.hash + " hash:" + hash); + console.log("article: scroll this.hash:" + this.hash + " hash:" + hash); if (this.hash != hash) { console.log('article: scroll hash update'); this.hash = hash; this.props.setHash(hash); - if (global.isMouseScrollArticle) - { + if (global.isMouseScrollArticle) { this.props.setScroll(hash); } } @@ -250,7 +245,7 @@ export default class Article extends Component { if (this.state.preview != null) { this.setState({ preview: null }); } - console.log("======>",e.target.nodeName); + console.log("======>", e.target.nodeName); switch (e.target.nodeName) { case 'IMG': e.preventDefault(); @@ -262,34 +257,33 @@ export default class Article extends Component { global.qtObjects.imageViewer.open(src); return; case 'A': - { - const dmanProtocol = 'dman://'; - const hashProtocol = '#'; - const httpProtocol = 'http'; - const href = e.target.getAttribute('href'); - console.log("href:"+ href); - switch (0) { - case href.indexOf(hashProtocol): - e.preventDefault(); - this.props.setHash(document.querySelector(`[text="${href.slice(1)}"]`).id); - return; - case href.indexOf(dmanProtocol): - e.preventDefault(); - const [appName, hash] = href.slice(dmanProtocol.length + 1).split('#'); - global.openTitle(appName,hash); - return; - case href.indexOf(httpProtocol): - e.preventDefault(); - global.qtObjects.imageViewer.openHttpUrl(href); - return; + { + const dmanProtocol = 'dman://'; + const hashProtocol = '#'; + const httpProtocol = 'http'; + const href = e.target.getAttribute('href'); + console.log("href:" + href); + switch (0) { + case href.indexOf(hashProtocol): + e.preventDefault(); + this.props.setHash(document.querySelector(`[text="${href.slice(1)}"]`).id); + return; + case href.indexOf(dmanProtocol): + e.preventDefault(); + const [appName, hash] = href.slice(dmanProtocol.length + 1).split('#'); + global.openTitle(appName, hash); + return; + case href.indexOf(httpProtocol): + e.preventDefault(); + global.qtObjects.imageViewer.openHttpUrl(href); + return; + } } - } //解决bug-46888, 当a标签内含有span标签,点击获取的是span标签,此时用其父元素来处理. case 'SPAN': e.preventDefault(); var parNode = e.target.parentNode; - if (parNode.nodeName == 'A') - { + if (parNode.nodeName == 'A') { const dmanProtocol = 'dman://'; const hashProtocol = '#'; const httpProtocol = 'http'; @@ -302,7 +296,7 @@ export default class Article extends Component { case hrefTmp.indexOf(dmanProtocol): e.preventDefault(); const [appName, hash] = hrefTmp.slice(dmanProtocol.length + 1).split('#'); - global.openTitle(appName,hash); + global.openTitle(appName, hash); return; case hrefTmp.indexOf(httpProtocol): e.preventDefault(); @@ -315,44 +309,44 @@ export default class Article extends Component { } //右键菜单事件 - contentMenu(e){ + contentMenu(e) { switch (e.target.nodeName) { //当前为图片或者链接时,右键清除选中状态. //当前为图片 case 'IMG': e.preventDefault(); - document.getSelection().empty(); + document.getSelection().empty(); return; //当前为链接 case 'A': e.preventDefault(); document.getSelection().empty(); return; - } + } } render() { console.log("article render...", this.state.preview); return ( -
-
- this.handleWheelScroll(e)} - onKeyUp={(e) => this.handleKeyUp(e)} - onKeyDown={(e) => this.handleKeyDown(e)}> -
- -
-
+
+
+ this.handleWheelScroll(e)} + onKeyUp={(e) => this.handleKeyUp(e)} + onKeyDown={(e) => this.handleKeyDown(e)}> +
+ +
+
); } } diff --git a/src/web/toManual/js/index.jsx b/src/web/toManual/js/index.jsx index fdfc969c5..aedf93afe 100755 --- a/src/web/toManual/js/index.jsx +++ b/src/web/toManual/js/index.jsx @@ -2,9 +2,11 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import React, { Component } from 'react'; +import React, { Component, useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; import ReactDOM from 'react-dom'; +import $ from 'jquery'; +import { useRef } from 'react'; import Scrollbar from './scrollbar.jsx'; import { type } from 'os'; @@ -17,83 +19,79 @@ class Item extends Component { title: '', logo: '', show: false, - desktopname:'', + desktopname: '', }; console.log('main item constructor...'); this.init(); } - init() - { + init() { var filePath; var appName = this.props.appName; - var myPromise = new Promise(function(resolve, reject){ + var myPromise = new Promise(function (resolve, reject) { global.qtObjects.manual.appToPath(appName, function (filepath) { filePath = filepath; //error: 目标文件不存在 - if (filePath == 'error') - { + if (filePath == 'error') { return; } resolve() }) }); - - myPromise.then(()=>{ + + myPromise.then(() => { global.readFile(filePath, data => { let [title, desktopname] = data .substr('# '.length, data.indexOf('\n')) .split('|'); - - global.qtObjects.manual.getAppIconPath(desktopname,(logopath) =>{ - //按约定会在图标主题放置dde图标,但为保险起见如果未获取到则取common中的 - if(logopath==''&&desktopname=="dde"){ - logopath=filePath.substr(0,filePath.lastIndexOf('/')+1)+'../common/dde.svg'; - } - this.setState({ logo:logopath}); - }); - global.qtObjects.manual.getLocalAppName(desktopname,(appname) =>{ - this.setState({ title:appname}); + global.qtObjects.manual.getAppIconPath(desktopname, (logopath) => { + //按约定会在图标主题放置dde图标,但为保险起见如果未获取到则取common中的 + if (logopath == '' && desktopname == "dde") { + logopath = filePath.substr(0, filePath.lastIndexOf('/') + 1) + '../common/dde.svg'; + } + // console.log("logopath:", logopath); + this.setState({ logo: logopath }); }); - - this.setState({desktopname, file:this.file, show: true}); + + global.qtObjects.manual.getLocalAppName(desktopname, (appname) => { + this.setState({ title: appname }); + }); + + this.setState({ desktopname, file: this.file, show: true }); }); }); - global.show=true; + global.show = true; //2021.3.4产品决定取消图标动态切换,使用default图标主题,暂时注释 - // global.qtObjects.manual.iconThemeChanged.connect( - // this.iconThemeChange.bind(this) - // ); - + // global.qtObjects.manual.iconThemeChanged.connect( + // this.iconThemeChange.bind(this) + // ); + } iconThemeChange(themeType) { - global.qtObjects.manual.getAppIconPath(this.state.desktopname,(logopath) =>{ - if( global.show===true) { - this.setState({ logo:logopath}); - } - }); + global.qtObjects.manual.getAppIconPath(this.state.desktopname, (logopath) => { + if (global.show === true) { + this.setState({ logo: logopath }); + } + }); } - + componentWillReceiveProps(nextProps) { - console.log("index item componentWillReceivePropss........"); + console.log("index item componentWillReceivePropss........"); this.init(); } - componentWillUnmount(){ - global.show=false; + componentWillUnmount() { + global.show = false; } render() { var contentSpan = null; - if (this.props.isOpened) - { + if (this.props.isOpened) { contentSpan = ({this.state.title}) - } - else - { + } else { contentSpan = ({this.state.title}) } @@ -103,14 +101,16 @@ class Item extends Component { draggable="false" tabIndex="1" className="item" - onClick={() => global.open(this.props.appName)} + onClick={() => { + global.open(this.props.appName) + }} onKeyPress={e => { if (e.key === 'Enter') { global.open(this.props.appName); } }} > - + { + this.setState({ title: _title }); + }); + } + + render() { + const backgroundPath = "./resource/banner/" + this.props.appName + "_bg.png"; + const iconPath = "./resource/banner/" + this.props.appName + ".png"; + + return ( +
{ + global.open(this.props.appName); + }} + onKeyPress={e => { + if (e.key === 'Enter') { + global.open(this.props.appName); + } + }} + > + +

{this.state.title}

+

{global.i18n['ClicktoView']} + +

+
+ ) + } +} + +// 带toolip的文本框 +const TitleWithTip = ({ text }) => { + const [isHovered, setIsHovered] = useState(false); + const [tooltipText, setTooltipText] = useState(text); + const [tooltipPosition, setTooltipPosition] = useState({ left: 0, top: 0 }); + const titleRef = useRef(null); + + useEffect(() => { + setTooltipText(text); + setTooltipPosition({ left: 0, top: 0 }); + }, [text]); + + useEffect(() => { + if (isHovered) { + setTooltipText(text); + } + }, [isHovered, text]); + + useEffect(() => { + if (!isHovered) { + setTooltipText(''); + } + }, [isHovered]); + + // 当鼠标移动时,更新提示框的位置为鼠标位置 + const handleMouseMove = (event) => { + const rect = titleRef.current.parentNode.getBoundingClientRect(); + const x = titleRef.current.parentNode.offsetWidth + event.pageX - titleRef.current.parentNode.offsetWidth; + const y = rect.y + titleRef.current.parentNode.offsetHeight; + // console.log("x:", x, " y:", y); + setTooltipPosition({ left: x + 10, top: y - 20 }); + }; + + return ( +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + onMouseMove={handleMouseMove} + style={{ userSelect: 'none' }} + > + {text} + {isHovered &&
+ {tooltipText} +
} +
+ ); +}; + +class VideoGuideItem extends Component { + constructor(props) { + super(props); + this.state = { + title: this.props.title, + imgpath: this.props.cover, + videourl: this.props.url, + }; + } + + render() { + return ( +
{ + global.qtObjects.manual.openVideo(this.props.url); + }} + onKeyPress={e => { + if (e.key === 'Enter') { + global.qtObjects.manual.openVideo(this.props.url); + } + }} + > + + + +
+ ) + } +} + export default class Index extends Component { constructor(props) { super(props); this.state = { appList: [], - openedAppList:[] + openedAppList: [], + videoList: [] }; - global.qtObjects.manual.getSystemManualList(appList =>{ - console.log("======>applist==+>",appList); + global.qtObjects.manual.getSystemManualList(appList => { + console.log("======>applist===>", appList); this.setState({ appList }); }); global.qtObjects.manual.getUsedAppList(openedAppList => - this.setState({openedAppList}) + this.setState({ openedAppList }) ); + + global.qtObjects.manual.getVideoGuideInfo(_videoList => { + console.log("======>videoList===>", _videoList); + this.setState({ videoList: _videoList }); + }); } - bIsBeOpen(app){ - if (this.state.openedAppList.indexOf(app) != -1) - { + bIsBeOpen(app) { + if (this.state.openedAppList.indexOf(app) != -1) { return true; } return false; @@ -152,23 +283,16 @@ export default class Index extends Component { shouldComponentUpdate(nextProps, nextState) { console.log("index shouldcomponentupdate"); - if (global.bIsReload) - { - global.qtObjects.manual.getSystemManualList(appList =>{ + if (global.bIsReload) { + global.qtObjects.manual.getSystemManualList(appList => { this.setState({ appList }) }); - + global.qtObjects.manual.getUsedAppList(openedAppList => - this.setState({openedAppList}) + this.setState({ openedAppList }) ); global.bIsReload = false; } - // else if (nextState.appList.toString() == this.state.appList.toString() - // && nextState.openedAppList.toString() == this.state.openedAppList.toString()) - // { - // console.log("index no update"); - // return false; - // } return true; } componentDidUpdate() { @@ -176,41 +300,81 @@ export default class Index extends Component { .querySelector('#index') .focus(); } + render() { console.log('index render...'); + + let videoSoft = JSON.parse(JSON.stringify(this.state.videoList)); let sysSoft = ['dde'].filter( appName => this.state.appList.indexOf(appName) != -1 ); + let appSoft = JSON.parse(JSON.stringify(this.state.appList))//使用数据副本 + let startSoft = []; var index = appSoft.indexOf("dde"); - if (index !== -1) - { - appSoft.splice(index, 1); + if (index !== -1) { + appSoft.splice(index, 1); + } + index = appSoft.indexOf("learn-basic-operations"); + if (index !== -1) { + startSoft.push(appSoft[index]); + appSoft.splice(index, 1); + } + index = appSoft.indexOf("common-application-libraries"); + if (index !== -1) { + startSoft.push(appSoft[index]); + appSoft.splice(index, 1); } return ( - -
-

{global.i18n['System']}

- {sysSoft.length > 0 && ( -
+
+ +
+ {startSoft.length == 2 && ( +
+

{global.i18n['QuickStart']}

+
- {sysSoft.map(appName => )} + +
-
- )} -

{global.i18n['Applications']}

-
-
- {appSoft.map(appName => )} - {/* {otherSoft.map(appName => )} - {Array.from(new Array(10), (val, index) => index).map(i => ( - - ))} */} +
-
-
-
+ )} + + {videoSoft.length > 0 && ( +
+

{global.i18n['VideoGuide']} + { + global.qtObjects.manual.openVideo(''); + }}> + {global.i18n['ViewAll']} + +

+ +
+
+ {videoSoft.map((item, index) => ( + + ))} +
+
+ )} + +

{global.i18n['System']}

+ {sysSoft.length > 0 && ( +
+ {sysSoft.map(appName => )} +
+ )} + +

{global.i18n['Applications']}

+
+ {appSoft.map(appName => )} +
+
+ +
); } } diff --git a/src/web/toManual/js/main.jsx b/src/web/toManual/js/main.jsx index 1b4484dcc..ba3548f58 100755 --- a/src/web/toManual/js/main.jsx +++ b/src/web/toManual/js/main.jsx @@ -14,55 +14,40 @@ export default class Main extends Component { super(props); this.state = { init: false, - bTest:true + bTest: true }; - let { file, hash ,key} = this.props.match.params; + let { file, hash, key } = this.props.match.params; console.log("main constructor..."); this.init(decodeURIComponent(file), hash ? decodeURIComponent(hash) : null, key); - var showFloatTimer=null; + var showFloatTimer = null; this.setHash = this.setHash.bind(this); this.setScroll = this.setScroll.bind(this); - this.onSupportClick = this.onSupportClick.bind(this); } - init(file, hash,key='') { - if (key !== '%') - { + init(file, hash, key = '') { + if (key !== '%') { key = decodeURIComponent(key) } - console.log("main init==>file:",file," hash:",hash," key:",key); - + console.log("main init==>file:", file, " hash:", hash, " key:", key); global.hash = hash; var filePath = file; - // if (filePath.indexOf('/') == -1) { - // if (filePath == "dde") - // { - // filePath = `${global.path}/system/${file}/${global.lang}/index.md`; - // } - // else{ - // filePath = `${global.path}/application/${file}/${global.lang}/index.md`; - // } - - // } - - var myPromise = new Promise(function(resolve, reject){ - if (filePath.indexOf('/') == -1) - { + + var myPromise = new Promise(function (resolve, reject) { + if (filePath.indexOf('/') == -1) { global.qtObjects.manual.appToPath(file, function (filepath) { filePath = filepath; resolve() }) } - else - { + else { resolve() } }); - myPromise.then(()=>{ + myPromise.then(() => { global.readFile(filePath, data => { - console.log("main init===>readfile finish...",filePath); - let { html, hlist } = m2h(filePath, data,key); + console.log("main init===>readfile finish...", filePath); + let { html, hlist } = m2h(filePath, data, key); this.setState({ file, html, @@ -85,17 +70,6 @@ export default class Main extends Component { this.setState({ hash }); } - // setScrollTitle(hash){ - // console.log("main setScrollTitle: " + hash); - // setTimeout(() => { - // global.hash = hash; - // global.oldHash = hash; - // global.isMouseClickNav = true; - // global.isMouseScrollArticle = false; - // this.setState({ hash }); - // },800); - // } - setScroll(hash) { console.log("main setScroll:" + hash); global.hash = hash; @@ -103,55 +77,48 @@ export default class Main extends Component { } //处理Nav类的Over Out Move事件,自定义Title框 - handleNavOver(e){ - var value = e.currentTarget.innerHTML; + handleNavOver(e) { + var value = e.currentTarget.innerHTML; clearTimeout(this.showFloatTimer); - this.showFloatTimer=setTimeout(function(){ - $('.tooltip-wp').attr('data-title', value); //动态设置data-title属性 - $('.tooltip-wp').fadeIn(200);//浮动框淡出 - },300); + this.showFloatTimer = setTimeout(function () { + $('.tooltip-wp').attr('data-title', value); //动态设置data-title属性 + $('.tooltip-wp').fadeIn(200);//浮动框淡出 + }, 300); } - handleNavOut(e){ + handleNavOut(e) { clearTimeout(this.showFloatTimer); $('.tooltip-wp').hide(); } - handleNavMove(e){ - var xPage = e.pageX+10; + handleNavMove(e) { + var xPage = e.pageX + 10; var yPage = e.pageY; - if((yPage + 40) > document.body.scrollHeight){ - yPage = document.body.scrollHeight-40; + console.log("...", document.body.scrollHeight); + if ((yPage + 40) > document.body.scrollHeight) { + yPage = document.body.scrollHeight - 40; } - setTimeout(function(){ - $('.tooltip-wp').css({ - 'top' : yPage + 'px', - 'left': xPage+ 'px' - }); - },150); - } - - onSupportClick(){ - global.qtObjects.manual.supportClick(); + setTimeout(function () { + $('.tooltip-wp').css({ + 'top': yPage + 'px', + 'left': xPage + 'px' + }); + }, 150); } componentWillReceiveProps(nextProps) { - let { file, hash,key } = nextProps.match.params; + let { file, hash, key } = nextProps.match.params; - if (global.bIsReload) - { + if (global.bIsReload) { var parentText; var hashText = ''; - for(var i = 0; i < this.state.hlist.length; i++) - { + for (var i = 0; i < this.state.hlist.length; i++) { var h = this.state.hlist[i]; - if (h.type == 'h2') - { + if (h.type == 'h2') { parentText = h.text; } - if (h.id == this.state.hash) - { + if (h.id == this.state.hash) { hashText = h.text; break; } @@ -166,69 +133,62 @@ export default class Main extends Component { // else{ // filePath = `${global.path}/application/${this.state.file}/${global.lang}/index.md`; // } - var myPromise = new Promise(function(resolve, reject){ + var myPromise = new Promise(function (resolve, reject) { global.qtObjects.manual.appToPath(file, function (filepath) { filePath = filepath; resolve() }) }); - myPromise.then(()=>{ + myPromise.then(() => { global.readFile(filePath, data => { - console.log("main init===>readfile finish...",filePath); - let { html, hlist } = m2h(filePath, data,key); + console.log("main init===>readfile finish...", filePath); + let { html, hlist } = m2h(filePath, data, key); var newParentHash = 'h1'; var newChildHash; var curHash; - - for(var i = 0; i < hlist.length; i++) - { + + for (var i = 0; i < hlist.length; i++) { var h = hlist[i]; - if (h.text == parentText) - { + if (h.text == parentText) { newParentHash = h.id; } - else if (h.text == hashText) - { + else if (h.text == hashText) { newChildHash = h.id; break; } } - - if (newChildHash) - { + + if (newChildHash) { curHash = newChildHash; } - else - { + else { curHash = newParentHash; } - console.log('================>',curHash); - + console.log('================>', curHash); + this.init(decodeURIComponent(file), curHash, key); global.bIsReload = false; }); }) - } - else{ - console.log("main componentWillReceivePropss: "+file+" "+hash+" this.file:"+ this.state.file +" this.hash"+this.state.hash+ " key:",key); + } else { + console.log("main componentWillReceivePropss: " + file + " " + hash + " this.file:" + this.state.file + " this.hash" + this.state.hash + " key:", key); //仅当页面文件发生改变时(文件改变或hash值发生改变),才刷新页面. - if (decodeURIComponent(file) != this.state.file || ((file == this.state.file) && (hash != this.state.hash))) - { - this.init(decodeURIComponent(file), hash ? decodeURIComponent(hash) : null,key); + if (decodeURIComponent(file) != this.state.file || ((file == this.state.file) && (hash != this.state.hash))) { + this.init(decodeURIComponent(file), hash ? decodeURIComponent(hash) : null, key); } } } - shouldComponentUpdate(nextProps,nextState){ + shouldComponentUpdate(nextProps, nextState) { console.log("main shouldComponentUpdate===="); return true; } - componentWillUpdate(){ + componentWillUpdate() { console.log("main componentWillUpdate.."); } - componentWillUnmount(){ + componentWillUnmount() { global.hash = ''; global.isMouseClickNav = false; global.isMouseScrollArticle = false; @@ -236,14 +196,8 @@ export default class Main extends Component { } render() { - console.log("main render....hash:",this.state.hash); - console.log("main render....hList:",this.state.hlist); - let support = null; - if (global.isShowHelperSupport) { - support =
- }else{ - support =
- } + console.log("main render....hash:", this.state.hash); + console.log("main render....hList:", this.state.hlist); return ( this.state.init && ( @@ -252,9 +206,9 @@ export default class Main extends Component { hlist={this.state.hlist} hash={this.state.hash} setHash={this.setHash} - onNavOver={(e)=>this.handleNavOver(e)} - onNavOut={(e)=>this.handleNavOut(e)} - onNavMove={(e)=>this.handleNavMove(e)} + onNavOver={(e) => this.handleNavOver(e)} + onNavOut={(e) => this.handleNavOut(e)} + onNavMove={(e) => this.handleNavMove(e)} />
- {support}
) diff --git a/src/web/toManual/js/nav.jsx b/src/web/toManual/js/nav.jsx index dbb7f43f8..e41da40da 100755 --- a/src/web/toManual/js/nav.jsx +++ b/src/web/toManual/js/nav.jsx @@ -61,7 +61,7 @@ class Nav extends Component { click(e) { let cid = e.target.getAttribute('cid'); if (cid) { - console.log('搜索结果', cid); + console.log('nav 搜索结果', cid); global.hash = cid; global.isMouseClickNav = true; global.isMouseScrollArticle = false; diff --git a/src/web/toManual/js/search.jsx b/src/web/toManual/js/search.jsx index 984ff462a..213230ff3 100755 --- a/src/web/toManual/js/search.jsx +++ b/src/web/toManual/js/search.jsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import React, { Component } from 'react'; +import React, { Component, useEffect, useRef } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import Scrollbar from './scrollbar.jsx'; @@ -17,27 +17,32 @@ class Items extends Component { show: false }; let path = props.file.slice(0, props.file.lastIndexOf('/') + 1); - console.log("========path======>",path); + console.log("========path======>", path); global.readFile(props.file, data => { let [title, desktopname] = data .substr('# '.length, data.indexOf('\n')) .split('|'); - // logo = `${path}${logo}`; - // this.setState({ title, logo, show: true }); - global.qtObjects.manual.getAppIconPath(desktopname,(logopath) =>{ - //按约定会在图标主题放置dde图标,但为保险起见如果未获取到则取common中的 - //global.qtObjects.manual.LogPrint("sbkebcmj"); - if(logopath==''&&desktopname=="dde"){ - logopath=path+'../common/dde.svg'; - //global.qtObjects.manual.LogPrint("logopath:"+ logopath); - } - this.setState({ logo:logopath}); - }); - - global.qtObjects.manual.getLocalAppName(desktopname,(appname) =>{ - this.setState({ title:appname}); - }); - this.setState({show: true }); + + global.qtObjects.manual.getAppIconPath(desktopname, (logopath) => { + //按约定会在图标主题放置dde图标,但为保险起见如果未获取到则取common中的 + //global.qtObjects.manual.LogPrint("sbkebcmj"); + if (logopath == '' && desktopname == "dde") { + logopath = path + '../common/dde.svg'; + } + if (logopath == '' && desktopname == "learn-basic-operations") { + logopath = path + '../common/learn_basic_operations.svg'; + } + if (logopath == '' && desktopname == "common-application-libraries") { + logopath = path + '../common/common_application_libraries.svg'; + } + // console.log("logopath: ", logopath); + this.setState({ logo: logopath }); + }); + + global.qtObjects.manual.getLocalAppName(desktopname, (appname) => { + this.setState({ title: appname }); + }); + this.setState({ show: true }); }); } @@ -50,17 +55,15 @@ class Items extends Component { let resultList = []; //将关键字转义 - let keyTemp = this.props.keyword; - if (this.props.keyword !== '%') - { - keyTemp = decodeURIComponent(this.props.keyword) + if (this.props.keyword !== '%') { + keyTemp = this.props.keyword; } // let keyTemp = decodeURIComponent(this.props.keyword) let re = new RegExp(this.escapeRegExp(keyTemp), 'gi'); - let cTitle =( + let cTitle = (
); - if (resultList.length < 5) - { + if (resultList.length < 5) { resultList.push(c); } } var sresultnum; - if(this.props.idList.length >1) - sresultnum=this.props.idList.length+global.i18n['ResultNumSuffixs']; - else - sresultnum=this.props.idList.length+global.i18n['ResultNumSuffix']; + if (this.props.idList.length > 1) + sresultnum = this.props.idList.length + global.i18n['ResultNumSuffixs']; + else + sresultnum = this.props.idList.length + global.i18n['ResultNumSuffix']; + + return ( this.state.show && (
-
global.open(this.props.file,'',this.props.keyword)}> +
global.open(this.props.file, '', this.props.keyword)}> {cTitle} {sresultnum} @@ -122,27 +125,113 @@ class Items extends Component { ); } } + +class VideoItem extends Component { + constructor(props) { + super(props); + this.state = { + logo: './resource/videos/video.svg', + videoList: props.titleList, + urlList: props.contentList, + show: false + }; + } + + render() { + let resultList = []; + for (let i = 0; i < this.state.videoList.length; i++) { + let c = ( +
+ + { + global.qtObjects.manual.openVideo(this.state.urlList[i]); + }}> + {this.state.videoList[i]} + +
+ ); + + if (resultList.length < 8) { + resultList.push(c); + } + } + + return ( +
+ {resultList} +
+ ) + } +} + function Mismatch(props) { return (
- {/* {global.i18n['NoResult'].replace('%1', keyword)} */} {global.i18n['NoResult']}
); } + +function VideoItems(props) { + const videoItemsRef = useRef(null); + let logo = './resource/video.svg'; + let videoList = props.titleList; + let urlList = props.contentList; + let show = false; + + let resultList = []; + for (let i = 0; i < videoList.length; i++) { + let c = ( +
+ + { + global.qtObjects.manual.openVideo(urlList[i]); + }}> + {videoList[i]} + +
+ ); + + if (resultList.length < 8) { + resultList.push(c); + } + } + + useEffect(() => { + const adjustOtherElements = () => { + const componentHeight = videoItemsRef.current.offsetHeight + 20; + setTimeout(function () { + document.getElementsByClassName("items")[0].style.marginTop = `${componentHeight}px`; + }, 50); + }; + + adjustOtherElements(); // 调整其他元素的位置 + }, []); + + function handleHover() { + console.log("hover....current:", videoItemsRef.current, " ", videoItemsRef.current.offsetHeight); + } + + return ( +
+ {resultList} +
+ ); +} + export default class SearchPage extends Component { constructor(props, context) { super(props, context); - // console.log('search constructor:',this.context); + console.log('search constructor:', this.context); } - componentWillReceiveProps(nextProps){ - // console.log("search componentWillReceiveProps..",this.context.searchResult); + componentWillReceiveProps(nextProps) { + console.log("search componentWillReceiveProps..", this.context.searchResult); console.log("search componentWillReceiveProps.."); } @@ -162,7 +251,15 @@ export default class SearchPage extends Component { c = ; } else { c = this.context.searchResult.map(result => ( - + + : div:last-child { +.scrollbar>div:last-child { width: 6px !important; - border-radius:3px !important; + border-radius: 3px !important; + div { background-color: var(--scrollbar-div-background-color) !important; cursor: default !important; + &:hover { - background-color: var(--scrollbar-div-hover-background-color) !important; + background-color: var(--scrollbar-div-hover-background-color) !important; } } + &:hover { width: 8px !important; - border-radius:4px !important; + border-radius: 4px !important; } } + body[style*='user-select: none'] { - .scrollbar > div:last-child { + .scrollbar>div:last-child { width: 8px !important; - border-radius:4px !important; + border-radius: 4px !important; + div { background-color: var(--scrollbar-div-select-background-color) !important; } @@ -50,7 +55,7 @@ body[style*='user-select: none'] { div { outline: none; - + //if screen is over 4K and webkit-min >= 2 ,the follow setting will create some warning... //so remove them now... @@ -78,5 +83,103 @@ div { // @media screen and (-webkit-min-device-pixel-ratio: 3) { // border-right: 1px solid var(--body-background-color); // } -} + .support-div { + width: 48px; + height: 48px; + border-radius: 48px; + background-color: var(--nav-hash-word-color); + display: inline-block; + position: fixed; + left: var(--support-position); + bottom: 25px; + + &:hover { + cursor: pointer; + background-color: var(--nav-hash-hover-color); + } + &:active { + // background-color: blue; + background-color: var(--nav-hash-press-color); + } + + .support { + position: absolute; + width: 20px; + height: 21px; + top: 14px; + left: 14px; + } + + .tooltip-wrapper { + position: absolute; + visibility: hidden; + white-space: nowrap; + right: -15px; + bottom: -23px; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + padding: 2px 5px; + border-radius: 8px; + border: 1px solid var(--tips-border-color); + font-family: var(--nav-world-font-family); + box-shadow: 0px 3px 20px var(--tips-shadow-color); + } + + .tooltip-wrapper.show { + visibility: visible; + } + } + + .store-div { + width: 48px; + height: 48px; + border-radius: 48px; + background-color: var(--nav-hash-word-color); + display: inline-block; + position: fixed; + left: var(--support-position); + bottom: 83px; + z-index: 10; + visibility: var(--app-store-visibility); + // box-shadow: 0px 4px 6px var(--active-shadow-color); + + &:hover { + cursor: pointer; + background-color: var(--nav-hash-hover-color); + } + &:active { + // background-color: blue; + background-color: var(--nav-hash-press-color); + } + + .store { + position: absolute; + width: 20px; + height: 21px; + top: 14px; + left: 14px; + } + + .tooltip-wrapper { + position: absolute; + visibility: hidden; + white-space: nowrap; + right: -15px; + bottom: -23px; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + padding: 2px 5px; + border-radius: 8px; + border: 1px solid var(--tips-border-color); + font-family: var(--nav-world-font-family); + box-shadow: 0px 3px 20px var(--tips-shadow-color); + } + + .tooltip-wrapper.show { + visibility: visible; + } + } +} \ No newline at end of file diff --git a/src/web/toManual/sass/index.scss b/src/web/toManual/sass/index.scss index da9cdac93..68dbe90ae 100644 --- a/src/web/toManual/sass/index.scss +++ b/src/web/toManual/sass/index.scss @@ -8,56 +8,82 @@ user-select: none; display: flex; flex-flow: column; - margin: -19px 117px -19px 117px; + margin-top: -2px; + margin-bottom: -19px; + margin-left: auto; + margin-right: auto; + width: calc(100% - 117px - 117px); + max-width: 1630px; + &:after { content: ''; display: block; width: 100%; height: 100px; } + h2 { + height: 60px; // font-family: SourceHanSansSC-Normal; font-family: var(--nav-world-font-family); - font-weight: normal; - font-size: 3.1rem; + font-weight: bold; + font-size: 1.6rem; line-height: 4.5rem; - margin: 0.5em 0 0; - border-bottom: 1px solid var(--index-h2-color); - padding-bottom: 12px; + margin: 0 0 0 0; + border-top: 1px solid var(--index-h2-color); + color: var(--nav-h2-word-color); + + #righttext { + color: var(--nav-hash-word-color); + float: right; + text-align: right; + bottom: 0; + font-family: var(--nav-world-font-family); + font-weight: 500; + font-size: 1.1rem; + + &:hover { + color: var(--nav-hash-hover-color); + cursor: pointer; + } + } } - - .items { + + .appitems { display: flex; - position:relative; - left:-50px; - width:calc(100% + 100px); - right:0px; + position: relative; + left: -10px; + width: calc(100% + 50px); flex-flow: row; flex-wrap: wrap; justify-content: flex-start; + margin: 0; + // background-color: rgba(0, 255, 0, 0.1); + .empty { width: 160px; padding: 0 10px; } + .item { background-color: var(--index-item-background-color); border-radius: 18px; - padding:0px; - // width: 160px; - // height: 160px; + padding: 0px; width: var(--index-item-size); height: var(--index-item-size); - margin: 30px 0px 0px 50px; + margin: 5px 40px 30px 10px; display: inline-block; text-align: center; vertical-align: bottom; cursor: pointer; + img { width: 96px; height: 96px; margin-top: 18px; margin-bottom: 3px; } + .content { //margin-left: 15px; //保持span居中,当设置display:-webkit-box后,默认居左,故设置其外边距 width: var(--index-span-width); @@ -66,15 +92,15 @@ text-overflow: ellipsis; margin: auto; //display:-webkit-box; //设置其排列两行 - -webkit-box-orient:vertical; - -webkit-line-clamp:2; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; font-family: var(--nav-world-font-family); font-size: var(--span-font-size); line-height: var(--span-line-height); // font-weight: bold; color: var(--index-item-span-word-color); } - //&:focus, + &:hover { background-clip: content-box; border-radius: 18px; @@ -82,16 +108,182 @@ background-color: var(--index-item-hover-color); } - .tag{ + .tag { display: inline-block; height: 8px; width: 8px; margin-right: 4px; - margin-bottom: var(--span-maring-bottom);; - box-shadow: 0px 2px 8px 0px var(--nav-hash-hover-color); + margin-bottom: var(--span-maring-bottom); + box-shadow: 0px 2px 8px 0px var(--nav-hash-hover-color); border-radius: 8px; background-color: var(--nav-hash-word-color); } } } + + .items { + display: flex; + position: relative; + left: -10px; + width: calc(100% + 20px); + // right:0px; + // flex-flow: row; + flex-wrap: wrap; + // justify-content: flex-start; + margin: 0 0 30px 0; + + .tooltip-wp { + position: fixed; + width: 200px; + // height: 40px; + z-index: 100; + display: none; + } + + .tooltip-wp:after { + content: attr(data-title); + position: fixed; + left: 0; + top: 0; + max-width: 500px; + padding: 2px 5px; + word-break: normal; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + font-family: var(--nav-world-font-family); + border-radius: 8px; + border: 1px solid var(--nav-hove-border-color); + } + + .quickitem { + position: relative; + border-radius: 18px; + width: calc(50% - 20px); + height: 160px; + margin: 5px 10px 0px 10px; + text-align: center; + vertical-align: bottom; + // background-color: cadetblue; + + #icon { + width: 68px; + height: 68px; + margin: 10px 0px 0px 0px; + } + + #title { + height: 50px; + color: #FFFFFF; + display: flex; + justify-content: center; + align-items: center; + font-family: var(--nav-world-font-family); + font-weight: bold; + font-size: 20px; + vertical-align: center; + // font-size: 2.5vw; + text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2); + padding: 0; + margin: 0; + } + + #click { + color: #FFFFFF; + font-family: var(--nav-world-font-family); + font-weight: normal; + font-size: 14px; + // font-size: 1.5vw; + text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2); + padding: 0; + margin: 0; + } + + &:hover::before { + visibility: visible; + cursor: pointer; + } + } + + .quickitem::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: 18px; + background-color: var(--index-item-hover-color); + visibility: hidden; + } + + .videoitem { + position: relative; + border-radius: 18px; + width: 182px; + height: 143px; + padding: 5px 10px 25px 10px; + text-align: center; + vertical-align: bottom; + // background-color: bisque; + + .image { + width: 182px; + height: 115px; + border-radius: 8px; + box-shadow: 1px 1px 4px rgba(41, 30, 30, 0.1); + } + + .title-div { + position: static; + width: 162; + white-space: nowrap; + overflow: hidden; + word-break: normal; + overflow: hidden; + text-overflow: ellipsis; + margin: 8px 0 0 10px; + + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + font-family: var(--nav-world-font-family); + font-size: var(--span-font-size); + font-weight: 500; + color: var(--index-item-span-word-color); + + .title-wrapper { + position: fixed; + visibility: hidden; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + z-index: 10; + padding: 2px 5px; + border-radius: 18px; + border: 1px solid var(--nav-hove-border-color); + font-family: var(--nav-world-font-family); + } + + .title-wrapper.show { + visibility: visible; + } + } + + &:hover::before { + visibility: visible; + cursor: pointer; + } + } + + .videoitem::before { + content: ""; + position: absolute; + top: 5px; + right: 10px; + left: 10px; + height: 115px; + border-radius: 8px; + background-color: var(--index-item-hover-color); + visibility: hidden; + } + } } diff --git a/src/web/toManual/sass/main.scss b/src/web/toManual/sass/main.scss index 993f5e4d7..de53c708d 100644 --- a/src/web/toManual/sass/main.scss +++ b/src/web/toManual/sass/main.scss @@ -6,47 +6,30 @@ //去除最外层滚动条 body { - overflow: hidden; + overflow: hidden; } #main { - .tooltip-wp{ - position: absolute; - width: 200px; - // height: 40px; - z-index: 100; - display: none; - } - .tooltip-wp:after{ - content: attr(data-title); - position: absolute; - left: 0; - top: 0; - max-width: 500px; - padding: 2px 5px; - word-break: normal; - background-color: var(--tips-background-color); - color: var(--nav-hove-word-color); - font-family: var(--nav-world-font-family); - border-radius: 8px; - border: 1px solid var(--nav-hove-border-color); - } - .support-div{ - width: 48px; - height: 48px; - border-radius: 48px; - background-color: var(--nav-hash-word-color); - display: inline-block; - position:absolute; - right: 20px; - bottom: 20px; - } - - .support{ - width: 20px; - height: 21px; - margin-top: 14px; - margin-left: 14px; - } + .tooltip-wp { + position: absolute; + width: 200px; + // height: 40px; + z-index: 100; + display: none; + } -} + .tooltip-wp:after { + content: attr(data-title); + position: absolute; + left: 0; + top: 0; + max-width: 500px; + padding: 2px 5px; + word-break: normal; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + font-family: var(--nav-world-font-family); + border-radius: 8px; + border: 1px solid var(--nav-hove-border-color); + } +} \ No newline at end of file diff --git a/src/web/toManual/sass/nav.scss b/src/web/toManual/sass/nav.scss index f6a7df07c..b6176be20 100644 --- a/src/web/toManual/sass/nav.scss +++ b/src/web/toManual/sass/nav.scss @@ -64,4 +64,4 @@ background-color: var(--nav-hash-hover-color); } } -} \ No newline at end of file +} diff --git a/src/web/toManual/sass/search.scss b/src/web/toManual/sass/search.scss index 47185453a..f8fd2298f 100644 --- a/src/web/toManual/sass/search.scss +++ b/src/web/toManual/sass/search.scss @@ -5,11 +5,13 @@ #search { width: 80%; //margin:auto auto auto 95px; - margin:auto; + margin: auto; user-select: text !important; + div { width: 100%; } + #mismatch { width: 80%; height: 100%; @@ -19,6 +21,7 @@ -webkit-box-pack: center; -webkit-box-align: center; text-align: center; + #NoResult { // font-family: SourceHanSansSC-Normal; font-family: var(--nav-world-font-family); @@ -30,6 +33,7 @@ color: var(--search-noresult-word-color); margin-bottom: 11px; } + #WikiSearch { // font-family: SourceHanSansSC-Normal; font-family: var(--nav-world-font-family); @@ -37,50 +41,57 @@ color: var(--search-WikiSearch-color); margin-bottom: 26px; } + .button { // font-family: SourceHanSansSC-Medium; font-family: var(--nav-world-font-family); font-weight: 500; font-size: 1.1rem; padding: 6px 42px 8px; - background:linear-gradient(var(--search-button-background-color-start),var(--search-button-background-color-end)); + background: linear-gradient(var(--search-button-background-color-start), var(--search-button-background-color-end)); color: var(--search-button-word-color); width: 80px; - box-shadow: 0 2px 4px 0 rgba(0,0,0,0.05); + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); border: solid 1px rgba(0, 0, 0, 0.03); - border-radius:8px; + border-radius: 8px; text-align: center; cursor: pointer; } - .button:hover{ + + .button:hover { opacity: 0.9; color: var(--search-button-hover-word-color); - background:linear-gradient(var(--search-button-hover-color-start),var(--search-button-hover-color-end)); + background: linear-gradient(var(--search-button-hover-color-start), var(--search-button-hover-color-end)); } - .button:hover:after{ + + .button:hover:after { opacity: 1; color: var(--search-button-word-color); - background:linear-gradient(var(--search-button-background-color-start),var(--search-button-background-color-end)); + background: linear-gradient(var(--search-button-background-color-start), var(--search-button-background-color-end)); } } + .items { padding: 0px 20px 0px 40px; color: var(--search-items-word-color); // font-family: SourceHanSansSC-Bold; font-family: var(--nav-world-font-family); margin: 20px 0px 0px -20px; + .itemsTitle { img { height: 100%; vertical-align: middle; margin: auto 10px auto 5px; } + .resulttitle { color: var(--search-noresult-word-color); vertical-align: middle; font-size: 1.3rem; font-weight: bold; } + .resultnum { // font-family: SourceHanSansSC-Normal; font-family: var(--nav-world-font-family); @@ -92,6 +103,7 @@ margin-right: 0px; vertical-align: text-bottom; } + padding: 7px 10px 0px 0px; margin: 10px auto auto -20px; cursor: pointer; @@ -101,45 +113,62 @@ -webkit-line-clamp: 1; -webkit-box-orient: vertical; } + .item { img { + //svg图片内嵌同行 &[src$='svg'] { margin-top: -2px; height: 18px; vertical-align: middle; } - //png图片 + &[src$='png'] { - $i: 0; - @while $i<1 { - $i: $i+0.25; - @media screen and (-webkit-min-device-pixel-ratio: 1+$i) { - zoom: 0.5/$i; - } - } - // margin-top: 26px; //搜索界面图片对其 - max-width: 99%; - cursor: pointer; + margin-top: -2px; + height: 18px; + vertical-align: middle; } + + //png图片 + // &[src$='png'] { + // $i: 0; + + // @while $i<1 { + // $i: $i+0.25; + + // @media screen and (-webkit-min-device-pixel-ratio: 1+$i) { + // zoom: 0.5/$i; + // } + // } + + // // margin-top: 26px; //搜索界面图片对其 + // max-width: 99%; + // cursor: pointer; + // } + //jpg图片 &[src$='jpg'] { $i: 0; + @while $i<1 { $i: $i+0.25; + @media screen and (-webkit-min-device-pixel-ratio: 1+$i) { zoom: 0.5/$i; } } + // margin-top: 26px; max-width: 99%; cursor: pointer; border-radius: 4px; // border: 1px solid rgba(0, 0, 0, 0.18); box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.2), - 0 0 0 1px rgba(0, 0, 0, 0.1); + 0 0 0 1px rgba(0, 0, 0, 0.1); } } + .itemTitle { width: 99%; margin: 0px 0px 0px 15px; @@ -149,6 +178,7 @@ font-weight: bold; color: var(--search-itemTitle-word-color); } + .context { width: 98%; margin: 7px 0px 10px 15px; @@ -160,6 +190,7 @@ -webkit-line-clamp: 3; -webkit-box-orient: vertical; } + cursor: pointer; padding: 7px 10px 0px 0px; margin: 10px auto auto -20px; @@ -171,8 +202,36 @@ -webkit-line-clamp: 3; -webkit-box-orient: vertical; } + .highlight { color: #2bba57; } } -} + + .videoItems { + padding: 14px 20px 0px 0px; + position: absolute; + top: 0; + + #item { + height: 34px; + display: flex; + align-items: center; + + span { + margin: 0 0 0 10px; + vertical-align: center; + text-decoration: underline; + color: var(--nav-hash-word-color); + font-family: var(--nav-world-font-family); + font-weight: 500; + font-size: 1.1rem; + + &:hover { + color: var(--nav-hash-hover-color); + cursor: pointer; + } + } + } + } +} \ No newline at end of file diff --git a/src/web/toSearchMd/app/main.js b/src/web/toSearchMd/app/main.js index 0e1e7ab9b..d2a9f6fe7 100644 --- a/src/web/toSearchMd/app/main.js +++ b/src/web/toSearchMd/app/main.js @@ -25,7 +25,7 @@ init(); global.parseMdList=(listMdPath)=>{ - console.log("=====>",listMdPath); + console.log("global.parseMdList=====>",listMdPath); var mdList = listMdPath.split(','); @@ -60,8 +60,7 @@ function delHtmlTagAndNewLine(str) { function mainTmp(pathList){ console.log("======>", pathList); - if (pathList.length > 0) - { + if (pathList.length > 0) { pathList.forEach(function(pathObj){ global.readFile(pathObj, data => { let count = 0; diff --git a/src/web/toSearchMd/common/index.html b/src/web/toSearchMd/common/index.html index dd9a17f26..53322a5d6 100644 --- a/src/web/toSearchMd/common/index.html +++ b/src/web/toSearchMd/common/index.html @@ -12,4 +12,4 @@ - \ No newline at end of file + diff --git a/src/web/toSearchMd/webpack.config.js b/src/web/toSearchMd/webpack.config.js index a366396d2..620d7fbdd 100644 --- a/src/web/toSearchMd/webpack.config.js +++ b/src/web/toSearchMd/webpack.config.js @@ -25,4 +25,4 @@ module.exports = { node: { fs: 'empty' }, -} \ No newline at end of file +} diff --git a/src/web_dist/toManual/index.css b/src/web_dist/toManual/index.css index 34bd37b0a..ca4451e76 100644 --- a/src/web_dist/toManual/index.css +++ b/src/web_dist/toManual/index.css @@ -1,7 +1,3 @@ -/*SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. - -SPDX-License-Identifier: GPL-3.0-or-later*/ - body { background-color: var(--body-background-color); width: 100%; @@ -11,7 +7,6 @@ body { #app { width: 100%; - height: calc(100%); color: var(--app-word-color); } #app a { text-decoration: none; @@ -37,6 +32,80 @@ body[style*='user-select: none'] .scrollbar > div:last-child { div { outline: none; } + div .support-div { + width: 48px; + height: 48px; + border-radius: 48px; + background-color: var(--nav-hash-word-color); + display: inline-block; + position: fixed; + left: var(--support-position); + bottom: 25px; } + div .support-div:hover { + cursor: pointer; + background-color: var(--nav-hash-hover-color); } + div .support-div:active { + background-color: var(--nav-hash-press-color); } + div .support-div .support { + position: absolute; + width: 20px; + height: 21px; + top: 14px; + left: 14px; } + div .support-div .tooltip-wrapper { + position: absolute; + visibility: hidden; + white-space: nowrap; + right: -15px; + bottom: -23px; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + padding: 2px 5px; + border-radius: 8px; + border: 1px solid var(--tips-border-color); + font-family: var(--nav-world-font-family); + box-shadow: 0px 3px 20px var(--tips-shadow-color); } + div .support-div .tooltip-wrapper.show { + visibility: visible; } + div .store-div { + width: 48px; + height: 48px; + border-radius: 48px; + background-color: var(--nav-hash-word-color); + display: inline-block; + position: fixed; + left: var(--support-position); + bottom: 83px; + z-index: 10; + visibility: var(--app-store-visibility); } + div .store-div:hover { + cursor: pointer; + background-color: var(--nav-hash-hover-color); } + div .store-div:active { + background-color: var(--nav-hash-press-color); } + div .store-div .store { + position: absolute; + width: 20px; + height: 21px; + top: 14px; + left: 14px; } + div .store-div .tooltip-wrapper { + position: absolute; + visibility: hidden; + white-space: nowrap; + right: -15px; + bottom: -23px; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + padding: 2px 5px; + border-radius: 8px; + border: 1px solid var(--tips-border-color); + font-family: var(--nav-world-font-family); + box-shadow: 0px 3px 20px var(--tips-shadow-color); } + div .store-div .tooltip-wrapper.show { + visibility: visible; } @charset "UTF-8"; .Triangle, #article .t_center_down::after, #article .t_center_up::after, #article .t_right_down::after, #article .t_right_up::after, #article .t_left_down::after, #article .t_left_up::after { @@ -250,49 +319,66 @@ div { user-select: none; display: flex; flex-flow: column; - margin: -19px 117px -19px 117px; } + margin-top: -2px; + margin-bottom: -19px; + margin-left: auto; + margin-right: auto; + width: calc(100% - 117px - 117px); + max-width: 1630px; } #index:after { content: ''; display: block; width: 100%; height: 100px; } #index h2 { + height: 60px; font-family: var(--nav-world-font-family); - font-weight: normal; - font-size: 3.1rem; + font-weight: bold; + font-size: 1.6rem; line-height: 4.5rem; - margin: 0.5em 0 0; - border-bottom: 1px solid var(--index-h2-color); - padding-bottom: 12px; } - #index .items { + margin: 0 0 0 0; + border-top: 1px solid var(--index-h2-color); + color: var(--nav-h2-word-color); } + #index h2 #righttext { + color: var(--nav-hash-word-color); + float: right; + text-align: right; + bottom: 0; + font-family: var(--nav-world-font-family); + font-weight: 500; + font-size: 1.1rem; } + #index h2 #righttext:hover { + color: var(--nav-hash-hover-color); + cursor: pointer; } + #index .appitems { display: flex; position: relative; - left: -50px; - width: calc(100% + 100px); - right: 0px; + left: -10px; + width: calc(100% + 50px); flex-flow: row; flex-wrap: wrap; - justify-content: flex-start; } - #index .items .empty { + justify-content: flex-start; + margin: 0; } + #index .appitems .empty { width: 160px; padding: 0 10px; } - #index .items .item { + #index .appitems .item { background-color: var(--index-item-background-color); border-radius: 18px; padding: 0px; width: var(--index-item-size); height: var(--index-item-size); - margin: 30px 0px 0px 50px; + margin: 5px 40px 30px 10px; display: inline-block; text-align: center; vertical-align: bottom; cursor: pointer; } - #index .items .item img { + #index .appitems .item img { width: 96px; height: 96px; margin-top: 18px; margin-bottom: 3px; } - #index .items .item .content { + #index .appitems .item .content { width: var(--index-span-width); word-break: normal; overflow: hidden; @@ -304,11 +390,11 @@ div { font-size: var(--span-font-size); line-height: var(--span-line-height); color: var(--index-item-span-word-color); } - #index .items .item:hover { + #index .appitems .item:hover { background-clip: content-box; border-radius: 18px; background-color: var(--index-item-hover-color); } - #index .items .item .tag { + #index .appitems .item .tag { display: inline-block; height: 8px; width: 8px; @@ -317,6 +403,131 @@ div { box-shadow: 0px 2px 8px 0px var(--nav-hash-hover-color); border-radius: 8px; background-color: var(--nav-hash-word-color); } + #index .items { + display: flex; + position: relative; + left: -10px; + width: calc(100% + 20px); + flex-wrap: wrap; + margin: 0 0 30px 0; } + #index .items .tooltip-wp { + position: fixed; + width: 200px; + z-index: 100; + display: none; } + #index .items .tooltip-wp:after { + content: attr(data-title); + position: fixed; + left: 0; + top: 0; + max-width: 500px; + padding: 2px 5px; + word-break: normal; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + font-family: var(--nav-world-font-family); + border-radius: 8px; + border: 1px solid var(--nav-hove-border-color); } + #index .items .quickitem { + position: relative; + border-radius: 18px; + width: calc(50% - 20px); + height: 160px; + margin: 5px 10px 0px 10px; + text-align: center; + vertical-align: bottom; } + #index .items .quickitem #icon { + width: 68px; + height: 68px; + margin: 10px 0px 0px 0px; } + #index .items .quickitem #title { + height: 50px; + color: #FFFFFF; + display: flex; + justify-content: center; + align-items: center; + font-family: var(--nav-world-font-family); + font-weight: bold; + font-size: 20px; + vertical-align: center; + text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2); + padding: 0; + margin: 0; } + #index .items .quickitem #click { + color: #FFFFFF; + font-family: var(--nav-world-font-family); + font-weight: normal; + font-size: 14px; + text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2); + padding: 0; + margin: 0; } + #index .items .quickitem:hover::before { + visibility: visible; + cursor: pointer; } + #index .items .quickitem::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: 18px; + background-color: var(--index-item-hover-color); + visibility: hidden; } + #index .items .videoitem { + position: relative; + border-radius: 18px; + width: 182px; + height: 143px; + padding: 5px 10px 25px 10px; + text-align: center; + vertical-align: bottom; } + #index .items .videoitem .image { + width: 182px; + height: 115px; + border-radius: 8px; + box-shadow: 1px 1px 4px rgba(41, 30, 30, 0.1); } + #index .items .videoitem .title-div { + position: static; + width: 162; + white-space: nowrap; + overflow: hidden; + word-break: normal; + overflow: hidden; + text-overflow: ellipsis; + margin: 8px 0 0 10px; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + font-family: var(--nav-world-font-family); + font-size: var(--span-font-size); + font-weight: 500; + color: var(--index-item-span-word-color); } + #index .items .videoitem .title-div .title-wrapper { + position: fixed; + visibility: hidden; + background-color: var(--tips-background-color); + color: var(--nav-hove-word-color); + max-width: 500px; + z-index: 10; + padding: 2px 5px; + border-radius: 18px; + border: 1px solid var(--nav-hove-border-color); + font-family: var(--nav-world-font-family); } + #index .items .videoitem .title-div .title-wrapper.show { + visibility: visible; } + #index .items .videoitem:hover::before { + visibility: visible; + cursor: pointer; } + #index .items .videoitem::before { + content: ""; + position: absolute; + top: 5px; + right: 10px; + left: 10px; + height: 115px; + border-radius: 8px; + background-color: var(--index-item-hover-color); + visibility: hidden; } body { overflow: hidden; } @@ -341,22 +552,6 @@ body { border-radius: 8px; border: 1px solid var(--nav-hove-border-color); } -#main .support-div { - width: 48px; - height: 48px; - border-radius: 48px; - background-color: var(--nav-hash-word-color); - display: inline-block; - position: absolute; - right: 20px; - bottom: 20px; } - -#main .support { - width: 20px; - height: 21px; - margin-top: 14px; - margin-left: 14px; } - #nav { margin: 0 0 0 0; padding-bottom: 10px; @@ -507,20 +702,9 @@ body { height: 18px; vertical-align: middle; } #search .items .item img[src$='png'] { - max-width: 99%; - cursor: pointer; } - @media screen and (-webkit-min-device-pixel-ratio: 1.25) { - #search .items .item img[src$='png'] { - zoom: 2; } } - @media screen and (-webkit-min-device-pixel-ratio: 1.5) { - #search .items .item img[src$='png'] { - zoom: 1; } } - @media screen and (-webkit-min-device-pixel-ratio: 1.75) { - #search .items .item img[src$='png'] { - zoom: 0.66667; } } - @media screen and (-webkit-min-device-pixel-ratio: 2) { - #search .items .item img[src$='png'] { - zoom: 0.5; } } + margin-top: -2px; + height: 18px; + vertical-align: middle; } #search .items .item img[src$='jpg'] { max-width: 99%; cursor: pointer; @@ -557,3 +741,22 @@ body { -webkit-box-orient: vertical; } #search .items .highlight { color: #2bba57; } + #search .videoItems { + padding: 14px 20px 0px 0px; + position: absolute; + top: 0; } + #search .videoItems #item { + height: 34px; + display: flex; + align-items: center; } + #search .videoItems #item span { + margin: 0 0 0 10px; + vertical-align: center; + text-decoration: underline; + color: var(--nav-hash-word-color); + font-family: var(--nav-world-font-family); + font-weight: 500; + font-size: 1.1rem; } + #search .videoItems #item span:hover { + color: var(--nav-hash-hover-color); + cursor: pointer; } diff --git a/src/web_dist/toManual/index.html b/src/web_dist/toManual/index.html index a16a03e3c..23e67fc80 100644 --- a/src/web_dist/toManual/index.html +++ b/src/web_dist/toManual/index.html @@ -14,4 +14,4 @@ - \ No newline at end of file + diff --git a/src/web_dist/toManual/index.js b/src/web_dist/toManual/index.js index 1f1bb1fe6..9bee5feff 100644 --- a/src/web_dist/toManual/index.js +++ b/src/web_dist/toManual/index.js @@ -1,43332 +1,45010 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - (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 scrollingEdgeEnd || elementEdgeStart > scrollingEdgeStart && elementEdgeEnd < scrollingEdgeEnd) { - return 0; - } +var _history = require('history'); - if (elementEdgeStart <= scrollingEdgeStart && elementSize <= scrollingSize || elementEdgeEnd >= scrollingEdgeEnd && elementSize >= scrollingSize) { - return elementEdgeStart - scrollingEdgeStart - scrollingBorderStart; - } +var _mdToHtml = require('./mdToHtml'); - if (elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize || elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize) { - return elementEdgeEnd - scrollingEdgeEnd + scrollingBorderEnd; - } +var _mdToHtml2 = _interopRequireDefault(_mdToHtml); - return 0; -} +var _index = require('./index.jsx'); -var _default = function _default(target, options) { - var scrollMode = options.scrollMode, - block = options.block, - inline = options.inline, - boundary = options.boundary, - skipOverflowHiddenElements = options.skipOverflowHiddenElements; - var checkBoundary = typeof boundary === 'function' ? boundary : function (node) { - return node !== boundary; - }; +var _index2 = _interopRequireDefault(_index); - if (!isElement(target)) { - throw new TypeError('Invalid target'); - } +var _main = require('./main.jsx'); - var scrollingElement = document.scrollingElement || document.documentElement; - var frames = []; - var cursor = target; +var _main2 = _interopRequireDefault(_main); - while (isElement(cursor) && checkBoundary(cursor)) { - cursor = cursor.parentNode; +var _search = require('./search.jsx'); - if (cursor === scrollingElement) { - frames.push(cursor); - break; - } +var _search2 = _interopRequireDefault(_search); - if (cursor === document.body && isScrollable(cursor) && !isScrollable(document.documentElement)) { - continue; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (isScrollable(cursor, skipOverflowHiddenElements)) { - frames.push(cursor); - } - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var viewportWidth = window.visualViewport ? visualViewport.width : innerWidth; - var viewportHeight = window.visualViewport ? visualViewport.height : innerHeight; - var viewportX = window.scrollX || pageXOffset; - var viewportY = window.scrollY || pageYOffset; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - var _target$getBoundingCl = target.getBoundingClientRect(), - targetHeight = _target$getBoundingCl.height, - targetWidth = _target$getBoundingCl.width, - targetTop = _target$getBoundingCl.top, - targetRight = _target$getBoundingCl.right, - targetBottom = _target$getBoundingCl.bottom, - targetLeft = _target$getBoundingCl.left; +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var targetBlock = block === 'start' || block === 'nearest' ? targetTop : block === 'end' ? targetBottom : targetTop + targetHeight / 2; - var targetInline = inline === 'center' ? targetLeft + targetWidth / 2 : inline === 'end' ? targetRight : targetLeft; - var computations = []; +global.hash = ' '; +global.isMouseClickNav = false; +global.isMouseScrollArticle = false; - for (var index = 0; index < frames.length; index++) { - var frame = frames[index]; +global.isLinkClicked = false; - var _frame$getBoundingCli = frame.getBoundingClientRect(), - _height = _frame$getBoundingCli.height, - _width = _frame$getBoundingCli.width, - _top = _frame$getBoundingCli.top, - right = _frame$getBoundingCli.right, - bottom = _frame$getBoundingCli.bottom, - _left = _frame$getBoundingCli.left; +global.lastUrlBeforeSearch = '/'; +global.lastHistoryIndex = 0; +global.lastAction = 'PUSH'; +global.isShowHelperSupport = false; +global.isShowAppStore = false; +global.scrollBehavior = 'smooth'; +global.bIsReload = false; +// global.gHistoryGo = 0; - if (scrollMode === 'if-needed' && targetTop >= 0 && targetLeft >= 0 && targetBottom <= viewportHeight && targetRight <= viewportWidth && targetTop >= _top && targetBottom <= bottom && targetLeft >= _left && targetRight <= right) { - return computations; - } - var frameStyle = getComputedStyle(frame); - var borderLeft = parseInt(frameStyle.borderLeftWidth, 10); - var borderTop = parseInt(frameStyle.borderTopWidth, 10); - var borderRight = parseInt(frameStyle.borderRightWidth, 10); - var borderBottom = parseInt(frameStyle.borderBottomWidth, 10); - var blockScroll = 0; - var inlineScroll = 0; - var scrollbarWidth = 'offsetWidth' in frame ? frame.offsetWidth - frame.clientWidth - borderLeft - borderRight : 0; - var scrollbarHeight = 'offsetHeight' in frame ? frame.offsetHeight - frame.clientHeight - borderTop - borderBottom : 0; +global.readFile = function (fileName, callback) { + console.log("global.readFile...", fileName); + var xhr = new XMLHttpRequest(); + xhr.open('GET', fileName); + xhr.onload = function () { + // if (xhr.responseText != '') { + callback(xhr.responseText); + // } + }; + xhr.send(); +}; - if (scrollingElement === frame) { - if (block === 'start') { - blockScroll = targetBlock; - } else if (block === 'end') { - blockScroll = targetBlock - viewportHeight; - } else if (block === 'nearest') { - blockScroll = alignNearest(viewportY, viewportY + viewportHeight, viewportHeight, borderTop, borderBottom, viewportY + targetBlock, viewportY + targetBlock + targetHeight, targetHeight); - } else { - blockScroll = targetBlock - viewportHeight / 2; - } +var Support = function Support(_ref) { + var text = _ref.text; - if (inline === 'start') { - inlineScroll = targetInline; - } else if (inline === 'center') { - inlineScroll = targetInline - viewportWidth / 2; - } else if (inline === 'end') { - inlineScroll = targetInline - viewportWidth; - } else { - inlineScroll = alignNearest(viewportX, viewportX + viewportWidth, viewportWidth, borderLeft, borderRight, viewportX + targetInline, viewportX + targetInline + targetWidth, targetWidth); - } + var _useState = (0, _react.useState)(false), + _useState2 = _slicedToArray(_useState, 2), + isHovered = _useState2[0], + setIsHovered = _useState2[1]; - blockScroll = Math.max(0, blockScroll + viewportY); - inlineScroll = Math.max(0, inlineScroll + viewportX); - } else { - if (block === 'start') { - blockScroll = targetBlock - _top - borderTop; - } else if (block === 'end') { - blockScroll = targetBlock - bottom + borderBottom + scrollbarHeight; - } else if (block === 'nearest') { - blockScroll = alignNearest(_top, bottom, _height, borderTop, borderBottom + scrollbarHeight, targetBlock, targetBlock + targetHeight, targetHeight); - } else { - blockScroll = targetBlock - (_top + _height / 2) + scrollbarHeight / 2; - } + var _useState3 = (0, _react.useState)(text), + _useState4 = _slicedToArray(_useState3, 2), + tooltipText = _useState4[0], + setTooltipText = _useState4[1]; - if (inline === 'start') { - inlineScroll = targetInline - _left - borderLeft; - } else if (inline === 'center') { - inlineScroll = targetInline - (_left + _width / 2) + scrollbarWidth / 2; - } else if (inline === 'end') { - inlineScroll = targetInline - right + borderRight + scrollbarWidth; - } else { - inlineScroll = alignNearest(_left, right, _width, borderLeft, borderRight + scrollbarWidth, targetInline, targetInline + targetWidth, targetWidth); - } + // useEffect(() => { + // setTooltipText(text); + // }, [text]); - var scrollLeft = frame.scrollLeft, - scrollTop = frame.scrollTop; - blockScroll = Math.max(0, Math.min(scrollTop + blockScroll, frame.scrollHeight - _height + scrollbarHeight)); - inlineScroll = Math.max(0, Math.min(scrollLeft + inlineScroll, frame.scrollWidth - _width + scrollbarWidth)); - targetBlock += scrollTop - blockScroll; - targetInline += scrollLeft - inlineScroll; - } + (0, _react.useEffect)(function () { + if (isHovered) { + setTooltipText(global.i18n['Support']); + } + }, [isHovered]); - computations.push({ - el: frame, - top: blockScroll, - left: inlineScroll - }); - } + (0, _react.useEffect)(function () { + if (!isHovered) { + setTooltipText(''); + } + }, [isHovered]); - return computations; + return global.isShowHelperSupport ? _react2.default.createElement( + 'div', + { className: 'support-div', + onClick: function onClick() { + return global.qtObjects.manual.supportClick(); + }, + onMouseEnter: function onMouseEnter() { + return setIsHovered(true); + }, + onMouseLeave: function onMouseLeave() { + return setIsHovered(false); + }, + style: { userSelect: 'none' } + }, + _react2.default.createElement('img', { className: 'support', src: './support.svg' }), + isHovered && _react2.default.createElement( + 'div', + { className: 'tooltip-wrapper ' + (isHovered ? 'show' : '') }, + tooltipText + ) + ) : _react2.default.createElement('div', null); }; -exports.default = _default; -module.exports = exports.default; -},{}],3:[function(require,module,exports){ -var prefix = require('prefix-style') -var toCamelCase = require('to-camel-case') -var cache = { 'float': 'cssFloat' } -var addPxToStyle = require('add-px-to-style') - -function style (element, property, value) { - var camel = cache[property] - if (typeof camel === 'undefined') { - camel = detect(property) - } +var AppStore = function AppStore(_ref2) { + var text = _ref2.text; - // may be false if CSS prop is unsupported - if (camel) { - if (value === undefined) { - return element.style[camel] - } + var _useState5 = (0, _react.useState)(false), + _useState6 = _slicedToArray(_useState5, 2), + isHovered = _useState6[0], + setIsHovered = _useState6[1]; - element.style[camel] = addPxToStyle(camel, value) - } -} + var _useState7 = (0, _react.useState)(text), + _useState8 = _slicedToArray(_useState7, 2), + tooltipText = _useState8[0], + setTooltipText = _useState8[1]; -function each (element, properties) { - for (var k in properties) { - if (properties.hasOwnProperty(k)) { - style(element, k, properties[k]) - } - } -} + (0, _react.useEffect)(function () { + if (isHovered) { + setTooltipText(global.i18n['AppStore']); + } + }, [isHovered]); -function detect (cssProp) { - var camel = toCamelCase(cssProp) - var result = prefix(camel) - cache[camel] = cache[cssProp] = cache[result] = result - return result -} + (0, _react.useEffect)(function () { + if (!isHovered) { + setTooltipText(''); + } + }, [isHovered]); -function set () { - if (arguments.length === 2) { - if (typeof arguments[1] === 'string') { - arguments[0].style.cssText = arguments[1] - } else { - each(arguments[0], arguments[1]) - } - } else { - style(arguments[0], arguments[1], arguments[2]) - } -} + return global.isShowAppStore ? _react2.default.createElement( + 'div', + { className: 'store-div', + onClick: function onClick() { + return global.qtObjects.manual.appStoreClick(); + }, + onMouseEnter: function onMouseEnter() { + return setIsHovered(true); + }, + onMouseLeave: function onMouseLeave() { + return setIsHovered(false); + }, + style: { userSelect: 'none' } + }, + _react2.default.createElement('img', { className: 'store', src: './shop.svg' }), + isHovered && _react2.default.createElement( + 'div', + { className: 'tooltip-wrapper ' + (isHovered ? 'show' : '') }, + tooltipText + ) + ) : _react2.default.createElement('div', null); +}; -module.exports = set -module.exports.set = set +var App = function (_React$Component) { + _inherits(App, _React$Component); -module.exports.get = function (element, properties) { - if (Array.isArray(properties)) { - return properties.reduce(function (obj, prop) { - obj[prop] = style(element, prop || '') - return obj - }, {}) - } else { - return style(element, properties || '') - } -} + function App(props, context) { + _classCallCheck(this, App); -},{"add-px-to-style":1,"prefix-style":16,"to-camel-case":78}],4:[function(require,module,exports){ -'use strict'; + var _this = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, props, context)); -Object.defineProperty(exports, '__esModule', { value: true }); + _this.state = { + init: false, + searchResult: [], + mismatch: false, + historyGO: 0 + // changeAppList:[] + }; + new QWebChannel(qt.webChannelTransport, _this.initQt.bind(_this)); + return _this; + } -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + _createClass(App, [{ + key: 'initQt', + value: function initQt(channel) { + var _this2 = this; -var resolvePathname = _interopDefault(require('resolve-pathname')); -var valueEqual = _interopDefault(require('value-equal')); -var warning = _interopDefault(require('tiny-warning')); -var invariant = _interopDefault(require('tiny-invariant')); + console.log("channel initqt....."); + channel.objects.i18n.getSentences(function (i18n) { + channel.objects.i18n.getLocale(function (lang) { + if (lang === 'en_US' || lang === 'zh_CN') { + global.lang = lang; + } else { + global.lang = 'en_US'; + } + }); -function _extends() { - _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; + global.i18n = i18n; + global.qtObjects = channel.objects; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } + global.qtObjects.manual.hasSelperSupport(function (bFlag) { + global.isShowHelperSupport = bFlag; + }); + global.qtObjects.manual.hasAppStore(function (bFlag) { + global.isShowAppStore = bFlag; + }); - return target; - }; + global.qtObjects.manual.bIsLongSon(function (isLongSon) { + if (isLongSon) { + global.scrollBehavior = 'auto'; + } + }); - return _extends.apply(this, arguments); -} + channel.objects.manual.getSystemManualDir(function (path) { + global.path = path; + }); + // global.openWindow = global.qtObjects.manual.openExternalLink; + // global.qtObjects.titleBar.setBackwardButtonActive(false); + // global.qtObjects.titleBar.setForwardButtonActive(false); + global.qtObjects.titleBar.backwardButtonClicked.connect(_this2.onBackwardClick.bind(_this2)); + global.qtObjects.titleBar.forwardButtonClicked.connect(_this2.onForwardClick.bind(_this2)); + global.qtObjects.search.mismatch.connect(function () { + return _this2.setState({ mismatch: true }); + }); + global.qtObjects.search.onContentResult.connect(_this2.onContentResult.bind(_this2)); + global.qtObjects.search.reloadPage.connect(_this2.onReloadPage.bind(_this2)); + global.qtObjects.manual.searchEditTextisEmpty.connect(_this2.onSearchEditClear.bind(_this2)); + global.qtObjects.theme.getTheme(function (themeType) { + return _this2.themeChange(themeType); + }); + global.qtObjects.theme.themeChange.connect(_this2.themeChange.bind(_this2)); + global.qtObjects.settings.fontChangeRequested.connect(_this2.onFontChange.bind(_this2)); + console.log("finsh global.qtObjects = channel.objects..."); + global.qtObjects.manual.finishChannel(); + }); + } + }, { + key: 'onBackwardClick', + value: function onBackwardClick() { + global.handleLocation(global.hash); + console.log("----------backwardButtonClicked----------"); + this.setState({ historyGO: this.state.historyGO - 1 }); + console.log("==========backwardButtonClicked=========>"); + this.context.router.history.goBack(); + console.log("back history location: " + this.context.router.history.location.pathname); + } + }, { + key: 'onForwardClick', + value: function onForwardClick() { + global.handleLocation(global.hash); + console.log("----------forwardButtonClicked----------"); + this.setState({ historyGO: this.state.historyGO + 1 }); + console.log("==========forwardButtonClicked=========>"); + this.context.router.history.goForward(); + console.log("forward history location: " + this.context.router.history.location.pathname); + } + }, { + key: 'onFontChange', + value: function onFontChange(fontFamily, fontSize) { + console.log("fontChangeRequested: fontFamily:" + fontFamily + ",fontSize:" + fontSize); + console.log("fontSize/13.0:" + fontSize); + var HTMLGlobal = document.querySelector('html'); + HTMLGlobal.style.fontFamily = fontFamily; + HTMLGlobal.style.fontSize = fontSize; //设置rem标准 设计图上默认是在14px字体上设计,所以默认1rem = 14px. + if (fontSize >= 18) { + document.documentElement.style.setProperty('--index-item-size', '170px'); + document.documentElement.style.setProperty('--index-span-width', '140px'); + } else { + document.documentElement.style.setProperty('--index-item-size', '160px'); + document.documentElement.style.setProperty('--index-span-width', '130px'); + } + } + }, { + key: 'themeChange', + value: function themeChange(themeType) { + global.setTheme(themeType); + } + }, { + key: 'onContentResult', + value: function onContentResult(appName, titleList, idList, contentList) { + var _this3 = this; -function addLeadingSlash(path) { - return path.charAt(0) === '/' ? path : '/' + path; -} -function stripLeadingSlash(path) { - return path.charAt(0) === '/' ? path.substr(1) : path; -} -function hasBasename(path, prefix) { - return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); -} -function stripBasename(path, prefix) { - return hasBasename(path, prefix) ? path.substr(prefix.length) : path; -} -function stripTrailingSlash(path) { - return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path; -} -function parsePath(path) { - var pathname = path || '/'; - var search = ''; - var hash = ''; - var hashIndex = pathname.indexOf('#'); + console.log('app 搜索结果', appName, titleList, idList, contentList); + var searchResult = this.state.searchResult; - if (hashIndex !== -1) { - hash = pathname.substr(hashIndex); - pathname = pathname.substr(0, hashIndex); - } + var filePath = void 0; + // if (appName == "dde") + // { + // filePath = `${global.path}/system/${appName}/${global.lang}/index.md`; + // } + // else + // { + // filePath = `${global.path}/application/${appName}/${global.lang}/index.md`; + // } + var myPromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.appToPath(appName, function (filepath) { + filePath = filepath; + resolve(); + }); + }); - var searchIndex = pathname.indexOf('?'); + myPromise.then(function () { + if (appName === "video-guide") { + filePath = "video-guide"; + } + searchResult.push({ + file: filePath, + idList: idList, + titleList: titleList, + contentList: contentList + }); + _this3.setState({ searchResult: searchResult, mismatch: false }); + }); + } + }, { + key: 'onReloadPage', + value: function onReloadPage(appList) { + var _this4 = this; - if (searchIndex !== -1) { - search = pathname.substr(searchIndex); - pathname = pathname.substr(0, searchIndex); - } + // console.log("============>page reload..."); + var bRetFlag = true; + var locationPath = this.context.router.history.location.pathname; + console.log("============>page reload...", locationPath); + var list = locationPath.split("/"); + if (list[1] == 'open') { + var curApp = list[2]; + console.log("============>open...", appList, curApp); + var bFlag = false; + appList.map(function (app) { + if (!bFlag && curApp.indexOf(app) != -1) { + bFlag = true; + } + }); - return { - pathname: pathname, - search: search === '?' ? '' : search, - hash: hash === '#' ? '' : hash - }; -} -function createPath(location) { - var pathname = location.pathname, - search = location.search, - hash = location.hash; - var path = pathname || '/'; - if (search && search !== '?') path += search.charAt(0) === '?' ? search : "?" + search; - if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : "#" + hash; - return path; -} - -function createLocation(path, state, key, currentLocation) { - var location; - - if (typeof path === 'string') { - // Two-arg form: push(path, state) - location = parsePath(path); - location.state = state; - } else { - // One-arg form: push(location) - location = _extends({}, path); - if (location.pathname === undefined) location.pathname = ''; - - if (location.search) { - if (location.search.charAt(0) !== '?') location.search = '?' + location.search; - } else { - location.search = ''; - } - - if (location.hash) { - if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash; - } else { - location.hash = ''; - } - - if (state !== undefined && location.state === undefined) location.state = state; - } - - try { - location.pathname = decodeURI(location.pathname); - } catch (e) { - if (e instanceof URIError) { - throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.'); - } else { - throw e; - } - } + if (bFlag) { + global.qtObjects.manual.getSystemManualList(function (appNames) { + var bKFlage = false; + appNames.map(function (name) { + if (curApp.indexOf(name) != -1) { + bKFlage = true; + } + }); - if (key) location.key = key; + if (bKFlage) { + global.bIsReload = true; + _this4.context.router.history.go(0); + } else { + var historyList = _this4.context.router.history.entries; + var index = _this4.context.router.history.index; + var historyLate = historyList.slice(index + 1); + console.log("===========>", historyLate); + _this4.setState({ historyGO: _this4.state.historyGO - 1 }); + _this4.context.router.history.go(-1); - if (currentLocation) { - // Resolve incomplete/relative pathname relative to current location. - if (!location.pathname) { - location.pathname = currentLocation.pathname; - } else if (location.pathname.charAt(0) !== '/') { - location.pathname = resolvePathname(location.pathname, currentLocation.pathname); - } - } else { - // When there is no prior location and pathname is empty, set it to / - if (!location.pathname) { - location.pathname = '/'; - } - } + historyLate.map(function (url) { + console.log("..........>", url); + _this4.context.router.history.push(url); + }); + global.backHome(); + } + }); + } else { + bRetFlag = false; + } + } else if (list[1] == 'search') { + console.log("============>search...", list[2]); + global.qtObjects.search.updateSearch(list[2]); + } else { + global.bIsReload = true; + this.context.router.history.go(0); + } - return location; -} -function locationsAreEqual(a, b) { - return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && valueEqual(a.state, b.state); -} + if (bRetFlag) { + global.qtObjects.manual.showUpdateLabel(); + } + } + }, { + key: 'onSearchEditClear', -function createTransitionManager() { - var prompt = null; - function setPrompt(nextPrompt) { - warning(prompt == null, 'A history supports only one prompt at a time'); - prompt = nextPrompt; - return function () { - if (prompt === nextPrompt) prompt = null; - }; - } + //搜索框清空后回到上一个页面(未搜索的页面). + value: function onSearchEditClear() { + console.log("==================>onSearcheditclear"); + var locationPath = this.context.router.history.location.pathname; + var list = locationPath.split("/"); + var bFlag = false; + //open页length = 5, search页length = 3 + if (list.length == 5 && list[4] != "") { + bFlag = true; + } else if (list.length == 3 && list[2] != "") { + bFlag = true; + } - function confirmTransitionTo(location, action, getUserConfirmation, callback) { - // TODO: If another transition starts while we're still confirming - // the previous one, we may end up in a weird state. Figure out the - // best way to handle this. - if (prompt != null) { - var result = typeof prompt === 'function' ? prompt(location, action) : prompt; + if (bFlag) { + var step; + var indexGo = this.state.historyGO; + // var indexGo = global.gHistoryGo; + var objList = this.context.router.history.entries; + for (var i = indexGo; i >= 0; i--) { - if (typeof result === 'string') { - if (typeof getUserConfirmation === 'function') { - getUserConfirmation(result, callback); - } else { - warning(false, 'A history needs a getUserConfirmation function in order to use a prompt message'); - callback(true); + var curPath = objList[i].pathname; + 帮助; + var curPathList = curPath.split("/"); + if (curPathList.length == 5 && curPathList[4] == "") { + step = indexGo - i; + break; + } else if (curPathList.length == 3 && curPathList[2] == "") { + step = indexGo - i; + break; + } else if (curPathList.length == 2) { + step = indexGo - i; + break; + } + } + if (step) { + if (this.context.router.history.canGo(-1 * step)) { + this.setState({ historyGO: this.state.historyGO - step }); + // global.gHistoryGo = global.gHistoryGo - step; + this.context.router.history.go(-1 * step); + } + } + } } - } else { - // Return false from a transition hook to cancel the transition. - callback(result !== false); - } - } else { - callback(true); - } - } + }, { + key: 'getChildContext', + value: function getChildContext() { + var _state = this.state, + searchResult = _state.searchResult, + mismatch = _state.mismatch; - var listeners = []; + return { searchResult: searchResult, mismatch: mismatch }; + } + }, { + key: 'isbase64', + value: function isbase64(str) { + if (str == '' || str.trim == '') { + return false; + } + try { + return btoa(atob(str)) == str; + } catch (err) { + return false; + } + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + console.log("app componentWillReceiveProps", this.context.router.history); + console.log("this location: " + this.context.router.history.location); + var pathName = this.context.router.history.location.pathname; + var pathList = pathName.split("/"); + var cKeyword = ''; - function appendListener(fn) { - var isActive = true; + if (pathName.includes("common-application-libraries")) document.documentElement.style.setProperty('--app-store-visibility', 'visible');else document.documentElement.style.setProperty('--app-store-visibility', 'hidden'); - function listener() { - if (isActive) fn.apply(void 0, arguments); - } + //search页===>/search/:keyword + //open页=====>/open/:file/:hash?/:key? + if (pathList.length == 3) { + cKeyword = pathList[2]; + } else if (pathList.length == 5) { + cKeyword = pathList[4]; + } - listeners.push(listener); - return function () { - isActive = false; - listeners = listeners.filter(function (item) { - return item !== listener; - }); - }; - } + if (this.isbase64(cKeyword)) { + global.qtObjects.search.getKeyword(decodeURIComponent(atob(cKeyword))); + } else { + global.qtObjects.search.getKeyword(decodeURIComponent(cKeyword)); + } - function notifyListeners() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + if (this.context.router.history.action == 'PUSH') { + var entriesLen = this.context.router.history.entries.length; + if (entriesLen > 1) { + var entry = this.context.router.history.entries[entriesLen - 1]; + if (entry.pathname.toString().indexOf("/search/") != -1) { + this.setState({ historyGO: entriesLen - 1 }); + // global.gHistoryGo = entriesLen - 1; + return; + } + } + this.setState({ historyGO: entriesLen - 1 }); + // global.gHistoryGo = entriesLen - 1; + } - listeners.forEach(function (listener) { - return listener.apply(void 0, args); - }); - } + //切换状态时,去除选中状态....为何选中状态切换页面时会保留?????? + window.getSelection().empty(); + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + var _this5 = this; - return { - setPrompt: setPrompt, - confirmTransitionTo: confirmTransitionTo, - appendListener: appendListener, - notifyListeners: notifyListeners - }; -} + global.index = function () { + // this.context.router.history.push('/'); + if (_this5.state.init == false) { + _this5.setState({ init: true }); + } + }; + global.backHome = function () { + global.handleLocation(global.hash); + console.log("global.backHome()" + _this5.context.router.history.entries.length); + console.log("global.backHome()" + _this5.state.historyGO); + var goNum = _this5.state.historyGO; + _this5.setState({ historyGO: 0 }); + console.log("global.backHome()" + goNum); -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); -function getConfirmation(message, callback) { - callback(window.confirm(message)); // eslint-disable-line no-alert -} -/** - * Returns true if the HTML5 history API is supported. Taken from Modernizr. - * - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586 - */ + if (_this5.context.router.history.canGo(-1 * goNum)) { + _this5.context.router.history.go(-1 * goNum); + // this.context.router.history.go(0); + } + }; -function supportsHistory() { - var ua = window.navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; - return window.history && 'pushState' in window.history; -} -/** - * Returns true if browser fires popstate on hash change. - * IE10 and IE11 do not. - */ + //打开某一个文件,并定位到具体hash + global.open = function (file) { + var hash = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; -function supportsPopStateOnHashChange() { - return window.navigator.userAgent.indexOf('Trident') === -1; -} -/** - * Returns false if using go(n) with hash history causes a full page reload. - */ + console.log("global.open()....file:" + file + " hash:" + hash + " key:" + key); + //h0默认为应用名称,内容为空,所以当打开h0,将其变为h1概述的位置。 + if (hash == 'h0' || hash == '') { + hash = 'h1'; + } + file = encodeURIComponent(file); + // console.log("globla.open........... ", file); + hash = encodeURIComponent(hash); + global.hash = hash; -function supportsGoWithoutReloadUsingHash() { - return window.navigator.userAgent.indexOf('Firefox') === -1; -} -/** - * Returns true if a given popstate event is an extraneous WebKit event. - * Accounts for the fact that Chrome on iOS fires real popstate events - * containing undefined state when pressing the back button. - */ + // '%'字符替换为其他非常用字符组合,来替代'%', 路由URL单含此字符会出错。。。 + if (key == '%') { + key = '=-='; + } -function isExtraneousPopstateEvent(event) { - event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1; -} + var url = '/open/' + file + '/' + hash + '/' + key; + _this5.context.router.history.push(url); -var PopStateEvent = 'popstate'; -var HashChangeEvent = 'hashchange'; + //Init属性设置, 放在index与opentitle中. 避免直接跳转到特定模块时会先走/模块. + if (_this5.state.init == false) { + _this5.setState({ init: true }); + } -function getHistoryState() { - try { - return window.history.state || {}; - } catch (e) { - // IE 11 sometimes throws when accessing window.history.state - // See https://github.com/ReactTraining/history/pull/289 - return {}; - } -} -/** - * Creates a history object that uses the HTML5 history API including - * pushState, replaceState, and the popstate event. - */ + //通知qt对象,修改应用打开状态 + global.qtObjects.manual.setApplicationState(file); + }; + global.openTitle = function (file) { + var title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; -function createBrowserHistory(props) { - if (props === void 0) { - props = {}; - } + console.log("global linkTitle==> file:" + file + " title: " + title); + global.handleLocation(global.hash); + if (title !== '') { + var filePath = void 0; + // if(file == "dde") + // { + // filePath = `${global.path}/system/${file}/${global.lang}/index.md` + // } + // else + // { + // filePath = `${global.path}/application/${file}/${global.lang}/index.md` + // } - !canUseDOM ? invariant(false, 'Browser history needs a DOM') : void 0; - var globalHistory = window.history; - var canUseHistory = supportsHistory(); - var needsHashChangeListener = !supportsPopStateOnHashChange(); - var _props = props, - _props$forceRefresh = _props.forceRefresh, - forceRefresh = _props$forceRefresh === void 0 ? false : _props$forceRefresh, - _props$getUserConfirm = _props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm, - _props$keyLength = _props.keyLength, - keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength; - var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : ''; + var myPromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.appToPath(file, function (filepath) { + filePath = filepath; + resolve(); + }); + }); - function getDOMLocation(historyState) { - var _ref = historyState || {}, - key = _ref.key, - state = _ref.state; + myPromise.then(function () { + global.readFile(filePath, function (data) { + var _m2h = (0, _mdToHtml2.default)(filePath, data), + html = _m2h.html; - var _window$location = window.location, - pathname = _window$location.pathname, - search = _window$location.search, - hash = _window$location.hash; - var path = pathname + search + hash; - warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); - if (basename) path = stripBasename(path, basename); - return createLocation(path, state, key); - } + var d = document.createElement('div'); + d.innerHTML = html; + var dlist = d.querySelectorAll('[text="' + title + '"]'); + if (dlist.length == 0) { + var translatePromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.translateTitle(title, function (titleTr) { + title = titleTr; + resolve(); + }); + }); - function createKey() { - return Math.random().toString(36).substr(2, keyLength); - } + translatePromise.then(function () { + dlist = d.querySelectorAll('[text="' + title + '"]'); + var hashID = 'h0'; + for (var i = 0; i < dlist.length; i++) { + hashID = dlist[i].id; + } + global.open(file, hashID); + }); + } else { + var hashID = 'h0'; + for (var i = 0; i < dlist.length; i++) { + hashID = dlist[i].id; + } + global.open(file, hashID); + } + }); + }); + } else { + global.open(file); + } + }; - var transitionManager = createTransitionManager(); + //替换当前URL,仅仅在切换到其他页面处调用...(包含前进,后退,重新打开一个新的页面) + global.handleLocation = function () { + var hash = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - function setState(nextState) { - _extends(history, nextState); + var url = _this5.context.router.history.location.pathname; + console.log("global.handhash: ", url); + var urlList = url.split("/"); + if (urlList.length == 5) { + url = '/' + urlList[1] + '/' + urlList[2] + '/' + hash + '/' + urlList[4]; + console.log("new url:", url); + _this5.context.router.history.replace(url); + } + }; - history.length = globalHistory.length; - transitionManager.notifyListeners(history.location, history.action); - } + //获取当前系统活动色 + global.setHashWordColor = function (strRgb) { + console.log("hash color: ", strRgb); + document.documentElement.style.setProperty('--nav-hash-word-color', strRgb); //btnlist 改这行 - function handlePopState(event) { - // Ignore extraneous popstate events in WebKit. - if (isExtraneousPopstateEvent(event)) return; - handlePop(getDOMLocation(event.state)); - } + //对系统活动色统一增加一定的值作为Hover色 + var rgb = strRgb.slice(1); + var r = rgb.substr(0, 2); + var g = rgb.substr(2, 2); + var b = rgb.substr(4, 2); + var nR = parseInt(r, 16); + var nG = parseInt(g, 16); + var nB = parseInt(b, 16); + nR += 16; + nG += 16; + nB += 16; + if (nR > 255) nR = 255; + if (nG > 255) nG = 255; + if (nB > 255) nB = 255; + var toR = nR.toString(16); + var toG = nG.toString(16); + var toB = nB.toString(16); + if (toR.length == 1) toR = '0' + toR; + if (toG.length == 1) toG = '0' + toG; + if (toB.length == 1) toB = '0' + toB; + var toRGB = "#" + toR + toG + toB; + console.log('hover color:', toRGB); + document.documentElement.style.setProperty('--nav-hash-hover-color', toRGB); - function handleHashChange() { - handlePop(getDOMLocation(getHistoryState())); - } + var pR = parseInt(r, 16); + var pG = parseInt(g, 16); + var pB = parseInt(b, 16); + pR -= 16; + pG -= 16; + pB -= 16; + if (pR > 255) pR = 255; + if (pG > 255) pG = 255; + if (pB > 255) pB = 255; + toR = pR.toString(16); + toG = pG.toString(16); + toB = pB.toString(16); + if (toR.length == 1) toR = '0' + toR; + if (toG.length == 1) toG = '0' + toG; + if (toB.length == 1) toB = '0' + toB; + toRGB = "#" + toR + toG + toB; + document.documentElement.style.setProperty('--nav-hash-press-color', toRGB); + // toRGB = "rgba(" + pR + ", " + pG + ", " + pB + ", " + "0.4)"; + // document.documentElement.style.setProperty(`--active-shadow-color`, toRGB); + }; - var forceNextPop = false; + global.setWordFontfamily = function (strFontFamily) { + document.documentElement.style.setProperty('--nav-world-font-family', strFontFamily); //btnlist 改这行 + }; - function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); - } else { - var action = 'POP'; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ - action: action, - location: location - }); - } else { - revertPop(location); - } - }); - } - } + global.setTheme = function (themeType) { + console.log('主题切换', themeType); + if (navigator.language.toString().indexOf('en_') != -1) { + document.documentElement.style.setProperty('--span-line-height', '1.0rem'); + document.documentElement.style.setProperty('--span-font-size', '0.9rem'); + document.documentElement.style.setProperty('--span-maring-bottom', '0.15rem'); + } else { + document.documentElement.style.setProperty('--span-line-height', '1.4rem'); + document.documentElement.style.setProperty('--span-font-size', '1.03rem'); + document.documentElement.style.setProperty('--span-maring-bottom', '0.15rem'); + } + if ("DarkType" == themeType) { + console.log('DarkType'); + document.documentElement.style.setProperty('--nav-hover-color', 'rgba(255,255,255,0.1)'); + document.documentElement.style.setProperty('--body-background-color', '#252525'); + document.documentElement.style.setProperty('--body-color-white2black', '#000000'); + document.documentElement.style.setProperty('--app-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--nav-background-color', '#282828'); + document.documentElement.style.setProperty('--nav-h2-word-color', 'rgba(255, 255, 255, 0.85)'); + document.documentElement.style.setProperty('--nav-h3-word-color', 'rgba(255, 255, 255, 0.7)'); + document.documentElement.style.setProperty('--nav-hove-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--nav-hove-border-color', 'rgba(0, 0, 0, 0.3)'); + //document.documentElement.style.setProperty(`--nav-hash-word-color`, '#0059D2'); //btnlist 改这行 + document.documentElement.style.setProperty('--article-read-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--article-read-h2-word-color', '#0082FA'); + document.documentElement.style.setProperty('--article-table-text-color', '#6D7C88'); + document.documentElement.style.setProperty('--article-table-border-color', 'rgba(96, 96, 96, 0.5)'); + document.documentElement.style.setProperty('--article-table-cell-border-color', 'rgba(96, 96, 96, 0.1)'); + document.documentElement.style.setProperty('--index-item-background-color', 'rgba(255,255,255,0.05)'); + document.documentElement.style.setProperty('--index-item-hover-color', 'rgba(255,255,255,0.2)'); + document.documentElement.style.setProperty('--index-item-span-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--search-noresult-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--search-button-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--search-button-hover-word-color', '#FFFFFF'); + document.documentElement.style.setProperty('--search-items-word-color', '#6D7C88'); + document.documentElement.style.setProperty('--search-items-resultnum-word-color', '#6D7C88'); + document.documentElement.style.setProperty('--search-item-background-color', 'rgba(255,255,255,0.05)'); + document.documentElement.style.setProperty('--scrollbar-div-background-color', 'rgba(255,255,255,0.2)'); + document.documentElement.style.setProperty('--scrollbar-div-hover-background-color', 'rgba(255,255,255,0.25)'); + document.documentElement.style.setProperty('--scrollbar-div-select-background-color', 'rgba(255,255,255,0.3)'); + document.documentElement.style.setProperty('--index-h2-color', 'rgba(255,255,255,0.1)'); + document.documentElement.style.setProperty('--search-button-background-color-start', '#484848'); + document.documentElement.style.setProperty('--search-button-background-color-end', '#414141'); + document.documentElement.style.setProperty('--search-button-hover-color-start', '#676767'); + document.documentElement.style.setProperty('--search-button-hover-color-end', '#606060'); + document.documentElement.style.setProperty('--search-WikiSearch-color', '#6D7C88'); + document.documentElement.style.setProperty('--search-itemTitle-word-color', '#C0C6D4'); + document.documentElement.style.setProperty('--search-context-word-color', '#6D7C88'); + document.documentElement.style.setProperty('--tips-background-color', 'rgba(42, 42, 42, 0.8)'); + document.documentElement.style.setProperty('--tips-border-color', 'rgba(0, 0, 0, 0.3)'); + document.documentElement.style.setProperty('--tips-shadow-color', 'rgba(0, 0, 0, 0.2)'); + } else if ("LightType" == themeType) { + console.log('LightType'); + document.documentElement.style.setProperty('--nav-hover-color', 'rgba(0,0,0,0.1)'); + document.documentElement.style.setProperty('--body-background-color', '#F8F8F8'); + document.documentElement.style.setProperty('--body-color-white2black', '#FFFFFF'); + document.documentElement.style.setProperty('--app-word-color', '#414D68'); + document.documentElement.style.setProperty('--nav-background-color', '#FFFFFF'); + document.documentElement.style.setProperty('--nav-h2-word-color', 'rgba(0, 0, 0, 0.85)'); + document.documentElement.style.setProperty('--nav-h3-word-color', 'rgba(0, 0, 0, 0.7)'); + document.documentElement.style.setProperty('--nav-hove-word-color', '#000000'); + document.documentElement.style.setProperty('--nav-hove-border-color', 'rgba(0, 0, 0, 0.05)'); + // document.documentElement.style.setProperty(`--nav-hash-word-color`, '#ca0c16'); //btn list 改这一行 + document.documentElement.style.setProperty('--article-read-word-color', '#000000'); + document.documentElement.style.setProperty('--article-read-h2-word-color', '#2CA7F8'); + document.documentElement.style.setProperty('--article-table-text-color', '#606060'); + document.documentElement.style.setProperty('--article-table-border-color', 'rgba(0, 0, 0, 0.1)'); + document.documentElement.style.setProperty('--article-table-cell-border-color', 'rgba(0, 0, 0, 0.05)'); + document.documentElement.style.setProperty('--index-item-background-color', '#FFFFFF'); + document.documentElement.style.setProperty('--index-item-hover-color', 'rgba(0,0,0,0.05)'); + document.documentElement.style.setProperty('--index-item-span-word-color', 'rgba(0, 0, 0, 0.7)'); + document.documentElement.style.setProperty('--search-noresult-word-color', '#000000'); + document.documentElement.style.setProperty('--search-button-word-color', '#414D68'); + document.documentElement.style.setProperty('--search-button-hover-word-color', '#001B2E'); + document.documentElement.style.setProperty('--search-items-word-color', '#000000'); + document.documentElement.style.setProperty('--search-items-resultnum-word-color', '#8AA1B4'); + document.documentElement.style.setProperty('--search-item-background-color', 'rgba(255,255,255,1)'); + document.documentElement.style.setProperty('--scrollbar-div-background-color', 'rgba(0,0,0,0.3)'); + document.documentElement.style.setProperty('--scrollbar-div-hover-background-color', 'rgba(0,0,0,0.5)'); + document.documentElement.style.setProperty('--scrollbar-div-select-background-color', 'rgba(0,0,0,0.4)'); + document.documentElement.style.setProperty('--index-h2-color', 'rgba(0, 0, 0, 0.1)'); + document.documentElement.style.setProperty('--search-button-background-color-start', '#E6E6E6'); + document.documentElement.style.setProperty('--search-button-background-color-end', '#E3E3E3'); + document.documentElement.style.setProperty('--search-button-hover-color-start', '#CACACA'); + document.documentElement.style.setProperty('--search-button-hover-color-end', '#C6C6C6'); + document.documentElement.style.setProperty('--search-WikiSearch-color', '#7a7a7a'); + document.documentElement.style.setProperty('--search-itemTitle-word-color', '#000000'); + document.documentElement.style.setProperty('--search-context-word-color', '#000000'); + document.documentElement.style.setProperty('--tips-background-color', 'rgba(247, 247, 247, 0.6)'); + document.documentElement.style.setProperty('--tips-border-color', 'rgba(0, 0, 0, 0.05)'); + document.documentElement.style.setProperty('--tips-shadow-color', 'rgba(0, 0, 0, 0.2)'); + } else { + console.log('Null'); + } - function revertPop(fromLocation) { - var toLocation = history.location; // TODO: We could probably make this more reliable by - // keeping a list of keys we've seen in sessionStorage. - // Instead, we just default to 0 for keys we don't know. + var windowWidth = window.innerWidth; + var leftDistance = windowWidth - 70 + 'px'; + if (windowWidth > 1630 + 234) { + leftDistance = (windowWidth - 1630) / 2 + 1630 + 50 + 'px'; + } + document.documentElement.style.setProperty('--support-position', leftDistance); + }; - var toIndex = allKeys.indexOf(toLocation.key); - if (toIndex === -1) toIndex = 0; - var fromIndex = allKeys.indexOf(fromLocation.key); - if (fromIndex === -1) fromIndex = 0; - var delta = toIndex - fromIndex; + var Base64 = { + encode: function encode(str) { + // first we use encodeURIComponent to get percent-encoded UTF-8, + // then we convert the percent encodings into raw bytes which + // can be fed into btoa. + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { + return String.fromCharCode('0x' + p1); + })); + }, + decode: function decode(str) { + // Going backwards: from bytestream, to percent-encoding, to original string. + console.log("decode URIComponent decode"); + return decodeURIComponent(atob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + } + }; - if (delta) { - forceNextPop = true; - go(delta); - } - } + global.openSearchPage = function (keyword) { + global.handleLocation(global.hash); + console.log('====>', keyword); + var decodeKeyword = Base64.decode(keyword); + console.log("decodeKeyword", decodeKeyword, "===", encodeURIComponent(decodeKeyword)); + console.log("openSearchPage", _this5.context.router.history); + console.log('lastUrl:' + global.lastUrlBeforeSearch + ', lastHistoryIndex: ' + global.lastHistoryIndex); - var initialLocation = getDOMLocation(getHistoryState()); - var allKeys = [initialLocation.key]; // Public interface + var entriesLen = _this5.context.router.history.entries.length; + if ('POP' == global.lastAction && lastHistoryIndex > 0 && lastHistoryIndex < entriesLen - 1) { + console.log("global.opensearch..."); + _this5.context.router.history.entries.length = lastHistoryIndex; + _this5.context.router.history.length = lastHistoryIndex; + _this5.context.router.history.index = lastHistoryIndex - 1; - function createHref(location) { - return basename + createPath(location); - } + _this5.setState({ searchResult: [] }); + _this5.context.router.history.push('/search/' + btoa(encodeURIComponent(decodeKeyword))); - function push(path, state) { - warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - var action = 'PUSH'; - var location = createLocation(path, state, createKey(), history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var href = createHref(location); - var key = location.key, - state = location.state; + return; + } - if (canUseHistory) { - globalHistory.pushState({ - key: key, - state: state - }, null, href); + entriesLen = _this5.context.router.history.entries.length; + if (entriesLen > 1) { + var entry = _this5.context.router.history.entries[entriesLen - 1]; + var entryIndex = entry.pathname.toString().indexOf("/search/"); + if (entryIndex != -1) { + _this5.context.router.history.entries.length = entriesLen - 1; + _this5.context.router.history.length = entriesLen - 1; + _this5.context.router.history.index = _this5.context.router.history.entries.length - 1; + } + } - if (forceRefresh) { - window.location.href = href; - } else { - var prevIndex = allKeys.indexOf(history.location.key); - var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); - nextKeys.push(location.key); - allKeys = nextKeys; - setState({ - action: action, - location: location - }); - } - } else { - warning(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history'); - window.location.href = href; - } - }); - } + _this5.setState({ searchResult: [] }); + _this5.context.router.history.push('/search/' + btoa(encodeURIComponent(decodeKeyword))); + }; - function replace(path, state) { - warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - var action = 'REPLACE'; - var location = createLocation(path, state, createKey(), history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var href = createHref(location); - var key = location.key, - state = location.state; + this.context.router.history.listen(function (location, action) { + //console.log(`The current URL is ${location.pathname}${location.search}${location.hash}` ); + //console.log(`The last navigation action was ${action}`); + //console.log("index:" + this.context.router.history.index); + console.log("app router.history.listen..."); + global.lastUrlBeforeSearch = location.pathname; + global.lastHistoryIndex = _this5.context.router.history.index; + global.lastAction = action; + }); - if (canUseHistory) { - globalHistory.replaceState({ - key: key, - state: state - }, null, href); + global.back = function () { + console.log("global.back()"); + _this5.context.router.history.goBack(); + }; + this.componentDidUpdate(); - if (forceRefresh) { - window.location.replace(href); - } else { - var prevIndex = allKeys.indexOf(history.location.key); - if (prevIndex !== -1) allKeys[prevIndex] = location.key; - setState({ - action: action, - location: location - }); + document.documentElement.style.setProperty('--app-store-visibility', 'hidden'); } - } else { - warning(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history'); - window.location.replace(href); - } - }); - } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + if (global.qtObjects) { + console.log("app componentDidUpdate------------>", this.state.historyGO, this.context.router.history.length); + global.qtObjects.titleBar.setBackwardButtonActive(this.state.historyGO > 0 + // global.gHistoryGo > 0 + ); + global.qtObjects.titleBar.setForwardButtonActive(this.context.router.history.length - this.state.historyGO > 1 + // this.context.router.history.length - global.gHistoryGo > 1 + ); + } + } + }, { + key: 'render', + value: function render() { + return _react2.default.createElement( + 'div', + null, + this.state.init && _react2.default.createElement( + _reactRouterDom.Switch, + null, + _react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/', component: _index2.default }), + _react2.default.createElement(_reactRouterDom.Route, { path: '/index', component: _index2.default }), + _react2.default.createElement(_reactRouterDom.Route, { path: '/open/:file/:hash?/:key?', component: _main2.default }), + _react2.default.createElement(_reactRouterDom.Route, { path: '/search/:keyword', component: _search2.default }) + ), + _react2.default.createElement(AppStore, { text: ' ' }), + _react2.default.createElement(Support, { text: ' ' }) + ); + } + }]); - function go(n) { - globalHistory.go(n); - } + return App; +}(_react2.default.Component); - function goBack() { - go(-1); - } +App.contextTypes = { + router: _propTypes2.default.object +}; +App.childContextTypes = { + searchResult: _propTypes2.default.array, + mismatch: _propTypes2.default.bool +}; - function goForward() { - go(1); - } +window.addEventListener('resize', function () { + var windowWidth = window.innerWidth; + var leftDistance = windowWidth - 70 + 'px'; - var listenerCount = 0; + if (windowWidth > 1630 + 234) { + leftDistance = (windowWidth - 1630) / 2 + 1630 + 50 + 'px'; + } + document.documentElement.style.setProperty('--support-position', leftDistance); +}); - function checkDOMListeners(delta) { - listenerCount += delta; +(0, _reactDom.render)(_react2.default.createElement( + _reactRouterDom.Router, + { history: (0, _history.createMemoryHistory)('/') }, + _react2.default.createElement(App, null) +), document.getElementById('app')); - if (listenerCount === 1 && delta === 1) { - window.addEventListener(PopStateEvent, handlePopState); - if (needsHashChangeListener) window.addEventListener(HashChangeEvent, handleHashChange); - } else if (listenerCount === 0) { - window.removeEventListener(PopStateEvent, handlePopState); - if (needsHashChangeListener) window.removeEventListener(HashChangeEvent, handleHashChange); - } - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./index.jsx":3,"./main.jsx":4,"./mdToHtml":5,"./search.jsx":8,"history":14,"prop-types":29,"react":74,"react-dom":43,"react-router-dom":59}],2:[function(require,module,exports){ +(function (global){ +'use strict'; - var isBlocked = false; +Object.defineProperty(exports, "__esModule", { + value: true +}); - function block(prompt) { - if (prompt === void 0) { - prompt = false; - } +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - var unblock = transitionManager.setPrompt(prompt); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; - } +var _react = require('react'); - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); - } +var _react2 = _interopRequireDefault(_react); - return unblock(); - }; - } +var _reactDom = require('react-dom'); - function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); - return function () { - checkDOMListeners(-1); - unlisten(); - }; - } +var _reactDom2 = _interopRequireDefault(_reactDom); - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; - return history; -} +var _smoothScrollIntoViewIfNeeded = require('smooth-scroll-into-view-if-needed'); -var HashChangeEvent$1 = 'hashchange'; -var HashPathCoders = { - hashbang: { - encodePath: function encodePath(path) { - return path.charAt(0) === '!' ? path : '!/' + stripLeadingSlash(path); - }, - decodePath: function decodePath(path) { - return path.charAt(0) === '!' ? path.substr(1) : path; - } - }, - noslash: { - encodePath: stripLeadingSlash, - decodePath: addLeadingSlash - }, - slash: { - encodePath: addLeadingSlash, - decodePath: addLeadingSlash - } -}; +var _smoothScrollIntoViewIfNeeded2 = _interopRequireDefault(_smoothScrollIntoViewIfNeeded); -function getHashPath() { - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - var href = window.location.href; - var hashIndex = href.indexOf('#'); - return hashIndex === -1 ? '' : href.substring(hashIndex + 1); -} +var _mdToHtml = require('./mdToHtml'); -function pushHashPath(path) { - window.location.hash = path; -} +var _mdToHtml2 = _interopRequireDefault(_mdToHtml); -function replaceHashPath(path) { - var hashIndex = window.location.href.indexOf('#'); - window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path); -} +var _scrollbar = require('./scrollbar.jsx'); -function createHashHistory(props) { - if (props === void 0) { - props = {}; - } +var _scrollbar2 = _interopRequireDefault(_scrollbar); - !canUseDOM ? invariant(false, 'Hash history needs a DOM') : void 0; - var globalHistory = window.history; - var canGoWithoutReload = supportsGoWithoutReloadUsingHash(); - var _props = props, - _props$getUserConfirm = _props.getUserConfirmation, - getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm, - _props$hashType = _props.hashType, - hashType = _props$hashType === void 0 ? 'slash' : _props$hashType; - var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : ''; - var _HashPathCoders$hashT = HashPathCoders[hashType], - encodePath = _HashPathCoders$hashT.encodePath, - decodePath = _HashPathCoders$hashT.decodePath; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - function getDOMLocation() { - var path = decodePath(getHashPath()); - warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); - if (basename) path = stripBasename(path, basename); - return createLocation(path); - } +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - var transitionManager = createTransitionManager(); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - function setState(nextState) { - _extends(history, nextState); +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - history.length = globalHistory.length; - transitionManager.notifyListeners(history.location, history.action); - } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - var forceNextPop = false; - var ignorePath = null; +var Article = function (_Component) { + _inherits(Article, _Component); - function handleHashChange() { - var path = getHashPath(); - var encodedPath = encodePath(path); + function Article(props) { + _classCallCheck(this, Article); - if (path !== encodedPath) { - // Ensure we always have a properly-encoded hash. - replaceHashPath(encodedPath); - } else { - var location = getDOMLocation(); - var prevLocation = history.location; - if (!forceNextPop && locationsAreEqual(prevLocation, location)) return; // A hashchange doesn't always == location change. + var _this = _possibleConstructorReturn(this, (Article.__proto__ || Object.getPrototypeOf(Article)).call(this, props)); - if (ignorePath === createPath(location)) return; // Ignore this change; we already setState in push/replace. + _this.state = { + preview: null, + smoothScroll: false, + fillblank: null, + bIsTimerOut: true + }; - ignorePath = null; - handlePop(location); - } - } + _this.scroll = _this.scroll.bind(_this); + _this.click = _this.click.bind(_this); + _this.contentMenu = _this.contentMenu.bind(_this); - function handlePop(location) { - if (forceNextPop) { - forceNextPop = false; - setState(); - } else { - var action = 'POP'; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ - action: action, - location: location - }); - } else { - revertPop(location); - } - }); - } + var timerObj; + var bIsMount = false; + return _this; } + //滚动到锚点 - function revertPop(fromLocation) { - var toLocation = history.location; // TODO: We could probably make this more reliable by - // keeping a list of paths we've seen in sessionStorage. - // Instead, we just default to 0 for paths we don't know. - var toIndex = allPaths.lastIndexOf(createPath(toLocation)); - if (toIndex === -1) toIndex = 0; - var fromIndex = allPaths.lastIndexOf(createPath(fromLocation)); - if (fromIndex === -1) fromIndex = 0; - var delta = toIndex - fromIndex; + _createClass(Article, [{ + key: 'scrollToHash', + value: function scrollToHash() { + var _this2 = this; - if (delta) { - forceNextPop = true; - go(delta); - } - } // Ensure the hash is encoded properly before doing anything else. + console.log("article scrollToHash ", this.hash); + var tempHash = this.hash; + var hashNode = document.getElementById(tempHash); + console.log("article scrollToHash temphash: " + tempHash + " " + hashNode); - var path = getHashPath(); - var encodedPath = encodePath(path); - if (path !== encodedPath) replaceHashPath(encodedPath); - var initialLocation = getDOMLocation(); - var allPaths = [createPath(initialLocation)]; // Public interface + if (this.state.preview != null) { + this.setState({ preview: null }); + } - function createHref(location) { - return '#' + encodePath(basename + createPath(location)); - } + if (hashNode) { + console.log(" article scrollToHash===============>", this.bIsMount); + clearTimeout(this.timerObj); + this.setState({ smoothScroll: true }); - function push(path, state) { - warning(state === undefined, 'Hash history cannot push state; it is ignored'); - var action = 'PUSH'; - var location = createLocation(path, undefined, undefined, history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var path = createPath(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; + var timeVar = 800; + if (this.bIsMount) { + timeVar = 3 * 1000; + this.bIsMount = false; + } - if (hashChanged) { - // We cannot tell if a hashchange was caused by a PUSH, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - pushHashPath(encodedPath); - var prevIndex = allPaths.lastIndexOf(createPath(history.location)); - var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); - nextPaths.push(path); - allPaths = nextPaths; - setState({ - action: action, - location: location + this.timerObj = setTimeout(function () { + _this2.setState({ smoothScroll: false }); + }, timeVar); + + (0, _smoothScrollIntoViewIfNeeded2.default)(hashNode, { behavior: 'smooth', block: 'start' }).then(function () { + + console.log(" scrollIntoView finish ===============>"); + + // this.setState({ smoothScroll: false }); + + //scrollIntoView函数存在异步,如果tempHash != this.hash时,说明存在异步操作,直接return. + if (tempHash != _this2.hash) return; + + console.log("scrollIntoView finish.."); + //find parent h3 title of h4 title + var hList = _reactDom2.default.findDOMNode(_this2).querySelectorAll('h2,h3,h4,h5'); + var currH3Hash = ''; + for (var i = 0; i < hList.length; i++) { + if (hList[i].tagName == 'H3') { + currH3Hash = hList[i].id; + } + if (tempHash == hList[i].id && (hList[i].tagName == 'H4' || hList[i].tagName == 'H5')) { + console.log("article: scroll hlist:" + hList[i].tagName + "," + hList[i].id); + console.log("currH3Hash:" + currH3Hash); + _this2.hash = currH3Hash; + _this2.props.setHash(currH3Hash); + _this2.props.setScroll(currH3Hash); + break; + } + } }); } else { - warning(false, 'Hash history cannot PUSH the same path; a new entry will not be added to the history stack'); - setState(); + if (this.props.hlist.length > 0) { + this.props.setHash(this.props.hlist[0].id); + } } - }); - } - - function replace(path, state) { - warning(state === undefined, 'Hash history cannot replace state; it is ignored'); - var action = 'REPLACE'; - var location = createLocation(path, undefined, undefined, history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var path = createPath(location); - var encodedPath = encodePath(basename + path); - var hashChanged = getHashPath() !== encodedPath; + } + }, { + key: 'componentWillMount', + value: function componentWillMount() { + console.log("article componentWillMount"); + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + console.log("article componentDidMount"); + this.bIsMount = true; + this.componentDidUpdate(); + } + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(nextProps, nextState) { + console.log("article shouldComponentUpdate====", this.hash, "prop hash:", this.props.hash); + // if (this.hash == this.props.hash) + // { + // return false; + // } + return true; + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + console.log("article componentWillReceiveProps nextfile", nextProps.nextProps, ' prop.file:', this.props.file); + if (nextProps.file != this.props.file) { + this.hash = ''; + this.load = false; + this.bIsMount = true; + } + } + }, { + key: 'componentWillUpdate', + value: function componentWillUpdate() { + console.log("article componentWillUpdate.."); + var alink_arr = document.getElementsByTagName('a'); + for (var i = 0; i < alink_arr.length; i++) { + alink_arr[i].onclick = function () { + global.isLinkClicked = true; + }; + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + var _this3 = this; - if (hashChanged) { - // We cannot tell if a hashchange was caused by a REPLACE, so we'd - // rather setState here and ignore the hashchange. The caveat here - // is that other hash histories in the page will consider it a POP. - ignorePath = path; - replaceHashPath(encodedPath); + console.log("article componentDidUpdate.." + this.hash + " props hash->" + this.props.hash); + if (this.hash != this.props.hash) { + this.hash = this.props.hash; + this.scrollToHash(); } + if (!this.load) { + var article = _reactDom2.default.findDOMNode(this); + var read = article.querySelector('#read'); + read.focus(); + var imgList = [].concat(_toConsumableArray(article.querySelectorAll('img'))); - var prevIndex = allPaths.indexOf(createPath(history.location)); - if (prevIndex !== -1) allPaths[prevIndex] = path; - setState({ - action: action, - location: location + var loadCount = 0; + var promiseAll = []; + imgList.map(function (el) { + promiseAll.push(new Promise(function (resolve, reject) { + el.onload = function () { + console.log("------img onload---------"); + resolve(el); + }; + el.onerror = function () { + console.log("------img onerror---------"); + resolve(el); + }; + })); + }); + Promise.all(promiseAll).then(function () { + // 全部图片加载完成 + _this3.load = true; + _this3.scrollToHash(); + var last = article.querySelector('#' + _this3.props.hlist[_this3.props.hlist.length - 1].id); + var fillblank = { + marginBottom: article.clientHeight - (read.clientHeight - last.offsetTop) + }; + _this3.setState({ + fillblank: fillblank + }); + }); + } + } + }, { + key: 'gethID', + value: function gethID(htext) { + var id = this.props.hlist[0].id; + console.log(this.props.hlist[0]); + var hlist = this.props.hlist.filter(function (h) { + return h.text == htext; }); - }); - } + if (hlist.length > 0) { + id = hlist[0].id; + } + console.log(htext, id); + return id; + } + }, { + key: 'handleWheelScroll', + value: function handleWheelScroll(e) { + global.isMouseScrollArticle = true; + } + }, { + key: 'handleKeyDown', + value: function handleKeyDown(e) { + if (38 == e.keyCode || 40 == e.keyCode) { + global.isMouseScrollArticle = true; + } + } + }, { + key: 'handleKeyUp', + value: function handleKeyUp(e) { + if (38 == e.keyCode || 40 == e.keyCode) { + global.isMouseScrollArticle = true; + } + } - function go(n) { - warning(canGoWithoutReload, 'Hash history go(n) causes a full page reload in this browser'); - globalHistory.go(n); - } + //滚动事件 - function goBack() { - go(-1); - } + }, { + key: 'scroll', + value: function scroll() { + // if (!this.load) { + // return; + // } + if (this.state.smoothScroll) { + return; + } + if (this.state.preview != null) { + this.setState({ preview: null }); + } + var hList = _reactDom2.default.findDOMNode(this).querySelectorAll('h2,h3'); + var aritleView = this.refs.articleView; - function goForward() { - go(1); - } + var hash = hList[0].id; + for (var i = 0; i < hList.length; i++) { + //console.log("article: scroll hlist:" + hList[i]); + //console.log("article: scroll hlist offset top:" + hList[i].getBoundingClientRect().top); + var articleTop = Math.abs(aritleView.getBoundingClientRect().top); + //console.log(hList[i].id + "," + hList[i].nodeName + ", hList[" + i + "].offsetTop" + hList[i].offsetTop + ", articleTop" + articleTop); + var offsetY = 10; + if (hList[i].nodeName == 'H2') { + offsetY = 10; + } else if (hList[i].nodeName == 'H3') { + offsetY = 30; + } + if (hList[i].offsetTop - offsetY >= articleTop) { + //console.log("article: scroll hlist offset top:" + hList[i].offsetTop); + break; + } + hash = hList[i].id; + } + console.log("article: scroll this.hash:" + this.hash + " hash:" + hash); + if (this.hash != hash) { + console.log('article: scroll hash update'); + this.hash = hash; + this.props.setHash(hash); + if (global.isMouseScrollArticle) { + this.props.setScroll(hash); + } + } + } - var listenerCount = 0; + //链接处理 - function checkDOMListeners(delta) { - listenerCount += delta; + }, { + key: 'click', + value: function click(e) { + console.log("article click"); + if (this.state.preview != null) { + this.setState({ preview: null }); + } + console.log("======>", e.target.nodeName); + switch (e.target.nodeName) { + case 'IMG': + e.preventDefault(); + var src = e.target.src; + if (src.indexOf('.svg') != -1) { + return; + } + console.log('imageViewer', src); + global.qtObjects.imageViewer.open(src); + return; + case 'A': + { + var dmanProtocol = 'dman://'; + var hashProtocol = '#'; + var httpProtocol = 'http'; + var _href = e.target.getAttribute('href'); + console.log("href:" + _href); + switch (0) { + case _href.indexOf(hashProtocol): + e.preventDefault(); + this.props.setHash(document.querySelector('[text="' + _href.slice(1) + '"]').id); + return; + case _href.indexOf(dmanProtocol): + e.preventDefault(); - if (listenerCount === 1 && delta === 1) { - window.addEventListener(HashChangeEvent$1, handleHashChange); - } else if (listenerCount === 0) { - window.removeEventListener(HashChangeEvent$1, handleHashChange); - } - } + var _href$slice$split = _href.slice(dmanProtocol.length + 1).split('#'), + _href$slice$split2 = _slicedToArray(_href$slice$split, 2), + appName = _href$slice$split2[0], + hash = _href$slice$split2[1]; - var isBlocked = false; + global.openTitle(appName, hash); + return; + case _href.indexOf(httpProtocol): + e.preventDefault(); + global.qtObjects.imageViewer.openHttpUrl(_href); + return; + } + } + //解决bug-46888, 当a标签内含有span标签,点击获取的是span标签,此时用其父元素来处理. + case 'SPAN': + e.preventDefault(); + var parNode = e.target.parentNode; + if (parNode.nodeName == 'A') { + var _dmanProtocol = 'dman://'; + var _hashProtocol = '#'; + var _httpProtocol = 'http'; + var hrefTmp = parNode.getAttribute('href'); + switch (0) { + case hrefTmp.indexOf(_hashProtocol): + e.preventDefault(); + this.props.setHash(document.querySelector('[text="' + href.slice(1) + '"]').id); + return; + case hrefTmp.indexOf(_dmanProtocol): + e.preventDefault(); - function block(prompt) { - if (prompt === void 0) { - prompt = false; + var _hrefTmp$slice$split = hrefTmp.slice(_dmanProtocol.length + 1).split('#'), + _hrefTmp$slice$split2 = _slicedToArray(_hrefTmp$slice$split, 2), + _appName = _hrefTmp$slice$split2[0], + _hash = _hrefTmp$slice$split2[1]; + + global.openTitle(_appName, _hash); + return; + case hrefTmp.indexOf(_httpProtocol): + e.preventDefault(); + global.qtObjects.imageViewer.openHttpUrl(hrefTmp); + return; + } + } + return; + } } - var unblock = transitionManager.setPrompt(prompt); + //右键菜单事件 - if (!isBlocked) { - checkDOMListeners(1); - isBlocked = true; + }, { + key: 'contentMenu', + value: function contentMenu(e) { + switch (e.target.nodeName) { + //当前为图片或者链接时,右键清除选中状态. + //当前为图片 + case 'IMG': + e.preventDefault(); + document.getSelection().empty(); + return; + //当前为链接 + case 'A': + e.preventDefault(); + document.getSelection().empty(); + return; + } } + }, { + key: 'render', + value: function render() { + var _this4 = this; - return function () { - if (isBlocked) { - isBlocked = false; - checkDOMListeners(-1); - } + console.log("article render...", this.state.preview); + return _react2.default.createElement( + 'div', + { id: 'article' }, + _react2.default.createElement( + 'div', + { id: 'article_bg' }, + _react2.default.createElement( + _scrollbar2.default, + { onScroll: this.scroll, + onWheel: function onWheel(e) { + return _this4.handleWheelScroll(e); + }, + onKeyUp: function onKeyUp(e) { + return _this4.handleKeyUp(e); + }, + onKeyDown: function onKeyDown(e) { + return _this4.handleKeyDown(e); + } }, + _react2.default.createElement('div', { + id: 'read', + ref: 'articleView', + className: 'read', + tabIndex: '-1', + dangerouslySetInnerHTML: { __html: this.props.html }, + style: this.state.fillblank, + onClick: this.click, + onContextMenu: this.contentMenu + }) + ) + ) + ); + } + }]); - return unblock(); - }; - } + return Article; +}(_react.Component); - function listen(listener) { - var unlisten = transitionManager.appendListener(listener); - checkDOMListeners(1); - return function () { - checkDOMListeners(-1); - unlisten(); - }; - } +exports.default = Article; - var history = { - length: globalHistory.length, - action: 'POP', - location: initialLocation, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - block: block, - listen: listen - }; - return history; -} +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./mdToHtml":5,"./scrollbar.jsx":7,"react":74,"react-dom":43,"smooth-scroll-into-view-if-needed":83}],3:[function(require,module,exports){ +(function (global){ +'use strict'; -function clamp(n, lowerBound, upperBound) { - return Math.min(Math.max(n, lowerBound), upperBound); -} -/** - * Creates a history object that stores locations in memory. - */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); -function createMemoryHistory(props) { - if (props === void 0) { - props = {}; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var _props = props, - getUserConfirmation = _props.getUserConfirmation, - _props$initialEntries = _props.initialEntries, - initialEntries = _props$initialEntries === void 0 ? ['/'] : _props$initialEntries, - _props$initialIndex = _props.initialIndex, - initialIndex = _props$initialIndex === void 0 ? 0 : _props$initialIndex, - _props$keyLength = _props.keyLength, - keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength; - var transitionManager = createTransitionManager(); +var _react = require('react'); - function setState(nextState) { - _extends(history, nextState); +var _react2 = _interopRequireDefault(_react); - history.length = history.entries.length; - transitionManager.notifyListeners(history.location, history.action); - } +var _reactRouterDom = require('react-router-dom'); - function createKey() { - return Math.random().toString(36).substr(2, keyLength); - } +var _reactDom = require('react-dom'); - var index = clamp(initialIndex, 0, initialEntries.length - 1); - var entries = initialEntries.map(function (entry) { - return typeof entry === 'string' ? createLocation(entry, undefined, createKey()) : createLocation(entry, undefined, entry.key || createKey()); - }); // Public interface +var _reactDom2 = _interopRequireDefault(_reactDom); - var createHref = createPath; +var _jquery = require('jquery'); - function push(path, state) { - warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - var action = 'PUSH'; - var location = createLocation(path, state, createKey(), history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - var prevIndex = history.index; - var nextIndex = prevIndex + 1; - var nextEntries = history.entries.slice(0); +var _jquery2 = _interopRequireDefault(_jquery); - if (nextEntries.length > nextIndex) { - nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location); - } else { - nextEntries.push(location); - } +var _scrollbar = require('./scrollbar.jsx'); - setState({ - action: action, - location: location, - index: nextIndex, - entries: nextEntries - }); - }); - } +var _scrollbar2 = _interopRequireDefault(_scrollbar); - function replace(path, state) { - warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); - var action = 'REPLACE'; - var location = createLocation(path, state, createKey(), history.location); - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (!ok) return; - history.entries[history.index] = location; - setState({ - action: action, - location: location - }); - }); - } - - function go(n) { - var nextIndex = clamp(history.index + n, 0, history.entries.length - 1); - var action = 'POP'; - var location = history.entries[nextIndex]; - transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { - if (ok) { - setState({ - action: action, - location: location, - index: nextIndex - }); - } else { - // Mimic the behavior of DOM histories by - // causing a render after a cancelled POP. - setState(); - } - }); - } - - function goBack() { - go(-1); - } +var _os = require('os'); - function goForward() { - go(1); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - function canGo(n) { - var nextIndex = history.index + n; - return nextIndex >= 0 && nextIndex < history.entries.length; - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - function block(prompt) { - if (prompt === void 0) { - prompt = false; - } +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - return transitionManager.setPrompt(prompt); - } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - function listen(listener) { - return transitionManager.appendListener(listener); - } +global.show = false; - var history = { - length: entries.length, - action: 'POP', - location: entries[index], - index: index, - entries: entries, - createHref: createHref, - push: push, - replace: replace, - go: go, - goBack: goBack, - goForward: goForward, - canGo: canGo, - block: block, - listen: listen - }; - return history; -} +var Item = function (_Component) { + _inherits(Item, _Component); -exports.createBrowserHistory = createBrowserHistory; -exports.createHashHistory = createHashHistory; -exports.createMemoryHistory = createMemoryHistory; -exports.createLocation = createLocation; -exports.locationsAreEqual = locationsAreEqual; -exports.parsePath = parsePath; -exports.createPath = createPath; + function Item(props) { + _classCallCheck(this, Item); -},{"resolve-pathname":67,"tiny-invariant":76,"tiny-warning":77,"value-equal":81}],5:[function(require,module,exports){ -"use strict";function _interopDefault(n){return n&&"object"==typeof n&&"default"in n?n.default:n}Object.defineProperty(exports,"__esModule",{value:!0});var resolvePathname=_interopDefault(require("resolve-pathname")),valueEqual=_interopDefault(require("value-equal"));require("tiny-warning");var invariant=_interopDefault(require("tiny-invariant"));function _extends(){return(_extends=Object.assign||function(n){for(var t=1;tt?e.splice(t,e.length-t,a):e.push(a),u({action:"PUSH",location:a,index:t,entries:e})}})},replace:function(n,t){var e="REPLACE",a=createLocation(n,t,f(),g.location);h.confirmTransitionTo(a,e,o,function(n){n&&(g.entries[g.index]=a,u({action:e,location:a}))})},go:p,goBack:function(){p(-1)},goForward:function(){p(1)},canGo:function(n){var t=g.index+n;return 0<=t&&t elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; +var Index = function (_Component4) { + _inherits(Index, _Component4); + function Index(props) { + _classCallCheck(this, Index); -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; + var _this9 = _possibleConstructorReturn(this, (Index.__proto__ || Object.getPrototypeOf(Index)).call(this, props)); + _this9.state = { + appList: [], + openedAppList: [], + videoList: [] + }; -var document = window.document; + global.qtObjects.manual.getSystemManualList(function (appList) { + console.log("======>applist===>", appList); + _this9.setState({ appList: appList }); + }); + global.qtObjects.manual.getUsedAppList(function (openedAppList) { + return _this9.setState({ openedAppList: openedAppList }); + }); + global.qtObjects.manual.getVideoGuideInfo(function (_videoList) { + console.log("======>videoList===>", _videoList); + _this9.setState({ videoList: _videoList }); + }); + return _this9; + } - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; + _createClass(Index, [{ + key: 'bIsBeOpen', + value: function bIsBeOpen(app) { + if (this.state.openedAppList.indexOf(app) != -1) { + return true; + } + return false; + } + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(nextProps, nextState) { + var _this10 = this; - function DOMEval( code, node, doc ) { - doc = doc || document; + console.log("index shouldcomponentupdate"); + if (global.bIsReload) { + global.qtObjects.manual.getSystemManualList(function (appList) { + _this10.setState({ appList: appList }); + }); - var i, val, - script = doc.createElement( "script" ); + global.qtObjects.manual.getUsedAppList(function (openedAppList) { + return _this10.setState({ openedAppList: openedAppList }); + }); + global.bIsReload = false; + } + return true; + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + _reactDom2.default.findDOMNode(this).querySelector('#index').focus(); + } + }, { + key: 'render', + value: function render() { + var _this11 = this; - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { + console.log('index render...'); - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } + var videoSoft = JSON.parse(JSON.stringify(this.state.videoList)); + var sysSoft = ['dde'].filter(function (appName) { + return _this11.state.appList.indexOf(appName) != -1; + }); + var appSoft = JSON.parse(JSON.stringify(this.state.appList)); //使用数据副本 + var startSoft = []; + var index = appSoft.indexOf("dde"); + if (index !== -1) { + appSoft.splice(index, 1); + } + index = appSoft.indexOf("learn-basic-operations"); + if (index !== -1) { + startSoft.push(appSoft[index]); + appSoft.splice(index, 1); + } + index = appSoft.indexOf("common-application-libraries"); + if (index !== -1) { + startSoft.push(appSoft[index]); + appSoft.splice(index, 1); + } -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module + return _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + _scrollbar2.default, + null, + _react2.default.createElement( + 'div', + { id: 'index', tabIndex: '-1' }, + startSoft.length == 2 && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'h2', + null, + global.i18n['QuickStart'] + ), + _react2.default.createElement( + 'div', + { className: 'items' }, + _react2.default.createElement(QuickStartItem, { appName: 'learn-basic-operations' }), + _react2.default.createElement(QuickStartItem, { appName: 'common-application-libraries' }) + ) + ), + videoSoft.length > 0 && _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'h2', + null, + global.i18n['VideoGuide'], + _react2.default.createElement( + 'span', + { id: 'righttext', onClick: function onClick() { + global.qtObjects.manual.openVideo(''); + } }, + global.i18n['ViewAll'] + ) + ), + _react2.default.createElement( + 'div', + { className: 'items' }, + _react2.default.createElement('div', { className: 'tooltip-wp' }), + videoSoft.map(function (item, index) { + return _react2.default.createElement(VideoGuideItem, { key: index, index: index, title: item.name, cover: item.cover, url: item.url }); + }) + ) + ), + _react2.default.createElement( + 'h2', + null, + global.i18n['System'] + ), + sysSoft.length > 0 && _react2.default.createElement( + 'div', + { className: 'appitems' }, + sysSoft.map(function (appName) { + return _react2.default.createElement(Item, { key: appName, appName: appName, isOpened: _this11.bIsBeOpen(appName), type: "system" }); + }) + ), + _react2.default.createElement( + 'h2', + null, + global.i18n['Applications'] + ), + _react2.default.createElement( + 'div', + { className: 'appitems' }, + appSoft.map(function (appName) { + return _react2.default.createElement(Item, { key: appName, appName: appName, isOpened: _this11.bIsBeOpen(appName), type: "application" }); + }) + ) + ) + ) + ); + } + }]); + return Index; +}(_react.Component); +exports.default = Index; -var - version = "3.5.1", +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./scrollbar.jsx":7,"jquery":17,"os":20,"react":74,"react-dom":43,"react-router-dom":59}],4:[function(require,module,exports){ +(function (global){ +'use strict'; - // Define a local copy of jQuery - jQuery = function( selector, context ) { +Object.defineProperty(exports, "__esModule", { + value: true +}); - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -jQuery.fn = jQuery.prototype = { +var _react = require('react'); - // The current version of jQuery being used - jquery: version, +var _react2 = _interopRequireDefault(_react); - constructor: jQuery, +var _jquery = require('jquery'); - // The default length of a jQuery object is 0 - length: 0, +var _jquery2 = _interopRequireDefault(_jquery); - toArray: function() { - return slice.call( this ); - }, +var _nav = require('./nav.jsx'); - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { +var _nav2 = _interopRequireDefault(_nav); - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } +var _article = require('./article.jsx'); - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, +var _article2 = _interopRequireDefault(_article); - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { +var _mdToHtml = require('./mdToHtml.js'); - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); +var _mdToHtml2 = _interopRequireDefault(_mdToHtml); - // Add the old object onto the stack (as a reference) - ret.prevObject = this; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // Return the newly-formed element set - return ret; - }, +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, +var Main = function (_Component) { + _inherits(Main, _Component); - first: function() { - return this.eq( 0 ); - }, + function Main(props) { + _classCallCheck(this, Main); - last: function() { - return this.eq( -1 ); - }, + var _this = _possibleConstructorReturn(this, (Main.__proto__ || Object.getPrototypeOf(Main)).call(this, props)); - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, + _this.state = { + init: false, + bTest: true + }; + var _this$props$match$par = _this.props.match.params, + file = _this$props$match$par.file, + hash = _this$props$match$par.hash, + key = _this$props$match$par.key; - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, + console.log("main constructor..."); + _this.init(decodeURIComponent(file), hash ? decodeURIComponent(hash) : null, key); + var showFloatTimer = null; - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, + _this.setHash = _this.setHash.bind(_this); + _this.setScroll = _this.setScroll.bind(_this); + return _this; + } - end: function() { - return this.prevObject || this.constructor(); - }, + _createClass(Main, [{ + key: 'init', + value: function init(file, hash) { + var _this2 = this; - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; + var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; + if (key !== '%') { + key = decodeURIComponent(key); + } + console.log("main init==>file:", file, " hash:", hash, " key:", key); - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; + global.hash = hash; + var filePath = file; - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } + var myPromise = new Promise(function (resolve, reject) { + if (filePath.indexOf('/') == -1) { + global.qtObjects.manual.appToPath(file, function (filepath) { + filePath = filepath; + resolve(); + }); + } else { + resolve(); + } + }); + myPromise.then(function () { + global.readFile(filePath, function (data) { + console.log("main init===>readfile finish...", filePath); - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } + var _m2h = (0, _mdToHtml2.default)(filePath, data, key), + html = _m2h.html, + hlist = _m2h.hlist; - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } + _this2.setState({ + file: file, + html: html, + hlist: hlist, + init: true, + hash: hash ? hash : hlist[0].id + }); + }); + }); + } + }, { + key: 'setHash', + value: function setHash(hash) { + console.log("main setHash: " + hash); + if (global.isLinkClicked) { + console.log("main --setHash"); + global.hash = hash; + global.isLinkClicked = false; + } + console.log("main*********setHash"); + this.setState({ hash: hash }); + } + }, { + key: 'setScroll', + value: function setScroll(hash) { + console.log("main setScroll:" + hash); + global.hash = hash; + this.setState({ hash: hash }); + } - for ( ; i < length; i++ ) { + //处理Nav类的Over Out Move事件,自定义Title框 - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { + }, { + key: 'handleNavOver', + value: function handleNavOver(e) { + var value = e.currentTarget.innerHTML; + clearTimeout(this.showFloatTimer); + this.showFloatTimer = setTimeout(function () { + (0, _jquery2.default)('.tooltip-wp').attr('data-title', value); //动态设置data-title属性 + (0, _jquery2.default)('.tooltip-wp').fadeIn(200); //浮动框淡出 + }, 300); + } + }, { + key: 'handleNavOut', + value: function handleNavOut(e) { + clearTimeout(this.showFloatTimer); + (0, _jquery2.default)('.tooltip-wp').hide(); + } + }, { + key: 'handleNavMove', + value: function handleNavMove(e) { + var xPage = e.pageX + 10; + var yPage = e.pageY; + console.log("...", document.body.scrollHeight); + if (yPage + 40 > document.body.scrollHeight) { + yPage = document.body.scrollHeight - 40; + } + setTimeout(function () { + (0, _jquery2.default)('.tooltip-wp').css({ + 'top': yPage + 'px', + 'left': xPage + 'px' + }); + }, 150); + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + var _this3 = this; - // Extend the base object - for ( name in options ) { - copy = options[ name ]; + var _nextProps$match$para = nextProps.match.params, + file = _nextProps$match$para.file, + hash = _nextProps$match$para.hash, + key = _nextProps$match$para.key; - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; + if (global.bIsReload) { + var parentText; + var hashText = ''; - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; + for (var i = 0; i < this.state.hlist.length; i++) { + var h = this.state.hlist[i]; + if (h.type == 'h2') { + parentText = h.text; + } + if (h.id == this.state.hash) { + hashText = h.text; + break; + } + } - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); + var filePath; - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } + // if (this.state.file == "dde") + // { + // filePath = `${global.path}/system/${this.state.file}/${global.lang}/index.md`; + // } + // else{ + // filePath = `${global.path}/application/${this.state.file}/${global.lang}/index.md`; + // } + var myPromise = new Promise(function (resolve, reject) { + global.qtObjects.manual.appToPath(file, function (filepath) { + filePath = filepath; + resolve(); + }); + }); + myPromise.then(function () { + global.readFile(filePath, function (data) { + console.log("main init===>readfile finish...", filePath); - // Return the modified object - return target; -}; + var _m2h2 = (0, _mdToHtml2.default)(filePath, data, key), + html = _m2h2.html, + hlist = _m2h2.hlist; -jQuery.extend( { + var newParentHash = 'h1'; + var newChildHash; + var curHash; - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + for (var i = 0; i < hlist.length; i++) { + var h = hlist[i]; + if (h.text == parentText) { + newParentHash = h.id; + } else if (h.text == hashText) { + newChildHash = h.id; + break; + } + } - // Assume jQuery is ready without the ready module - isReady: true, + if (newChildHash) { + curHash = newChildHash; + } else { + curHash = newParentHash; + } + console.log('================>', curHash); - error: function( msg ) { - throw new Error( msg ); - }, + _this3.init(decodeURIComponent(file), curHash, key); + global.bIsReload = false; + }); + }); + } else { + console.log("main componentWillReceivePropss: " + file + " " + hash + " this.file:" + this.state.file + " this.hash" + this.state.hash + " key:", key); + //仅当页面文件发生改变时(文件改变或hash值发生改变),才刷新页面. + if (decodeURIComponent(file) != this.state.file || file == this.state.file && hash != this.state.hash) { + this.init(decodeURIComponent(file), hash ? decodeURIComponent(hash) : null, key); + } + } + } + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(nextProps, nextState) { + console.log("main shouldComponentUpdate===="); + return true; + } + }, { + key: 'componentWillUpdate', + value: function componentWillUpdate() { + console.log("main componentWillUpdate.."); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + global.hash = ''; + global.isMouseClickNav = false; + global.isMouseScrollArticle = false; + global.isLinkClicked = false; + } + }, { + key: 'render', + value: function render() { + var _this4 = this; - noop: function() {}, + console.log("main render....hash:", this.state.hash); + console.log("main render....hList:", this.state.hlist); - isPlainObject: function( obj ) { - var proto, Ctor; + return this.state.init && _react2.default.createElement( + 'div', + { id: 'main' }, + _react2.default.createElement(_nav2.default, { + hlist: this.state.hlist, + hash: this.state.hash, + setHash: this.setHash, + onNavOver: function onNavOver(e) { + return _this4.handleNavOver(e); + }, + onNavOut: function onNavOut(e) { + return _this4.handleNavOut(e); + }, + onNavMove: function onNavMove(e) { + return _this4.handleNavMove(e); + } + }), + _react2.default.createElement(_article2.default, { + file: this.props.match.params.file, + hlist: this.state.hlist, + html: this.state.html, + hash: this.state.hash, + setHash: this.setHash, + setScroll: this.setScroll + }), + _react2.default.createElement('div', { className: 'tooltip-wp' }) + ); + } + }]); - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } + return Main; +}(_react.Component); - proto = getProto( obj ); +exports.default = Main; - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./article.jsx":2,"./mdToHtml.js":5,"./nav.jsx":6,"jquery":17,"react":74}],5:[function(require,module,exports){ +'use strict'; - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, +Object.defineProperty(exports, "__esModule", { + value: true +}); - isEmptyObject: function( obj ) { - var name; +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - for ( name in obj ) { - return false; - } - return true; - }, +exports.default = function (mdFile, mdData) { + var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, + var hlist = []; + var info = {}; + var html = ''; - each: function( obj, callback ) { - var length, i = 0; + var path = mdFile.slice(0, mdFile.lastIndexOf('/') + 1); + var renderer = new _marked2.default.Renderer(); + var count = 0; + renderer.heading = function (text, level) { + var id = 'h' + count; + count++; + if (level == 1) { + var _text$split = text.split('|'), + _text$split2 = _slicedToArray(_text$split, 2), + title = _text$split2[0], + logo = _text$split2[1]; - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, + logo = path + logo; + console.log(logo); + info = { title: title, logo: logo }; + return ''; + } + if (level == 2) { + text = text.split('|')[0]; + } + var titlekey = text; + console.log("key======text========>", titlekey); + var type = 'h' + level; + if (level == 2) { + hlist.push({ id: id, text: text, type: type }); + } else if (level == 3) { + if (text.split('|').length > 1) { + titlekey = text.split('|')[1]; + text = text.split('|')[0]; + //global.qtObjects.manual.LogPrint('start key:' + key); + //global.qtObjects.manual.LogPrint('start key:' + text); + } - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; + hlist.push({ id: id, text: text, type: type }); + } - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } + return '<' + type + ' id="' + id + '" text="' + titlekey + '">' + text + '\n'; + }; + console.log(path); + renderer.image = function (href, title, text) { + var hrefX2 = href; - return ret; - }, + // if (devicePixelRatio >= 5.0 && href.indexOf('.svg') == -1) { + // // global.qtObjects.manual.LogPrint('start hrefX2:' + hrefX2); + // let path = href.split('.'); + // let ext = path.pop(); + // // global.qtObjects.manual.LogPrint(path + '--' + ext); + // hrefX2 = `${path.join('.')}x2.${ext}`; + // // global.qtObjects.manual.LogPrint('end hrefX2:' + hrefX2); + // } - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, + return '' + text + ''; + }; - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; + html = (0, _marked2.default)(mdData, { renderer: renderer }).replace(/src="/g, '$&' + path); + console.log("-----------------------------------"); + if (key != '') { + console.log("regexp==============>", key); + //将'=-='字符串 反向还原成'%' + key = key.replace(/=-=/g, '%'); - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } + console.log("regexp===>", key); - first.length = i; + //将关键字转义 + var keyTemp = new RegExp(escapeRegExp(key), 'gi'); - return first; - }, + // key = re; + var finder = new RegExp(">.*?<", 'g'); // 提取位于标签内的文本,避免误操作 class、id 等 + html = html.replace(finder, function (matched) { + return matched.replace(new RegExp(keyTemp, 'gi'), "$&"); + }); + } - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; + return { html: html, hlist: hlist, info: info }; +}; - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } +var _marked = require('marked'); - return matches; - }, +var _marked2 = _interopRequireDefault(_marked); - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); +//转义特定字符 +function escapeRegExp(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +}; - if ( value != null ) { - ret.push( value ); - } - } +},{"marked":18}],6:[function(require,module,exports){ +(function (global){ +'use strict'; - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); +Object.defineProperty(exports, "__esModule", { + value: true +}); - if ( value != null ) { - ret.push( value ); - } - } - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - // Flatten any nested arrays - return flat( ret ); - }, +var _react = require('react'); - // A global GUID counter for objects - guid: 1, +var _react2 = _interopRequireDefault(_react); - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); +var _reactDom = require('react-dom'); -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} +var _reactDom2 = _interopRequireDefault(_reactDom); -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); +var _reactRouterDom = require('react-router-dom'); -function isArrayLike( obj ) { +var _scrollbar = require('./scrollbar.jsx'); - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); +var _scrollbar2 = _interopRequireDefault(_scrollbar); - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.5 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2020-03-14 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, +var Nav = function (_Component) { + _inherits(Nav, _Component); - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", + function Nav(props) { + _classCallCheck(this, Nav); - // Regular expressions + var _this = _possibleConstructorReturn(this, (Nav.__proto__ || Object.getPrototypeOf(Nav)).call(this, props)); - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", + _this.contentMenu = _this.contentMenu.bind(_this); + return _this; + } - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + _createClass(Nav, [{ + key: 'componentWillMount', + value: function componentWillMount() { + console.log("nav componentWillMount"); + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + console.log("nav componentDidMount"); + document.getElementById('article').style.marginLeft = _reactDom2.default.findDOMNode(this).clientWidth; + this.componentDidUpdate(); + } + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(newProps, newState) { + console.log("nav shouldComponentUpdate newProps:" + newProps.hash + " global hash:" + global.hash); - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + if ('' == global.hash) { + return true; + } - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + + if ('POP' == global.lastAction) { + return true; + } + //why........ + if (newProps.hash != global.hash) { + return false; + } + return true; + } + }, { + key: 'componentWillUpdate', + value: function componentWillUpdate() { + console.log("nav componentWillUpdate"); + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + console.log("nav componentDidUpdate"); + var hashDOM = _reactDom2.default.findDOMNode(this).querySelector('.hash'); + if (hashDOM == null) { + return; + } + if (hashDOM.getAttribute('cid') == this.props.hlist[0].id) { + document.getElementById('backHome').scrollIntoViewIfNeeded(false); + return; + } + hashDOM.scrollIntoViewIfNeeded(false); + } + }, { + key: 'click', + value: function click(e) { + var cid = e.target.getAttribute('cid'); + if (cid) { + console.log('nav 搜索结果', cid); + global.hash = cid; + global.isMouseClickNav = true; + global.isMouseScrollArticle = false; + this.props.setHash(cid); + } + } + }, { + key: 'wheel', + value: function wheel(e) { + var nav = _reactDom2.default.findDOMNode(this); + if (e.deltaY > 0) { + if (e.deltaY > 0 && nav.scrollHeight == nav.clientHeight + nav.scrollTop) { + e.preventDefault(); + } else if (e.deltaY < 0 && nav.scrollTop == 0) { + e.preventDefault(); + } + } + } - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", + //右键菜单事件,去除选中状态 - pseudos = ":(" + identifier + ")(?:\\((" + + }, { + key: 'contentMenu', + value: function contentMenu(e) { + e.preventDefault(); + document.getSelection().empty(); + } + }, { + key: 'render', + value: function render() { + var _this2 = this; - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + console.log("nav render...", this.props.hlist.length); + var maxWidth = 0; + var c = 0; - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + if (this.props.hlist.length > 0) { + var max = this.props.hlist[0]; + this.props.hlist.map(function (h) { + if (max.text.length < h.text.length) { + max = h; + } + }); + maxWidth = max.text.length; + if (global.lang === 'zh_CN') { + if (maxWidth <= 6) { + c = 3; + } else { + c = 1; + } + maxWidth *= 18; + } else { + if (maxWidth <= 20) { + c = 2; + } + maxWidth *= 9; + } + } - // 3. anything else (capture 2) - ".*" + - ")\\)|)", + return _react2.default.createElement( + 'div', + { + id: 'nav', + lang: global.lang, + onMouseDown: function onMouseDown(e) { + return _this2.click(e); + }, + onContextMenu: this.contentMenu + // style={{ + // width: `calc(${maxWidth}px + ${c}rem)` + // }} + }, + _react2.default.createElement( + _scrollbar2.default, + null, + _react2.default.createElement( + 'div', + { + type: 'h2', + id: 'backHome', + className: 'h', + onClick: function onClick() { + return global.backHome(); + } + }, + global.i18n['ToIndexPage'] + ), + this.props.hlist.map(function (h) { + return _react2.default.createElement( + 'div', + { + key: h.id, + cid: h.id, + type: h.type, + className: _this2.props.hash == h.id ? 'h hash' : 'h', + onMouseOver: function onMouseOver(e) { + return _this2.props.onNavOver(e); + }, + onMouseOut: function onMouseOut(e) { + return _this2.props.onNavOut(e); + }, + onMouseMove: function onMouseMove(e) { + return _this2.props.onNavMove(e); + } + }, + h.text + ); + }) + ) + ); + } + }]); - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), + return Nav; +}(_react.Component); - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), +exports.default = Nav; - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./scrollbar.jsx":7,"react":74,"react-dom":43,"react-router-dom":59}],7:[function(require,module,exports){ +'use strict'; - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), +Object.defineProperty(exports, "__esModule", { + value: true +}); - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, +exports.default = function (props) { + return _react2.default.createElement( + _reactCustomScrollbars.Scrollbars, + _extends({}, props, { className: 'scrollbar', autoHide: true, renderTrackHorizontal: renderScrollBarTrackHorizontal, autoHideTimeout: 800 }), + props.children + ); +}; - rnative = /^[^{]+\{\s*\[native \w/, +var _react = require('react'); - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, +var _react2 = _interopRequireDefault(_react); - rsibling = /[+~]/, +var _reactCustomScrollbars = require('react-custom-scrollbars'); - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return nonHex ? +function renderScrollBarTrackHorizontal(props) { + return _react2.default.createElement('span', null); +} - // Strip the backslash prefix from a non-hex escape sequence - nonHex : +},{"react":74,"react-custom-scrollbars":35}],8:[function(require,module,exports){ +(function (global){ +'use strict'; - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, +Object.defineProperty(exports, "__esModule", { + value: true +}); - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } +var _react = require('react'); - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, +var _react2 = _interopRequireDefault(_react); - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, +var _reactDom = require('react-dom'); - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); +var _reactDom2 = _interopRequireDefault(_reactDom); -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); +var _propTypes = require('prop-types'); - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? +var _propTypes2 = _interopRequireDefault(_propTypes); - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : +var _scrollbar = require('./scrollbar.jsx'); - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; +var _scrollbar2 = _interopRequireDefault(_scrollbar); - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} +var _reactRouterDom = require('react-router-dom'); -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - results = results || []; +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later - return results; - } +var Items = function (_Component) { + _inherits(Items, _Component); - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; + function Items(props) { + _classCallCheck(this, Items); - if ( documentIsHTML ) { + var _this = _possibleConstructorReturn(this, (Items.__proto__ || Object.getPrototypeOf(Items)).call(this, props)); - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { + _this.state = { + title: '', + logo: '', + show: false + }; + var path = props.file.slice(0, props.file.lastIndexOf('/') + 1); + console.log("========path======>", path); + global.readFile(props.file, function (data) { + var _data$substr$split = data.substr('# '.length, data.indexOf('\n')).split('|'), + _data$substr$split2 = _slicedToArray(_data$substr$split, 2), + title = _data$substr$split2[0], + desktopname = _data$substr$split2[1]; - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { + global.qtObjects.manual.getAppIconPath(desktopname, function (logopath) { + //按约定会在图标主题放置dde图标,但为保险起见如果未获取到则取common中的 + //global.qtObjects.manual.LogPrint("sbkebcmj"); + if (logopath == '' && desktopname == "dde") { + logopath = path + '../common/dde.svg'; + } + if (logopath == '' && desktopname == "learn-basic-operations") { + logopath = path + '../common/learn_basic_operations.svg'; + } + if (logopath == '' && desktopname == "common-application-libraries") { + logopath = path + '../common/common_application_libraries.svg'; + } + // console.log("logopath: ", logopath); + _this.setState({ logo: logopath }); + }); - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } + global.qtObjects.manual.getLocalAppName(desktopname, function (appname) { + _this.setState({ title: appname }); + }); + _this.setState({ show: true }); + }); + return _this; + } - // Element context - } else { + //转义特定字符 - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - results.push( elem ); - return results; - } - } + _createClass(Items, [{ + key: 'escapeRegExp', + value: function escapeRegExp(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + }, { + key: 'render', + value: function render() { + var _this2 = this; - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; + var resultList = []; - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { + //将关键字转义 + var keyTemp = this.props.keyword; + if (this.props.keyword !== '%') { + keyTemp = this.props.keyword; + } - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } + // let keyTemp = decodeURIComponent(this.props.keyword) + var re = new RegExp(this.escapeRegExp(keyTemp), 'gi'); - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + var cTitle = _react2.default.createElement('span', { + className: 'resulttitle', + dangerouslySetInnerHTML: { + __html: this.state.title.replace(re, "$&") + } + }); - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + var _loop = function _loop(i) { + if (_this2.props.idList[i] == 'h0') { + return 'continue'; + } - newSelector = selector; - newContext = context; + var c = _react2.default.createElement( + 'div', + { className: 'item', key: i, onClick: function onClick() { + return global.open(_this2.props.file, _this2.props.idList[i], _this2.props.keyword); + } }, + _react2.default.createElement('div', { + className: 'itemTitle', + dangerouslySetInnerHTML: { + __html: _this2.props.titleList[i].replace(re, "$&") + } + }), + _react2.default.createElement('div', { + className: 'context', + dangerouslySetInnerHTML: { + __html: _this2.props.contentList[i] + // __html:contentTrans + } + }) + ); + if (resultList.length < 5) { + resultList.push(c); + } + }; - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + for (var i = 0; i < this.props.idList.length; i++) { + var _ret = _loop(i); - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; + if (_ret === 'continue') continue; + } + var sresultnum; + if (this.props.idList.length > 1) sresultnum = this.props.idList.length + global.i18n['ResultNumSuffixs'];else sresultnum = this.props.idList.length + global.i18n['ResultNumSuffix']; - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { + return this.state.show && _react2.default.createElement( + 'div', + { className: 'items' }, + _react2.default.createElement( + 'div', + { className: 'itemsTitle', onClick: function onClick() { + return global.open(_this2.props.file, '', _this2.props.keyword); + } }, + _react2.default.createElement('img', { src: this.state.logo }), + cTitle, + _react2.default.createElement( + 'span', + { className: 'resultnum' }, + sresultnum + ) + ), + resultList + ); + } + }]); - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } + return Items; +}(_react.Component); - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } +var VideoItem = function (_Component2) { + _inherits(VideoItem, _Component2); - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } + function VideoItem(props) { + _classCallCheck(this, VideoItem); - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} + var _this3 = _possibleConstructorReturn(this, (VideoItem.__proto__ || Object.getPrototypeOf(VideoItem)).call(this, props)); -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; + _this3.state = { + logo: './resource/videos/video.svg', + videoList: props.titleList, + urlList: props.contentList, + show: false + }; + return _this3; + } - function cache( key, value ) { + _createClass(VideoItem, [{ + key: 'render', + value: function render() { + var _this4 = this; - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { + var resultList = []; - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} + var _loop2 = function _loop2(i) { + var c = _react2.default.createElement( + 'div', + { id: 'item' }, + _react2.default.createElement('img', { src: _this4.state.logo }), + _react2.default.createElement( + 'span', + { onClick: function onClick() { + global.qtObjects.manual.openVideo(_this4.state.urlList[i]); + } }, + _this4.state.videoList[i] + ) + ); -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} + if (resultList.length < 8) { + resultList.push(c); + } + }; -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); + for (var i = 0; i < this.state.videoList.length; i++) { + _loop2(i); + } - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { + return _react2.default.createElement( + 'div', + { className: 'videoItems', ref: 'topVideoItems' }, + resultList + ); + } + }]); - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } + return VideoItem; +}(_react.Component); - // release memory in IE - el = null; - } +function Mismatch(props) { + return _react2.default.createElement( + 'div', + { id: 'mismatch' }, + _react2.default.createElement( + 'div', + null, + _react2.default.createElement( + 'div', + { id: 'NoResult' }, + global.i18n['NoResult'] + ) + ) + ); } -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; +function VideoItems(props) { + var videoItemsRef = (0, _react.useRef)(null); + var logo = './resource/video.svg'; + var videoList = props.titleList; + var urlList = props.contentList; + var show = false; - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} + var resultList = []; -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; + var _loop3 = function _loop3(i) { + var c = _react2.default.createElement( + 'div', + { id: 'item', key: i }, + _react2.default.createElement('img', { src: logo }), + _react2.default.createElement( + 'span', + { onClick: function onClick() { + global.qtObjects.manual.openVideo(urlList[i]); + } }, + videoList[i] + ) + ); - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } + if (resultList.length < 8) { + resultList.push(c); + } + }; - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } + for (var i = 0; i < videoList.length; i++) { + _loop3(i); + } - return a ? 1 : -1; -} + (0, _react.useEffect)(function () { + var adjustOtherElements = function adjustOtherElements() { + var componentHeight = videoItemsRef.current.offsetHeight + 20; + setTimeout(function () { + document.getElementsByClassName("items")[0].style.marginTop = componentHeight + 'px'; + }, 50); + }; -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} + adjustOtherElements(); // 调整其他元素的位置 + }, []); -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; + function handleHover() { + console.log("hover....current:", videoItemsRef.current, " ", videoItemsRef.current.offsetHeight); + } + + return _react2.default.createElement( + 'div', + { className: 'videoItems', ref: videoItemsRef, onMouseEnter: handleHover }, + resultList + ); } -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { +var SearchPage = function (_Component3) { + _inherits(SearchPage, _Component3); - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { + function SearchPage(props, context) { + _classCallCheck(this, SearchPage); - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { + var _this5 = _possibleConstructorReturn(this, (SearchPage.__proto__ || Object.getPrototypeOf(SearchPage)).call(this, props, context)); - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { + console.log('search constructor:', _this5.context); + return _this5; + } - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } + _createClass(SearchPage, [{ + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + console.log("search componentWillReceiveProps..", this.context.searchResult); + console.log("search componentWillReceiveProps.."); + } + }, { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(nextProps, nextState) { + console.log("search shouldComponentUpdate.."); + return true; + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + _reactDom2.default.findDOMNode(this).querySelector('#search').focus(); + } + }, { + key: 'render', + value: function render() { + var _this6 = this; - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || + var c = null; + if (this.context.mismatch) { + c = _react2.default.createElement(Mismatch, { keyword: this.props.match.params.keyword }); + } else { + c = this.context.searchResult.map(function (result) { + return result.file === "video-guide" ? _react2.default.createElement(VideoItems, { + key: result.file, + file: result.file, + idList: result.idList, + titleList: result.titleList, + contentList: result.contentList, + keyword: _this6.props.match.params.keyword }) : _react2.default.createElement(Items, { + key: result.file, + file: result.file, + idList: result.idList, + titleList: result.titleList, + contentList: result.contentList, + keyword: _this6.props.match.params.keyword + }); + }); + } + return _react2.default.createElement( + _scrollbar2.default, + null, + _react2.default.createElement( + 'div', + { + id: 'search', + tabIndex: '-1' + }, + c + ) + ); + } + }]); - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } + return SearchPage; +}(_react.Component); - return elem.disabled === disabled; +exports.default = SearchPage; - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} +SearchPage.contextTypes = { + searchResult: _propTypes2.default.array, + mismatch: _propTypes2.default.bool +}; -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./scrollbar.jsx":7,"prop-types":29,"react":74,"react-dom":43,"react-router-dom":59}],9:[function(require,module,exports){ +/* The following list is defined in React's core */ +var IS_UNITLESS = { + animationIterationCount: true, + boxFlex: true, + boxFlexGroup: true, + boxOrdinalGroup: true, + columnCount: true, + flex: true, + flexGrow: true, + flexPositive: true, + flexShrink: true, + flexNegative: true, + flexOrder: true, + gridRow: true, + gridColumn: true, + fontWeight: true, + lineClamp: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + tabSize: true, + widows: true, + zIndex: true, + zoom: true, - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} + // SVG-related properties + fillOpacity: true, + stopOpacity: true, + strokeDashoffset: true, + strokeOpacity: true, + strokeWidth: true +}; -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; +module.exports = function(name, value) { + if(typeof value === 'number' && !IS_UNITLESS[ name ]) { + return value + 'px'; + } else { + return value; + } +}; +},{}],10:[function(require,module,exports){ +"use strict"; + +exports.__esModule = true; +exports.default = void 0; + +function isElement(el) { + return el != null && typeof el === 'object' && el.nodeType === 1; } -// Expose support vars for convenience -support = Sizzle.support = {}; +function canOverflow(overflow, skipOverflowHiddenElements) { + if (skipOverflowHiddenElements && overflow === 'hidden') { + return false; + } -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem.namespaceURI, - docElem = ( elem.ownerDocument || elem ).documentElement; + return overflow !== 'visible' && overflow !== 'clip'; +} - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; +function isScrollable(el, skipOverflowHiddenElements) { + if (el.clientHeight < el.scrollHeight || el.clientWidth < el.scrollWidth) { + var style = getComputedStyle(el, null); + return canOverflow(style.overflowY, skipOverflowHiddenElements) || canOverflow(style.overflowX, skipOverflowHiddenElements); + } -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; + return false; +} - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } +function alignNearest(scrollingEdgeStart, scrollingEdgeEnd, scrollingSize, scrollingBorderStart, scrollingBorderEnd, elementEdgeStart, elementEdgeEnd, elementSize) { + if (elementEdgeStart < scrollingEdgeStart && elementEdgeEnd > scrollingEdgeEnd || elementEdgeStart > scrollingEdgeStart && elementEdgeEnd < scrollingEdgeEnd) { + return 0; + } - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); + if (elementEdgeStart <= scrollingEdgeStart && elementSize <= scrollingSize || elementEdgeEnd >= scrollingEdgeEnd && elementSize >= scrollingSize) { + return elementEdgeStart - scrollingEdgeStart - scrollingBorderStart; + } - /* Attributes - ---------------------------------------------------------------------- */ + if (elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize || elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize) { + return elementEdgeEnd - scrollingEdgeEnd + scrollingBorderEnd; + } - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); + return 0; +} - /* getElement(s)By* - ---------------------------------------------------------------------- */ +var _default = function _default(target, options) { + var scrollMode = options.scrollMode, + block = options.block, + inline = options.inline, + boundary = options.boundary, + skipOverflowHiddenElements = options.skipOverflowHiddenElements; + var checkBoundary = typeof boundary === 'function' ? boundary : function (node) { + return node !== boundary; + }; - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); + if (!isElement(target)) { + throw new TypeError('Invalid target'); + } - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + var scrollingElement = document.scrollingElement || document.documentElement; + var frames = []; + var cursor = target; - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); + while (isElement(cursor) && checkBoundary(cursor)) { + cursor = cursor.parentNode; - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; + if (cursor === scrollingElement) { + frames.push(cursor); + break; + } - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); + if (cursor === document.body && isScrollable(cursor) && !isScrollable(document.documentElement)) { + continue; + } - if ( elem ) { + if (isScrollable(cursor, skipOverflowHiddenElements)) { + frames.push(cursor); + } + } - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } + var viewportWidth = window.visualViewport ? visualViewport.width : innerWidth; + var viewportHeight = window.visualViewport ? visualViewport.height : innerHeight; + var viewportX = window.scrollX || pageXOffset; + var viewportY = window.scrollY || pageYOffset; - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } + var _target$getBoundingCl = target.getBoundingClientRect(), + targetHeight = _target$getBoundingCl.height, + targetWidth = _target$getBoundingCl.width, + targetTop = _target$getBoundingCl.top, + targetRight = _target$getBoundingCl.right, + targetBottom = _target$getBoundingCl.bottom, + targetLeft = _target$getBoundingCl.left; - return []; - } - }; - } + var targetBlock = block === 'start' || block === 'nearest' ? targetTop : block === 'end' ? targetBottom : targetTop + targetHeight / 2; + var targetInline = inline === 'center' ? targetLeft + targetWidth / 2 : inline === 'end' ? targetRight : targetLeft; + var computations = []; - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : + for (var index = 0; index < frames.length; index++) { + var frame = frames[index]; - function( tag, context ) { - var elem, - tmp = [], - i = 0, + var _frame$getBoundingCli = frame.getBoundingClientRect(), + _height = _frame$getBoundingCli.height, + _width = _frame$getBoundingCli.width, + _top = _frame$getBoundingCli.top, + right = _frame$getBoundingCli.right, + bottom = _frame$getBoundingCli.bottom, + _left = _frame$getBoundingCli.left; - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); + if (scrollMode === 'if-needed' && targetTop >= 0 && targetLeft >= 0 && targetBottom <= viewportHeight && targetRight <= viewportWidth && targetTop >= _top && targetBottom <= bottom && targetLeft >= _left && targetRight <= right) { + return computations; + } - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } + var frameStyle = getComputedStyle(frame); + var borderLeft = parseInt(frameStyle.borderLeftWidth, 10); + var borderTop = parseInt(frameStyle.borderTopWidth, 10); + var borderRight = parseInt(frameStyle.borderRightWidth, 10); + var borderBottom = parseInt(frameStyle.borderBottomWidth, 10); + var blockScroll = 0; + var inlineScroll = 0; + var scrollbarWidth = 'offsetWidth' in frame ? frame.offsetWidth - frame.clientWidth - borderLeft - borderRight : 0; + var scrollbarHeight = 'offsetHeight' in frame ? frame.offsetHeight - frame.clientHeight - borderTop - borderBottom : 0; - return tmp; - } - return results; - }; + if (scrollingElement === frame) { + if (block === 'start') { + blockScroll = targetBlock; + } else if (block === 'end') { + blockScroll = targetBlock - viewportHeight; + } else if (block === 'nearest') { + blockScroll = alignNearest(viewportY, viewportY + viewportHeight, viewportHeight, borderTop, borderBottom, viewportY + targetBlock, viewportY + targetBlock + targetHeight, targetHeight); + } else { + blockScroll = targetBlock - viewportHeight / 2; + } - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; + if (inline === 'start') { + inlineScroll = targetInline; + } else if (inline === 'center') { + inlineScroll = targetInline - viewportWidth / 2; + } else if (inline === 'end') { + inlineScroll = targetInline - viewportWidth; + } else { + inlineScroll = alignNearest(viewportX, viewportX + viewportWidth, viewportWidth, borderLeft, borderRight, viewportX + targetInline, viewportX + targetInline + targetWidth, targetWidth); + } - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ + blockScroll = Math.max(0, blockScroll + viewportY); + inlineScroll = Math.max(0, inlineScroll + viewportX); + } else { + if (block === 'start') { + blockScroll = targetBlock - _top - borderTop; + } else if (block === 'end') { + blockScroll = targetBlock - bottom + borderBottom + scrollbarHeight; + } else if (block === 'nearest') { + blockScroll = alignNearest(_top, bottom, _height, borderTop, borderBottom + scrollbarHeight, targetBlock, targetBlock + targetHeight, targetHeight); + } else { + blockScroll = targetBlock - (_top + _height / 2) + scrollbarHeight / 2; + } - // QSA and matchesSelector support + if (inline === 'start') { + inlineScroll = targetInline - _left - borderLeft; + } else if (inline === 'center') { + inlineScroll = targetInline - (_left + _width / 2) + scrollbarWidth / 2; + } else if (inline === 'end') { + inlineScroll = targetInline - right + borderRight + scrollbarWidth; + } else { + inlineScroll = alignNearest(_left, right, _width, borderLeft, borderRight + scrollbarWidth, targetInline, targetInline + targetWidth, targetWidth); + } - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; + var scrollLeft = frame.scrollLeft, + scrollTop = frame.scrollTop; + blockScroll = Math.max(0, Math.min(scrollTop + blockScroll, frame.scrollHeight - _height + scrollbarHeight)); + inlineScroll = Math.max(0, Math.min(scrollLeft + inlineScroll, frame.scrollWidth - _width + scrollbarWidth)); + targetBlock += scrollTop - blockScroll; + targetInline += scrollLeft - inlineScroll; + } - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; + computations.push({ + el: frame, + top: blockScroll, + left: inlineScroll + }); + } - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "
" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } + return computations; +}; - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } +exports.default = _default; +module.exports = exports.default; +},{}],11:[function(require,module,exports){ +var prefix = require('prefix-style') +var toCamelCase = require('to-camel-case') +var cache = { 'float': 'cssFloat' } +var addPxToStyle = require('add-px-to-style') - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } +function style (element, property, value) { + var camel = cache[property] + if (typeof camel === 'undefined') { + camel = detect(property) + } - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } + // may be false if CSS prop is unsupported + if (camel) { + if (value === undefined) { + return element.style[camel] + } - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } + element.style[camel] = addPxToStyle(camel, value) + } +} - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } +function each (element, properties) { + for (var k in properties) { + if (properties.hasOwnProperty(k)) { + style(element, k, properties[k]) + } + } +} - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); +function detect (cssProp) { + var camel = toCamelCase(cssProp) + var result = prefix(camel) + cache[camel] = cache[cssProp] = cache[result] = result + return result +} - assert( function( el ) { - el.innerHTML = "" + - ""; +function set () { + if (arguments.length === 2) { + if (typeof arguments[1] === 'string') { + arguments[0].style.cssText = arguments[1] + } else { + each(arguments[0], arguments[1]) + } + } else { + style(arguments[0], arguments[1], arguments[2]) + } +} - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); +module.exports = set +module.exports.set = set - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } +module.exports.get = function (element, properties) { + if (Array.isArray(properties)) { + return properties.reduce(function (obj, prop) { + obj[prop] = style(element, prop || '') + return obj + }, {}) + } else { + return style(element, properties || '') + } +} - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } +},{"add-px-to-style":9,"prefix-style":24,"to-camel-case":86}],12:[function(require,module,exports){ +'use strict'; - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } +Object.defineProperty(exports, '__esModule', { value: true }); - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { +var resolvePathname = _interopDefault(require('resolve-pathname')); +var valueEqual = _interopDefault(require('value-equal')); +var warning = _interopDefault(require('tiny-warning')); +var invariant = _interopDefault(require('tiny-invariant')); - assert( function( el ) { +function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } + return target; + }; - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + return _extends.apply(this, arguments); +} - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); - } : - function( a, b ) { - if ( b ) { - while ( ( b = b.parentNode ) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; +function addLeadingSlash(path) { + return path.charAt(0) === '/' ? path : '/' + path; +} +function stripLeadingSlash(path) { + return path.charAt(0) === '/' ? path.substr(1) : path; +} +function hasBasename(path, prefix) { + return new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path); +} +function stripBasename(path, prefix) { + return hasBasename(path, prefix) ? path.substr(prefix.length) : path; +} +function stripTrailingSlash(path) { + return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path; +} +function parsePath(path) { + var pathname = path || '/'; + var search = ''; + var hash = ''; + var hashIndex = pathname.indexOf('#'); - /* Sorting - ---------------------------------------------------------------------- */ + if (hashIndex !== -1) { + hash = pathname.substr(hashIndex); + pathname = pathname.substr(0, hashIndex); + } - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { + var searchIndex = pathname.indexOf('?'); - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } + if (searchIndex !== -1) { + search = pathname.substr(searchIndex); + pathname = pathname.substr(0, searchIndex); + } - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } + return { + pathname: pathname, + search: search === '?' ? '' : search, + hash: hash === '#' ? '' : hash + }; +} +function createPath(location) { + var pathname = location.pathname, + search = location.search, + hash = location.hash; + var path = pathname || '/'; + if (search && search !== '?') path += search.charAt(0) === '?' ? search : "?" + search; + if (hash && hash !== '#') path += hash.charAt(0) === '#' ? hash : "#" + hash; + return path; +} - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : +function createLocation(path, state, key, currentLocation) { + var location; - // Otherwise we know they are disconnected - 1; + if (typeof path === 'string') { + // Two-arg form: push(path, state) + location = parsePath(path); + location.state = state; + } else { + // One-arg form: push(location) + location = _extends({}, path); + if (location.pathname === undefined) location.pathname = ''; - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + if (location.search) { + if (location.search.charAt(0) !== '?') location.search = '?' + location.search; + } else { + location.search = ''; + } - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a == document || a.ownerDocument == preferredDoc && - contains( preferredDoc, a ) ) { - return -1; - } + if (location.hash) { + if (location.hash.charAt(0) !== '#') location.hash = '#' + location.hash; + } else { + location.hash = ''; + } - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b == document || b.ownerDocument == preferredDoc && - contains( preferredDoc, b ) ) { - return 1; - } + if (state !== undefined && location.state === undefined) location.state = state; + } - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } + try { + location.pathname = decodeURI(location.pathname); + } catch (e) { + if (e instanceof URIError) { + throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' + 'This is likely caused by an invalid percent-encoding.'); + } else { + throw e; + } + } - return compare & 4 ? -1 : 1; - } : - function( a, b ) { + if (key) location.key = key; - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } + if (currentLocation) { + // Resolve incomplete/relative pathname relative to current location. + if (!location.pathname) { + location.pathname = currentLocation.pathname; + } else if (location.pathname.charAt(0) !== '/') { + location.pathname = resolvePathname(location.pathname, currentLocation.pathname); + } + } else { + // When there is no prior location and pathname is empty, set it to / + if (!location.pathname) { + location.pathname = '/'; + } + } - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; + return location; +} +function locationsAreEqual(a, b) { + return a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && a.key === b.key && valueEqual(a.state, b.state); +} - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { +function createTransitionManager() { + var prompt = null; - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - return a == document ? -1 : - b == document ? 1 : - /* eslint-enable eqeqeq */ - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; + function setPrompt(nextPrompt) { + warning(prompt == null, 'A history supports only one prompt at a time'); + prompt = nextPrompt; + return function () { + if (prompt === nextPrompt) prompt = null; + }; + } - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } + function confirmTransitionTo(location, action, getUserConfirmation, callback) { + // TODO: If another transition starts while we're still confirming + // the previous one, we may end up in a weird state. Figure out the + // best way to handle this. + if (prompt != null) { + var result = typeof prompt === 'function' ? prompt(location, action) : prompt; - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( ( cur = cur.parentNode ) ) { - ap.unshift( cur ); - } - cur = b; - while ( ( cur = cur.parentNode ) ) { - bp.unshift( cur ); - } + if (typeof result === 'string') { + if (typeof getUserConfirmation === 'function') { + getUserConfirmation(result, callback); + } else { + warning(false, 'A history needs a getUserConfirmation function in order to use a prompt message'); + callback(true); + } + } else { + // Return false from a transition hook to cancel the transition. + callback(result !== false); + } + } else { + callback(true); + } + } - // Walk down the tree looking for a discrepancy - while ( ap[ i ] === bp[ i ] ) { - i++; - } + var listeners = []; - return i ? + function appendListener(fn) { + var isActive = true; - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[ i ], bp[ i ] ) : + function listener() { + if (isActive) fn.apply(void 0, arguments); + } - // Otherwise nodes in our document sort first - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - ap[ i ] == preferredDoc ? -1 : - bp[ i ] == preferredDoc ? 1 : - /* eslint-enable eqeqeq */ - 0; - }; - - return document; -}; + listeners.push(listener); + return function () { + isActive = false; + listeners = listeners.filter(function (item) { + return item !== listener; + }); + }; + } -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; + function notifyListeners() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } -Sizzle.matchesSelector = function( elem, expr ) { - setDocument( elem ); + listeners.forEach(function (listener) { + return listener.apply(void 0, args); + }); + } - if ( support.matchesSelector && documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + return { + setPrompt: setPrompt, + confirmTransitionTo: confirmTransitionTo, + appendListener: appendListener, + notifyListeners: notifyListeners + }; +} - try { - var ret = matches.call( elem, expr ); +var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); +function getConfirmation(message, callback) { + callback(window.confirm(message)); // eslint-disable-line no-alert +} +/** + * Returns true if the HTML5 history API is supported. Taken from Modernizr. + * + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586 + */ - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || +function supportsHistory() { + var ua = window.navigator.userAgent; + if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; + return window.history && 'pushState' in window.history; +} +/** + * Returns true if browser fires popstate on hash change. + * IE10 and IE11 do not. + */ - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } +function supportsPopStateOnHashChange() { + return window.navigator.userAgent.indexOf('Trident') === -1; +} +/** + * Returns false if using go(n) with hash history causes a full page reload. + */ - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; +function supportsGoWithoutReloadUsingHash() { + return window.navigator.userAgent.indexOf('Firefox') === -1; +} +/** + * Returns true if a given popstate event is an extraneous WebKit event. + * Accounts for the fact that Chrome on iOS fires real popstate events + * containing undefined state when pressing the back button. + */ -Sizzle.contains = function( context, elem ) { +function isExtraneousPopstateEvent(event) { + event.state === undefined && navigator.userAgent.indexOf('CriOS') === -1; +} - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return contains( context, elem ); -}; +var PopStateEvent = 'popstate'; +var HashChangeEvent = 'hashchange'; -Sizzle.attr = function( elem, name ) { +function getHistoryState() { + try { + return window.history.state || {}; + } catch (e) { + // IE 11 sometimes throws when accessing window.history.state + // See https://github.com/ReactTraining/history/pull/289 + return {}; + } +} +/** + * Creates a history object that uses the HTML5 history API including + * pushState, replaceState, and the popstate event. + */ - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - var fn = Expr.attrHandle[ name.toLowerCase() ], +function createBrowserHistory(props) { + if (props === void 0) { + props = {}; + } - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; + !canUseDOM ? invariant(false, 'Browser history needs a DOM') : void 0; + var globalHistory = window.history; + var canUseHistory = supportsHistory(); + var needsHashChangeListener = !supportsPopStateOnHashChange(); + var _props = props, + _props$forceRefresh = _props.forceRefresh, + forceRefresh = _props$forceRefresh === void 0 ? false : _props$forceRefresh, + _props$getUserConfirm = _props.getUserConfirmation, + getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm, + _props$keyLength = _props.keyLength, + keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength; + var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : ''; - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; -}; + function getDOMLocation(historyState) { + var _ref = historyState || {}, + key = _ref.key, + state = _ref.state; -Sizzle.escape = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; + var _window$location = window.location, + pathname = _window$location.pathname, + search = _window$location.search, + hash = _window$location.hash; + var path = pathname + search + hash; + warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); + if (basename) path = stripBasename(path, basename); + return createLocation(path, state, key); + } -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; + function createKey() { + return Math.random().toString(36).substr(2, keyLength); + } -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; + var transitionManager = createTransitionManager(); - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); + function setState(nextState) { + _extends(history, nextState); - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } + history.length = globalHistory.length; + transitionManager.notifyListeners(history.location, history.action); + } - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; + function handlePopState(event) { + // Ignore extraneous popstate events in WebKit. + if (isExtraneousPopstateEvent(event)) return; + handlePop(getDOMLocation(event.state)); + } - return results; -}; + function handleHashChange() { + handlePop(getDOMLocation(getHistoryState())); + } -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; + var forceNextPop = false; - if ( !nodeType ) { + function handlePop(location) { + if (forceNextPop) { + forceNextPop = false; + setState(); + } else { + var action = 'POP'; + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (ok) { + setState({ + action: action, + location: location + }); + } else { + revertPop(location); + } + }); + } + } - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { + function revertPop(fromLocation) { + var toLocation = history.location; // TODO: We could probably make this more reliable by + // keeping a list of keys we've seen in sessionStorage. + // Instead, we just default to 0 for keys we don't know. - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + var toIndex = allKeys.indexOf(toLocation.key); + if (toIndex === -1) toIndex = 0; + var fromIndex = allKeys.indexOf(fromLocation.key); + if (fromIndex === -1) fromIndex = 0; + var delta = toIndex - fromIndex; - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { + if (delta) { + forceNextPop = true; + go(delta); + } + } - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } + var initialLocation = getDOMLocation(getHistoryState()); + var allKeys = [initialLocation.key]; // Public interface - // Do not include comment or processing instruction nodes + function createHref(location) { + return basename + createPath(location); + } - return ret; -}; + function push(path, state) { + warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + var action = 'PUSH'; + var location = createLocation(path, state, createKey(), history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + var href = createHref(location); + var key = location.key, + state = location.state; -Expr = Sizzle.selectors = { + if (canUseHistory) { + globalHistory.pushState({ + key: key, + state: state + }, null, href); - // Can be adjusted by the user - cacheLength: 50, + if (forceRefresh) { + window.location.href = href; + } else { + var prevIndex = allKeys.indexOf(history.location.key); + var nextKeys = allKeys.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); + nextKeys.push(location.key); + allKeys = nextKeys; + setState({ + action: action, + location: location + }); + } + } else { + warning(state === undefined, 'Browser history cannot push state in browsers that do not support HTML5 history'); + window.location.href = href; + } + }); + } - createPseudo: markFunction, + function replace(path, state) { + warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + var action = 'REPLACE'; + var location = createLocation(path, state, createKey(), history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + var href = createHref(location); + var key = location.key, + state = location.state; - match: matchExpr, + if (canUseHistory) { + globalHistory.replaceState({ + key: key, + state: state + }, null, href); - attrHandle: {}, + if (forceRefresh) { + window.location.replace(href); + } else { + var prevIndex = allKeys.indexOf(history.location.key); + if (prevIndex !== -1) allKeys[prevIndex] = location.key; + setState({ + action: action, + location: location + }); + } + } else { + warning(state === undefined, 'Browser history cannot replace state in browsers that do not support HTML5 history'); + window.location.replace(href); + } + }); + } - find: {}, + function go(n) { + globalHistory.go(n); + } - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, + function goBack() { + go(-1); + } - preFilter: { - "ATTR": function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + function goForward() { + go(1); + } - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || - match[ 5 ] || "" ).replace( runescape, funescape ); + var listenerCount = 0; - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } + function checkDOMListeners(delta) { + listenerCount += delta; - return match.slice( 0, 4 ); - }, + if (listenerCount === 1 && delta === 1) { + window.addEventListener(PopStateEvent, handlePopState); + if (needsHashChangeListener) window.addEventListener(HashChangeEvent, handleHashChange); + } else if (listenerCount === 0) { + window.removeEventListener(PopStateEvent, handlePopState); + if (needsHashChangeListener) window.removeEventListener(HashChangeEvent, handleHashChange); + } + } - "CHILD": function( match ) { + var isBlocked = false; - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); + function block(prompt) { + if (prompt === void 0) { + prompt = false; + } - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + var unblock = transitionManager.setPrompt(prompt); - // nth-* requires argument - if ( !match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } + if (!isBlocked) { + checkDOMListeners(1); + isBlocked = true; + } - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + return function () { + if (isBlocked) { + isBlocked = false; + checkDOMListeners(-1); + } - // other types prohibit arguments - } else if ( match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } + return unblock(); + }; + } - return match; - }, + function listen(listener) { + var unlisten = transitionManager.appendListener(listener); + checkDOMListeners(1); + return function () { + checkDOMListeners(-1); + unlisten(); + }; + } - "PSEUDO": function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; + var history = { + length: globalHistory.length, + action: 'POP', + location: initialLocation, + createHref: createHref, + push: push, + replace: replace, + go: go, + goBack: goBack, + goForward: goForward, + block: block, + listen: listen + }; + return history; +} - if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { - return null; - } +var HashChangeEvent$1 = 'hashchange'; +var HashPathCoders = { + hashbang: { + encodePath: function encodePath(path) { + return path.charAt(0) === '!' ? path : '!/' + stripLeadingSlash(path); + }, + decodePath: function decodePath(path) { + return path.charAt(0) === '!' ? path.substr(1) : path; + } + }, + noslash: { + encodePath: stripLeadingSlash, + decodePath: addLeadingSlash + }, + slash: { + encodePath: addLeadingSlash, + decodePath: addLeadingSlash + } +}; - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; +function getHashPath() { + // We can't use window.location.hash here because it's not + // consistent across browsers - Firefox will pre-decode it! + var href = window.location.href; + var hashIndex = href.indexOf('#'); + return hashIndex === -1 ? '' : href.substring(hashIndex + 1); +} - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && +function pushHashPath(path) { + window.location.hash = path; +} - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && +function replaceHashPath(path) { + var hashIndex = window.location.href.indexOf('#'); + window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path); +} - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { +function createHashHistory(props) { + if (props === void 0) { + props = {}; + } - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } + !canUseDOM ? invariant(false, 'Hash history needs a DOM') : void 0; + var globalHistory = window.history; + var canGoWithoutReload = supportsGoWithoutReloadUsingHash(); + var _props = props, + _props$getUserConfirm = _props.getUserConfirmation, + getUserConfirmation = _props$getUserConfirm === void 0 ? getConfirmation : _props$getUserConfirm, + _props$hashType = _props.hashType, + hashType = _props$hashType === void 0 ? 'slash' : _props$hashType; + var basename = props.basename ? stripTrailingSlash(addLeadingSlash(props.basename)) : ''; + var _HashPathCoders$hashT = HashPathCoders[hashType], + encodePath = _HashPathCoders$hashT.encodePath, + decodePath = _HashPathCoders$hashT.decodePath; - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, + function getDOMLocation() { + var path = decodePath(getHashPath()); + warning(!basename || hasBasename(path, basename), 'You are attempting to use a basename on a page whose URL path does not begin ' + 'with the basename. Expected path "' + path + '" to begin with "' + basename + '".'); + if (basename) path = stripBasename(path, basename); + return createLocation(path); + } - filter: { + var transitionManager = createTransitionManager(); - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, + function setState(nextState) { + _extends(history, nextState); - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; + history.length = globalHistory.length; + transitionManager.notifyListeners(history.location, history.action); + } - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + - ")" + className + "(" + whitespace + "|$)" ) ) && classCache( - className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, + var forceNextPop = false; + var ignorePath = null; - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); + function handleHashChange() { + var path = getHashPath(); + var encodedPath = encodePath(path); - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; + if (path !== encodedPath) { + // Ensure we always have a properly-encoded hash. + replaceHashPath(encodedPath); + } else { + var location = getDOMLocation(); + var prevLocation = history.location; + if (!forceNextPop && locationsAreEqual(prevLocation, location)) return; // A hashchange doesn't always == location change. - /* eslint-disable max-len */ + if (ignorePath === createPath(location)) return; // Ignore this change; we already setState in push/replace. - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - /* eslint-enable max-len */ + ignorePath = null; + handlePop(location); + } + } - }; - }, + function handlePop(location) { + if (forceNextPop) { + forceNextPop = false; + setState(); + } else { + var action = 'POP'; + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (ok) { + setState({ + action: action, + location: location + }); + } else { + revertPop(location); + } + }); + } + } - "CHILD": function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; + function revertPop(fromLocation) { + var toLocation = history.location; // TODO: We could probably make this more reliable by + // keeping a list of paths we've seen in sessionStorage. + // Instead, we just default to 0 for paths we don't know. - return first === 1 && last === 0 ? + var toIndex = allPaths.lastIndexOf(createPath(toLocation)); + if (toIndex === -1) toIndex = 0; + var fromIndex = allPaths.lastIndexOf(createPath(fromLocation)); + if (fromIndex === -1) fromIndex = 0; + var delta = toIndex - fromIndex; - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : + if (delta) { + forceNextPop = true; + go(delta); + } + } // Ensure the hash is encoded properly before doing anything else. - function( elem, _context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - if ( parent ) { + var path = getHashPath(); + var encodedPath = encodePath(path); + if (path !== encodedPath) replaceHashPath(encodedPath); + var initialLocation = getDOMLocation(); + var allPaths = [createPath(initialLocation)]; // Public interface - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { + function createHref(location) { + return '#' + encodePath(basename + createPath(location)); + } - return false; - } - } + function push(path, state) { + warning(state === undefined, 'Hash history cannot push state; it is ignored'); + var action = 'PUSH'; + var location = createLocation(path, undefined, undefined, history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + var path = createPath(location); + var encodedPath = encodePath(basename + path); + var hashChanged = getHashPath() !== encodedPath; - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } + if (hashChanged) { + // We cannot tell if a hashchange was caused by a PUSH, so we'd + // rather setState here and ignore the hashchange. The caveat here + // is that other hash histories in the page will consider it a POP. + ignorePath = path; + pushHashPath(encodedPath); + var prevIndex = allPaths.lastIndexOf(createPath(history.location)); + var nextPaths = allPaths.slice(0, prevIndex === -1 ? 0 : prevIndex + 1); + nextPaths.push(path); + allPaths = nextPaths; + setState({ + action: action, + location: location + }); + } else { + warning(false, 'Hash history cannot PUSH the same path; a new entry will not be added to the history stack'); + setState(); + } + }); + } - start = [ forward ? parent.firstChild : parent.lastChild ]; + function replace(path, state) { + warning(state === undefined, 'Hash history cannot replace state; it is ignored'); + var action = 'REPLACE'; + var location = createLocation(path, undefined, undefined, history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + var path = createPath(location); + var encodedPath = encodePath(basename + path); + var hashChanged = getHashPath() !== encodedPath; - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { + if (hashChanged) { + // We cannot tell if a hashchange was caused by a REPLACE, so we'd + // rather setState here and ignore the hashchange. The caveat here + // is that other hash histories in the page will consider it a POP. + ignorePath = path; + replaceHashPath(encodedPath); + } - // Seek `elem` from a previously-cached index + var prevIndex = allPaths.indexOf(createPath(history.location)); + if (prevIndex !== -1) allPaths[prevIndex] = path; + setState({ + action: action, + location: location + }); + }); + } - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || ( node[ expando ] = {} ); + function go(n) { + warning(canGoWithoutReload, 'Hash history go(n) causes a full page reload in this browser'); + globalHistory.go(n); + } - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); + function goBack() { + go(-1); + } - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; + function goForward() { + go(1); + } - while ( ( node = ++nodeIndex && node && node[ dir ] || + var listenerCount = 0; - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { + function checkDOMListeners(delta) { + listenerCount += delta; - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } + if (listenerCount === 1 && delta === 1) { + window.addEventListener(HashChangeEvent$1, handleHashChange); + } else if (listenerCount === 0) { + window.removeEventListener(HashChangeEvent$1, handleHashChange); + } + } - } else { + var isBlocked = false; - // Use previously-cached element index if available - if ( useCache ) { + function block(prompt) { + if (prompt === void 0) { + prompt = false; + } - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || ( node[ expando ] = {} ); + var unblock = transitionManager.setPrompt(prompt); - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); + if (!isBlocked) { + checkDOMListeners(1); + isBlocked = true; + } - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } + return function () { + if (isBlocked) { + isBlocked = false; + checkDOMListeners(-1); + } - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { + return unblock(); + }; + } - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { + function listen(listener) { + var unlisten = transitionManager.appendListener(listener); + checkDOMListeners(1); + return function () { + checkDOMListeners(-1); + unlisten(); + }; + } - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { + var history = { + length: globalHistory.length, + action: 'POP', + location: initialLocation, + createHref: createHref, + push: push, + replace: replace, + go: go, + goBack: goBack, + goForward: goForward, + block: block, + listen: listen + }; + return history; +} - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); +function clamp(n, lowerBound, upperBound) { + return Math.min(Math.max(n, lowerBound), upperBound); +} +/** + * Creates a history object that stores locations in memory. + */ - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - uniqueCache[ type ] = [ dirruns, diff ]; - } +function createMemoryHistory(props) { + if (props === void 0) { + props = {}; + } - if ( node === elem ) { - break; - } - } - } - } - } + var _props = props, + getUserConfirmation = _props.getUserConfirmation, + _props$initialEntries = _props.initialEntries, + initialEntries = _props$initialEntries === void 0 ? ['/'] : _props$initialEntries, + _props$initialIndex = _props.initialIndex, + initialIndex = _props$initialIndex === void 0 ? 0 : _props$initialIndex, + _props$keyLength = _props.keyLength, + keyLength = _props$keyLength === void 0 ? 6 : _props$keyLength; + var transitionManager = createTransitionManager(); - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, + function setState(nextState) { + _extends(history, nextState); - "PSEUDO": function( pseudo, argument ) { + history.length = history.entries.length; + transitionManager.notifyListeners(history.location, history.action); + } - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); + function createKey() { + return Math.random().toString(36).substr(2, keyLength); + } - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } + var index = clamp(initialIndex, 0, initialEntries.length - 1); + var entries = initialEntries.map(function (entry) { + return typeof entry === 'string' ? createLocation(entry, undefined, createKey()) : createLocation(entry, undefined, entry.key || createKey()); + }); // Public interface - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } + var createHref = createPath; - return fn; - } - }, + function push(path, state) { + warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to push when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + var action = 'PUSH'; + var location = createLocation(path, state, createKey(), history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + var prevIndex = history.index; + var nextIndex = prevIndex + 1; + var nextEntries = history.entries.slice(0); - pseudos: { + if (nextEntries.length > nextIndex) { + nextEntries.splice(nextIndex, nextEntries.length - nextIndex, location); + } else { + nextEntries.push(location); + } - // Potentially complex pseudos - "not": markFunction( function( selector ) { + setState({ + action: action, + location: location, + index: nextIndex, + entries: nextEntries + }); + }); + } - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); + function replace(path, state) { + warning(!(typeof path === 'object' && path.state !== undefined && state !== undefined), 'You should avoid providing a 2nd state argument to replace when the 1st ' + 'argument is a location-like object that already has state; it is ignored'); + var action = 'REPLACE'; + var location = createLocation(path, state, createKey(), history.location); + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (!ok) return; + history.entries[history.index] = location; + setState({ + action: action, + location: location + }); + }); + } - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; + function go(n) { + var nextIndex = clamp(history.index + n, 0, history.entries.length - 1); + var action = 'POP'; + var location = history.entries[nextIndex]; + transitionManager.confirmTransitionTo(location, action, getUserConfirmation, function (ok) { + if (ok) { + setState({ + action: action, + location: location, + index: nextIndex + }); + } else { + // Mimic the behavior of DOM histories by + // causing a render after a cancelled POP. + setState(); + } + }); + } - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); + function goBack() { + go(-1); + } - // Don't keep the element (issue #299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), + function goForward() { + go(1); + } - "has": markFunction( function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - } ), + function canGo(n) { + var nextIndex = history.index + n; + return nextIndex >= 0 && nextIndex < history.entries.length; + } - "contains": markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; - }; - } ), + function block(prompt) { + if (prompt === void 0) { + prompt = false; + } - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { + return transitionManager.setPrompt(prompt); + } - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + function listen(listener) { + return transitionManager.appendListener(listener); + } - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), + var history = { + length: entries.length, + action: 'POP', + location: entries[index], + index: index, + entries: entries, + createHref: createHref, + push: push, + replace: replace, + go: go, + goBack: goBack, + goForward: goForward, + canGo: canGo, + block: block, + listen: listen + }; + return history; +} - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, +exports.createBrowserHistory = createBrowserHistory; +exports.createHashHistory = createHashHistory; +exports.createMemoryHistory = createMemoryHistory; +exports.createLocation = createLocation; +exports.locationsAreEqual = locationsAreEqual; +exports.parsePath = parsePath; +exports.createPath = createPath; - "root": function( elem ) { - return elem === docElem; - }, +},{"resolve-pathname":75,"tiny-invariant":84,"tiny-warning":85,"value-equal":89}],13:[function(require,module,exports){ +"use strict";function _interopDefault(n){return n&&"object"==typeof n&&"default"in n?n.default:n}Object.defineProperty(exports,"__esModule",{value:!0});var resolvePathname=_interopDefault(require("resolve-pathname")),valueEqual=_interopDefault(require("value-equal"));require("tiny-warning");var invariant=_interopDefault(require("tiny-invariant"));function _extends(){return(_extends=Object.assign||function(n){for(var t=1;tt?e.splice(t,e.length-t,a):e.push(a),u({action:"PUSH",location:a,index:t,entries:e})}})},replace:function(n,t){var e="REPLACE",a=createLocation(n,t,f(),g.location);h.confirmTransitionTo(a,e,o,function(n){n&&(g.entries[g.index]=a,u({action:e,location:a}))})},go:p,goBack:function(){p(-1)},goForward:function(){p(1)},canGo:function(n){var t=g.index+n;return 0<=t&&t length ? - length : - argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; + } - "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } }; -Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; +module.exports = invariant; -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} +}).call(this,require('_process')) +},{"_process":25}],17:[function(require,module,exports){ +/*! + * jQuery JavaScript Library v3.7.1 + * https://jquery.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2023-08-28T13:37Z + */ +( function( global, factory ) { -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); + "use strict"; -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; + if ( typeof module === "object" && typeof module.exports === "object" ) { - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket trac-14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); } - soFar = selector; - groups = []; - preFilters = Expr.preFilter; +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - while ( soFar ) { +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { +var arr = []; - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } +var getProto = Object.getPrototypeOf; - matched = false; +var slice = arr.slice; - // Combinators - if ( ( match = rcombinators.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrim, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } +var push = arr.push; - if ( !matched ) { - break; - } - } +var indexOf = arr.indexOf; - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : +var class2type = {}; - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; +var toString = class2type.toString; -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} +var hasOwn = class2type.hasOwnProperty; -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; +var fnToString = hasOwn.toString; - return combinator.first ? +var ObjectFunctionString = fnToString.call( Object ); - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : +var support = {}; - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; +var isFunction = function isFunction( obj ) { - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || - ( outerCache[ elem.uniqueID ] = {} ); - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = uniqueCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; +var document = window.document; - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[ i ], results ); - } - return results; -} + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; + function DOMEval( code, node, doc ) { + doc = doc || document; - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); } } } + doc.head.appendChild( script ).parentNode.removeChild( script ); } - return newUnmatched; -} -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); +function toType( obj ) { + if ( obj == null ) { + return obj + ""; } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - // Get initial elements from seed or context - elems = seed || multipleContexts( - selector || "*", - context.nodeType ? [ context ] : context, - [] - ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - // ...intermediate processing is necessary - [] : +var version = "3.7.1", - // ...otherwise use results directly - results : - matcherIn; + rhtmlSuffix = /HTML$/i, - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } + // Define a local copy of jQuery + jQuery = function( selector, context ) { - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } +jQuery.fn = jQuery.prototype = { - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { + // The current version of jQuery being used + jquery: version, - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { + constructor: jQuery, - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } + // The default length of a jQuery object is 0 + length: 0, - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + toArray: function() { + return slice.call( this ); + }, - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); } - } ); -} -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + // Add the old object onto the stack (as a reference) + ret.prevObject = this; - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { + // Return the newly-formed element set + return ret; + }, - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens - .slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, - return elementMatcher( matchers ); -} + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, + first: function() { + return this.eq( 0 ); + }, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + last: function() { + return this.eq( -1 ); + }, - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, - if ( outermost ) { + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; + end: function() { + return this.prevObject || this.constructor(); + }, - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; } - // Track unmatched elements for set filters - if ( bySet ) { + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; } + copyIsArray = false; - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; } } + } + } - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; + // Return the modified object + return target; +}; - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } +jQuery.extend( { - if ( seed ) { + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } + // Assume jQuery is ready without the ready module + isReady: true, - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } + error: function( msg ) { + throw new Error( msg ); + }, - // Add matches to results - push.apply( results, setMatched ); + noop: function() {}, - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; - Sizzle.uniqueSort( results ); + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } } + } - return unmatched; - }; + return obj; + }, - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; + // Retrieve the text value of an array of DOM nodes + text: function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; - if ( !cached ) { + if ( !nodeType ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += jQuery.text( node ); + } } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); + if ( nodeType === 1 || nodeType === 11 ) { + return elem.textContent; + } + if ( nodeType === 9 ) { + return elem.documentElement.textContent; + } + if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); } else { - elementMatchers.push( cached ); + push.call( ret, arr ); } } - // Cache the compiled function - cached = compilerCache( - selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) - ); + return ret; + }, - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + isXMLDoc: function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; - results = results || []; + // Assume HTML when documentElement doesn't yet exist, such as inside + // document fragments. + return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); + }, - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } - context = ( Expr.find[ "ID" ]( token.matches[ 0 ] - .replace( runescape, funescape ), context ) || [] )[ 0 ]; - if ( !context ) { - return results; + first.length = i; - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } + return first; + }, - selector = selector.slice( tokens.shift().value.length ); + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } } - // Fetch a seed set for right-to-left matching - i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; + return matches; + }, - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || - context - ) ) ) { + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } + if ( value != null ) { + ret.push( value ); + } + } - break; + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); } } } - } - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; + // Flatten any nested arrays + return flat( ret ); + }, -// One-time assignments + // A global GUID counter for objects + guid: 1, -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} -// Initialize against the default document -setDocument(); +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { +function isArrayLike( obj ) { - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert( function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute( "href" ) === "#"; -} ) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - } ); -} + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert( function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -} ) ) { - addHandle( "value", function( elem, _name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - } ); + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; } -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert( function( el ) { - return el.getAttribute( "disabled" ) == null; -} ) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; - } - } ); -} -return Sizzle; +function nodeName( elem, name ) { -} )( window ); + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); +} +var pop = arr.pop; -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; +var sort = arr.sort; -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; +var splice = arr.splice; +var whitespace = "[\\x20\\t\\r\\n\\f]"; -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; +var rtrimCSS = new RegExp( + "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", + "g" +); -var siblings = function( n, elem ) { - var matched = []; - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - return matched; +// Note: an element does not contain itself +jQuery.contains = function( a, b ) { + var bup = b && b.parentNode; + + return a === bup || !!( bup && bup.nodeType === 1 && ( + + // Support: IE 9 - 11+ + // IE doesn't have `contains` on SVG. + a.contains ? + a.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); }; -var rneedsContext = jQuery.expr.match.needsContext; +// CSS string/identifier serialization +// https://drafts.csswg.org/cssom/#common-serializing-idioms +var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; -function nodeName( elem, name ) { +function fcssescape( ch, asCodePoint ) { + if ( asCodePoint ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; +} +jQuery.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); }; -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } +var preferredDoc = document, + pushNative = push; - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } +( function() { - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} +var i, + Expr, + outermostContext, + sortInput, + hasDuplicate, + push = pushNative, -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; + // Local document vars + document, + documentElement, + documentIsHTML, + rbuggyQSA, + matches, - if ( not ) { - expr = ":not(" + expr + ")"; - } + // Instance-specific data + expando = jQuery.expando, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + + "loop|multiple|open|readonly|required|scoped", - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; + // Regular expressions -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } + // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - ret = this.pushStack( [] ); + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, + pseudos = ":(" + identifier + ")(?:\\((" + - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + -// Initialize a jQuery object + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), -// A central reference to the root jQuery(document) -var rootjQuery, + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + + whitespace + "*" ), + rdescend = new RegExp( whitespace + "|>" ), - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; + matchExpr = { + ID: new RegExp( "^#(" + identifier + ")" ), + CLASS: new RegExp( "^\\.(" + identifier + ")" ), + TAG: new RegExp( "^(" + identifier + "|[*])" ), + ATTR: new RegExp( "^" + attributes ), + PSEUDO: new RegExp( "^" + pseudos ), + CHILD: new RegExp( + "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + bool: new RegExp( "^(?:" + booleans + ")$", "i" ), - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } + // For use in libraries implementing .is() + // We use this for POS matching in `select` + needsContext: new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; + rsibling = /[+~]/, - } else { - match = rquickExpr.exec( selector ); - } + // CSS escapes + // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { + if ( nonHex ) { - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; + // Strip the backslash prefix from a non-hex escape sequence + return nonHex; + } - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + return high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { + // Used for iframes; see `setDocument`. + // Support: IE 9 - 11+, Edge 12 - 18+ + // Removing the function wrapper causes a "Permission Denied" + // error in IE/Edge. + unloadHandler = function() { + setDocument(); + }, - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && nodeName( elem, "fieldset" ); + }, + { dir: "parentNode", next: "legend" } + ); - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} - return this; +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); + // Support: Android <=4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { + apply: function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + }, + call: function( target ) { + pushNative.apply( target, slice.call( arguments, 1 ) ); + } + }; +} - if ( elem ) { +function find( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); + results = results || []; - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; + return results; + } - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; - // Execute immediately if ready is not present - selector( jQuery ); - } + if ( documentIsHTML ) { - return jQuery.makeArray( selector, this ); - }; + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; + // ID selector + if ( ( m = match[ 1 ] ) ) { -// Initialize central reference -rootjQuery = jQuery( document ); + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + // Support: IE 9 only + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + push.call( results, elem ); + return results; + } + } else { + return results; + } -var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Element context + } else { - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; + // Support: IE 9 only + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + find.contains( context, elem ) && + elem.id === m ) { -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; + push.call( results, elem ); + return results; + } + } - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; } } - } ); - }, - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); + // Take advantage of querySelectorAll + if ( !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + newSelector = selector; + newContext = context; - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; - matched.push( cur ); - break; - } - } - } - } + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when + // strict-comparing two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( newContext != context || !support.scope ) { - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = jQuery.escapeSelector( nid ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } - // Determine the position of an element within the set - index: function( elem ) { + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } } + } - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } + // All others + return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); +} - // Locate the position of the desired element - return indexOf.call( this, +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, + function cache( key, value ) { - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, + // Use (key + " ") to avoid collision with native prototype properties + // (see https://github.com/jquery/sizzle/issues/157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; + return cache; } -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && +/** + * Mark a function for special use by jQuery selector module + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); - return elem.contentDocument; - } + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); } - return jQuery.merge( [], elem.childNodes ); + // release memory in IE + el = null; } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); +} - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + return nodeName( elem, "input" ) && elem.type === type; + }; +} - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && + elem.type === type; + }; +} - if ( this.length > 1 ) { +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11+ + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; } - return this.pushStack( matched ); + // Remaining elements are neither :enabled nor :disabled + return false; }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - +} +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); } ); - return object; } -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * +/** + * Checks a node for validity as a jQuery selector context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ -jQuery.Callbacks = function( options ) { +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [node] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +function setDocument( node ) { + var subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; - var // Flag to know if list is currently firing - firing, + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } - // Last fire value for non-forgettable lists - memory, + // Update global variables + document = doc; + documentElement = document.documentElement; + documentIsHTML = !jQuery.isXMLDoc( document ); - // Flag to know if list was already fired - fired, + // Support: iOS 7 only, IE 9 - 11+ + // Older browsers didn't support unprefixed `matches`. + matches = documentElement.matches || + documentElement.webkitMatchesSelector || + documentElement.msMatchesSelector; - // Flag to prevent firing - locked, + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors + // (see trac-13936). + // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, + // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. + if ( documentElement.msMatchesSelector && - // Actual callback list - list = [], + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - // Queue of execution data for repeatable lists - queue = [], + // Support: IE 9 - 11+, Edge 12 - 18+ + subWindow.addEventListener( "unload", unloadHandler ); + } - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, + // Support: IE <10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + documentElement.appendChild( el ).id = jQuery.expando; + return !document.getElementsByName || + !document.getElementsByName( jQuery.expando ).length; + } ); - // Fire callbacks - fire = function() { + // Support: IE 9 only + // Check to see if it's possible to do matchesSelector + // on a disconnected node. + support.disconnectedMatch = assert( function( el ) { + return matches.call( el, "*" ); + } ); - // Enforce single-firing - locked = locked || options.once; + // Support: IE 9 - 11+, Edge 12 - 18+ + // IE/Edge don't support the :scope pseudo-class. + support.scope = assert( function() { + return document.querySelectorAll( ":scope" ); + } ); - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { + // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only + // Make sure the `:has()` argument is parsed unforgivingly. + // We include `*` in the test to detect buggy implementations that are + // _selectively_ forgiving (specifically when the list includes at least + // one valid selector). + // Note that we treat complete lack of support for `:has()` as if it were + // spec-compliant support, which is fine because use of `:has()` in such + // environments will fail in the qSA path and fall back to jQuery traversal + // anyway. + support.cssHas = assert( function() { + try { + document.querySelector( ":has(*,:jqfake)" ); + return false; + } catch ( e ) { + return true; + } + } ); - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { + // ID filter and find + if ( support.getById ) { + Expr.filter.ID = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find.ID = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter.ID = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find.ID = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } } } - } - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; + return []; } + }; + } - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { + // Tag + Expr.find.TAG = function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; + // DocumentFragment nodes don't have gEBTN + } else { + return context.querySelectorAll( tag ); + } + }; - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, + // Class + Expr.find.CLASS = function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; - // Actual Callbacks object - self = { + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { + // QSA and matchesSelector support - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } + rbuggyQSA = []; - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); + var input; - if ( memory && !firing ) { - fire(); - } - } - return this; - }, + documentElement.appendChild( el ).innerHTML = + "" + + ""; - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); + // Support: iOS <=7 - 8 only + // Boolean attributes and "value" are not treated correctly in some XML documents + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, + // Support: iOS <=7 - 8 only + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, + // Support: iOS 8 only + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, + // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ + // In some of the document kinds, these selectors wouldn't work natively. + // This is probably OK but for backwards compatibility we want to maintain + // handling them through jQuery traversal in jQuery 3.x. + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE 9 - 11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ + // In some of the document kinds, these selectors wouldn't work natively. + // This is probably OK but for backwards compatibility we want to maintain + // handling them through jQuery traversal in jQuery 3.x. + documentElement.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + } ); - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, + if ( !support.cssHas ) { - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, + // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ + // Our regular `try-catch` mechanism fails to detect natively-unsupported + // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) + // in browsers that parse the `:has()` argument as a forgiving selector list. + // https://drafts.csswg.org/selectors/#relational now requires the argument + // to be parsed unforgivingly, but browsers have not yet fully adjusted. + rbuggyQSA.push( ":has" ); + } - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; + /* Sorting + ---------------------------------------------------------------------- */ - return self; -}; + // Document order sorting + sortOrder = function( a, b ) { + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } -function adoptValue( value, resolve, reject, noValue ) { - var method; + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : - try { + // Otherwise we know they are disconnected + 1; - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a === document || a.ownerDocument == preferredDoc && + find.contains( preferredDoc, a ) ) { + return -1; + } - // Other non-thenables - } else { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b === document || b.ownerDocument == preferredDoc && + find.contains( preferredDoc, b ) ) { + return 1; + } - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; } - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { + return compare & 4 ? -1 : 1; + }; - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } + return document; } -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ +find.matches = function( expr, elements ) { + return find( expr, null, null, elements ); +}; - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, +find.matchesSelector = function( elem, expr ) { + setDocument( elem ); - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; + if ( documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { + try { + var ret = matches.call( elem, expr ); - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } + return find( expr, document, null, [ elem ] ).length > 0; +}; - returned = handler.apply( that, args ); +find.contains = function( context, elem ) { - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return jQuery.contains( context, elem ); +}; - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; +find.attr = function( elem, name ) { - // Handle a returned thenable - if ( isFunction( then ) ) { + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); + var fn = Expr.attrHandle[ name.toLowerCase() ], - // Normal processors (resolve) also hook into progress - } else { + // Don't get fooled by Object.prototype properties (see trac-13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; - // ...and disregard older resolution values - maxDepth++; + if ( val !== undefined ) { + return val; + } - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } + return elem.getAttribute( name ); +}; - // Handle all other returned values - } else { +find.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +jQuery.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, + // Unless we *know* we can detect duplicates, assume their presence + // + // Support: Android <=4.0+ + // Testing for detecting duplicates is unpredictable so instead assume we can't + // depend on duplicate detection in all browsers without a stable sort. + hasDuplicate = !support.sortStable; + sortInput = !support.sortStable && slice.call( results, 0 ); + sort.call( results, sortOrder ); - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + splice.call( results, duplicates[ j ], 1 ); + } + } - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { + return results; +}; - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } +jQuery.fn.uniqueSort = function() { + return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); +}; - deferred.rejectWith( that, args ); - } - } - }; +Expr = jQuery.expr = { - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { + // Can be adjusted by the user + cacheLength: 50, - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } + createPseudo: markFunction, - return jQuery.Deferred( function( newDefer ) { + match: matchExpr, - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); + attrHandle: {}, - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); + find: {}, - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; + preFilter: { + ATTR: function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) + .replace( runescape, funescape ); - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } - // Handle state - if ( stateString ) { - list.add( - function() { + return match.slice( 0, 4 ); + }, - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, + CHILD: function( match ) { - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, + // nth-* requires argument + if ( !match[ 3 ] ) { + find.error( match[ 0 ] ); + } - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - } + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); + // other types prohibit arguments + } else if ( match[ 3 ] ) { + find.error( match[ 0 ] ); + } - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; + return match; + }, - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); + PSEUDO: function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; - // Make the deferred a promise - promise.promise( deferred ); + if ( matchExpr.CHILD.test( match[ 0 ] ) ) { + return null; + } - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - // All done! - return deferred; - }, + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && - // Deferred helper - when: function( singleValue ) { - var + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && - // count of uncompleted subordinates - remaining = arguments.length, + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - // count of unprocessed arguments - i = remaining, + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, - // the master Deferred - master = jQuery.Deferred(), + filter: { - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); - } + TAG: function( nodeNameSelector ) { + var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return nodeName( elem, expectedNodeName ); }; - }; + }, - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, - !remaining ); + CLASS: function( className ) { + var pattern = classCache[ className + " " ]; - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + ")" + className + + "(" + whitespace + "|$)" ) ) && + classCache( className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, - return master.then(); - } - } + ATTR: function( name, operator, check ) { + return function( elem ) { + var result = find.attr( elem, name ); - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); - } + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } - return master.promise(); - } -} ); + result += ""; + if ( operator === "=" ) { + return result === check; + } + if ( operator === "!=" ) { + return result !== check; + } + if ( operator === "^=" ) { + return check && result.indexOf( check ) === 0; + } + if ( operator === "*=" ) { + return check && result.indexOf( check ) > -1; + } + if ( operator === "$=" ) { + return check && result.slice( -check.length ) === check; + } + if ( operator === "~=" ) { + return ( " " + result.replace( rwhitespace, " " ) + " " ) + .indexOf( check ) > -1; + } + if ( operator === "|=" ) { + return result === check || result.slice( 0, check.length + 1 ) === check + "-"; + } -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + return false; + }; + }, -jQuery.Deferred.exceptionHook = function( error, stack ) { + CHILD: function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; + return first === 1 && last === 0 ? + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + function( elem, _context, xml ) { + var cache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + if ( parent ) { -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + nodeName( node, name ) : + node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + start = [ forward ? parent.firstChild : parent.lastChild ]; -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { -jQuery.fn.ready = function( fn ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || ( parent[ expando ] = {} ); + cache = outerCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; - readyList - .then( fn ) + while ( ( node = ++nodeIndex && node && node[ dir ] || - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { - return this; -}; + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } -jQuery.extend( { + } else { - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, + // Use previously-cached element index if available + if ( useCache ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + cache = outerCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { - // Handle when the DOM is ready - ready: function( wait ) { + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } + if ( ( ofType ? + nodeName( node, name ) : + node.nodeType === 1 ) && + ++diff ) { - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + outerCache[ type ] = [ dirruns, diff ]; + } + if ( node === elem ) { + break; + } + } + } + } + } + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + PSEUDO: function( pseudo, argument ) { -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; + // pseudo-class names are case-insensitive + // https://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + find.error( "unsupported pseudo: " + pseudo ); - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as jQuery does + if ( fn[ expando ] ) { + return fn( argument ); + } - // Sets one value - } else if ( value !== undefined ) { - chainable = true; + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } - if ( !isFunction( value ) ) { - raw = true; + return fn; } + }, - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } + pseudos: { - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } + // Potentially complex pseudos + not: markFunction( function( selector ) { - if ( chainable ) { - return elems; - } + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrimCSS, "$1" ) ); - // Gets - if ( bulk ) { - return fn.call( elems ); - } + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + // Don't keep the element + // (see https://github.com/jquery/sizzle/issues/299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; + has: markFunction( function( selector ) { + return function( elem ) { + return find( selector, elem ).length > 0; + }; + } ), -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} + contains: markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; + }; + } ), -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // https://www.w3.org/TR/selectors/#lang-pseudo + lang: markFunction( function( lang ) { - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + find.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + // Miscellaneous + target: function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + root: function( elem ) { + return elem === documentElement; + }, -function Data() { - this.expando = jQuery.expando + Data.uid++; -} + focus: function( elem ) { + return elem === safeActiveElement() && + document.hasFocus() && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, -Data.uid = 1; + // Boolean properties + enabled: createDisabledPseudo( false ), + disabled: createDisabledPseudo( true ), -Data.prototype = { + checked: function( elem ) { - cache: function( owner ) { + // In CSS3, :checked should return both checked and selected elements + // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + return ( nodeName( elem, "input" ) && !!elem.checked ) || + ( nodeName( elem, "option" ) && !!elem.selected ); + }, - // Check if the owner object already has a cache - var value = owner[ this.expando ]; + selected: function( elem ) { - // If not, create one - if ( !value ) { - value = {}; + // Support: IE <=11+ + // Accessing the selectedIndex property + // forces the browser to treat the default option as + // selected when in an optgroup. + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { + return elem.selected === true; + }, - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; + // Contents + empty: function( elem ) { - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); + // https://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; } } - } + return true; + }, - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); + parent: function( elem ) { + return !Expr.pseudos.empty( elem ); + }, - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; + // Element/input types + header: function( elem ) { + return rheader.test( elem.nodeName ); + }, - // Handle: [ owner, { properties } ] args - } else { + input: function( elem ) { + return rinputs.test( elem.nodeName ); + }, - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : + button: function( elem ) { + return nodeName( elem, "input" ) && elem.type === "button" || + nodeName( elem, "button" ); + }, - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { + text: function( elem ) { + var attr; + return nodeName( elem, "input" ) && elem.type === "text" && - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { + // Support: IE <10 only + // New HTML5 attribute values (e.g., "search") appear + // with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, - return this.get( owner, key ); - } + // Position-in-collection + first: createPositionalPseudo( function() { + return [ 0 ]; + } ), - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); + last: createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; + eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), - if ( cache === undefined ) { - return; - } + even: createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), - if ( key !== undefined ) { + odd: createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { + lt: createPositionalPseudo( function( matchIndexes, length, argument ) { + var i; - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); + if ( argument < 0 ) { + i = argument + length; + } else if ( argument > length ) { + i = length; } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); + i = argument; } - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + return matchIndexes; + } ), - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; + gt: createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); + return matchIndexes; + } ) } }; -var dataPriv = new Data(); - -var dataUser = new Data(); +Expr.pseudos.nth = Expr.pseudos.eq; +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; -function getData( data ) { - if ( data === "true" ) { - return true; + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); } - if ( data === "false" ) { - return false; - } + soFar = selector; + groups = []; + preFilters = Expr.preFilter; - if ( data === "null" ) { - return null; - } + while ( soFar ) { - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } - return data; -} + matched = false; -function dataAttr( elem, key, data ) { - var name; + // Combinators + if ( ( match = rleadingCombinator.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrimCSS, " " ) + } ); + soFar = soFar.slice( matched.length ); + } - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; + if ( !matched ) { + break; } } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + if ( parseOnly ) { + return soFar.length; + } - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, + return soFar ? + find.error( selector ) : - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; } -} ); + return selector; +} -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); + return combinator.first ? - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; } } - dataPriv.set( elem, "hasDataAttrs", true ); } - } - - return data; - } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } + if ( skip && nodeName( elem, skip ) ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = outerCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - return access( this, function( value ) { - var data; + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { + // Reuse newcache so results back-propagate to previous elements + outerCache[ key ] = newCache; - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } } + } + return false; + }; +} - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; } - - // We tried really hard, but the data doesn't exist. - return; } + return true; + } : + matchers[ 0 ]; +} - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + find( selector, contexts[ i ], results ); } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; + return results; +} - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); } } - return queue || []; } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; + } - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; + return newUnmatched; +} - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, matcherOut, + preMap = [], + postMap = [], + preexisting = results.length, - if ( fn ) { + // Get initial elements from seed or context + elems = seed || + multipleContexts( selector || "*", + context.nodeType ? [ context ] : context, [] ), - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems; - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } + if ( matcher ) { - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, + // If we have a postFinder, or filtered seed, or non-seed postFilter + // or preexisting results, + matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); + // ...intermediate processing is necessary + [] : -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; + // ...otherwise use results directly + results; - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; + // Find primary matches + matcher( matcherIn, matcherOut, context, xml ); + } else { + matcherOut = matcherIn; } - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } } - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); } } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + } ); +} -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); -var documentElement = document.documentElement; + // Avoid hanging onto element + // (see https://github.com/jquery/sizzle/issues/299) + checkContext = null; + return ret; + } ]; + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrimCSS, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } } -var isHiddenWithinTree = function( elem, el ) { - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; + return elementMatcher( matchers ); +} - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find.TAG( "*", outermost ), - jQuery.css( elem, "display" ) === "none"; - }; + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + if ( outermost ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + // Add elements passing elementMatchers directly to results + // Support: iOS <=7 - 9 only + // Tolerate NodeList properties (IE: "length"; Safari: ) matching + // elements by id. (see trac-14142) + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + push.call( results, elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + // Track unmatched elements for set filters + if ( bySet ) { - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; - while ( maxIterations-- ) { + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; + if ( seed ) { - } + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } + // Add matches to results + push.apply( results, setMatched ); - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; + jQuery.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; } +function compile( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; -var defaultDisplayMap = {}; + if ( !cached ) { -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } - if ( display ) { - return display; + // Cache the compiled function + cached = compilerCache( selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; } + return cached; +} - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); +/** + * A low-level selection function that works with jQuery's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with jQuery selector compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - temp.parentNode.removeChild( temp ); + results = results || []; - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { - return display; -} + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; + context = ( Expr.find.ID( + token.matches[ 0 ].replace( runescape, funescape ), + context + ) || [] )[ 0 ]; + if ( !context ) { + return results; - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); } - display = elem.style.display; - if ( show ) { + // Fetch a seed set for right-to-left matching + i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; + if ( ( find = Expr.find[ type ] ) ) { - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && + testContext( context.parentNode ) || context + ) ) ) { - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } } } - return elements; + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; } -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); +// One-time assignments -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); +// Support: Android <=4.0 - 4.1+ +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); +// Initialize against the default document +setDocument(); +// Support: Android <=4.0 - 4.1+ +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); +jQuery.find = find; - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.unique = jQuery.uniqueSort; - div.appendChild( input ); +// These have always been private, but they used to be documented as part of +// Sizzle so let's maintain them for now for backwards compatibility purposes. +find.compile = compile; +find.select = select; +find.setDocument = setDocument; +find.tokenize = tokenize; - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; +find.escape = jQuery.escapeSelector; +find.getText = jQuery.text; +find.isXML = jQuery.isXMLDoc; +find.selectors = jQuery.expr; +find.support = jQuery.support; +find.uniqueSort = jQuery.uniqueSort; - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + /* eslint-enable */ - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; } )(); -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; - _default: [ 0, "", "" ] + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; }; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} +var siblings = function( n, elem ) { + var matched = []; + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } -function getAll( context, tag ) { + return matched; +}; - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); +var rneedsContext = jQuery.expr.match.needsContext; - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - } else { - ret = []; + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); } - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); } - return ret; + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); } +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; + if ( not ) { + expr = ":not(" + expr + ")"; + } - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } -} + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; -var rhtml = /<|&#?\w+;/; +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } - for ( ; i < l; i++ ) { - elem = elems[ i ]; + ret = this.pushStack( [] ); - if ( elem || elem === 0 ) { + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } - // Add nodes directly - if ( toType( elem ) === "object" ) { + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); +// Initialize a jQuery object - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } +// A central reference to the root jQuery(document) +var rootjQuery, - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (trac-9521) + // Strict HTML recognition (trac-11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - // Remember the top-level container - tmp = fragment.firstChild; + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; } - } - // Remove wrapper from fragment - fragment.textContent = ""; + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); } - continue; - } - attached = isAttached( elem ); + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { - return fragment; -} + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + return this; -function returnTrue() { - return true; -} + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); -function returnFalse() { - return false; -} + if ( elem ) { -// Support: IE <=9 - 11+ -// focus() and blur() are asynchronous, except when they are no-op. -// So expect focus to be synchronous when the element is already active, -// and blur to be synchronous when the element is not already active. -// (focus and blur are always synchronous in other supported browsers, -// this just defines when we can count on it). -function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); -function on( elem, types, selector, data, fn, one ) { - var origFn, type; + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } - // Types can be a map of types/handlers - if ( typeof types === "object" ) { + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); + // Execute immediately if ready is not present + selector( jQuery ); } - return elem; - } - if ( data == null && fn == null ) { + return jQuery.makeArray( selector, this ); + }; - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { +// Initialize central reference +rootjQuery = jQuery( document ); - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { +var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, - global: {}, + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); - add: function( elem, types, handler, data, selector ) { + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } + // Don't pass non-elements to jQuery#find + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; + matched.push( cur ); + break; + } + } + } } - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } + // Determine the position of an element within the set + index: function( elem ) { - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); } - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); + // Locate the position of the desired element + return indexOf.call( this, - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); - if ( special.add ) { - special.add.call( elem, handleObj ); +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; + return elem.contentDocument; } - }, + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } - if ( !elemData || !( events = elemData.events ) ) { - return; + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); } - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + if ( this.length > 1 ) { - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); } - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); } + } - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - delete events[ type ]; - } - } - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - dispatch: function( nativeEvent ) { +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; + var // Flag to know if list is currently firing + firing, - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; + // Last fire value for non-forgettable lists + memory, - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } + // Flag to know if list was already fired + fired, - event.delegateTarget = this; + // Flag to prevent firing + locked, - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } + // Actual callback list + list = [], - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + // Queue of execution data for repeatable lists + queue = [], - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { + // Fire callbacks + fire = function() { - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { + // Enforce single-firing + locked = locked || options.once; - event.handleObj = handleObj; - event.data = handleObj.data; + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; } } } - } - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } - return event.result; - }, + firing = false; - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; + // Clean up if we're done firing for good + if ( locked ) { - // Find delegate handlers - if ( delegateCount && + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { + // Actual Callbacks object + self = { - for ( ; cur !== this; cur = cur.parentNode || this ) { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); } } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, + return this; + }, - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; + return this; + }, - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", returnTrue ); + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; } - - // Return false to allow normal processing in the caller - return false; + return this; }, - trigger: function( data ) { - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, - leverageNative( el, "click" ); + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } } + return this; + }, - // Return non-false to allow normal event-path propagation - return true; + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; }, - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; } - }, - - beforeunload: { - postDispatch: function( event ) { + }; - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } + return self; }; -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, expectSync ) { - // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add - if ( !expectSync ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var notAsync, result, - saved = dataPriv.get( this, type ); +function adoptValue( value, resolve, reject, noValue ) { + var method; - if ( ( event.isTrigger & 1 ) && this[ type ] ) { + try { - // Interrupt processing of the outer synthetic .trigger()ed event - // Saved data should be false in such cases, but might be a leftover capture object - // from an async native handler (gh-4350) - if ( !saved.length ) { + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); - // Trigger the native event and capture its result - // Support: IE <=9 - 11+ - // focus() and blur() are asynchronous - notAsync = expectSync( this, type ); - this[ type ](); - result = dataPriv.get( this, type ); - if ( saved !== result || notAsync ) { - dataPriv.set( this, type, false ); - } else { - result = {}; - } - if ( saved !== result ) { + // Other non-thenables + } else { - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - return result.value; - } + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering the - // native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved.length ) { + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} - // ...and capture the result - dataPriv.set( this, type, { - value: jQuery.event.trigger( - - // Support: IE <=9 - 11+ - // Extend with the prototype to reset the above stopImmediatePropagation() - jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), - saved.slice( 1 ), - this - ) - } ); +jQuery.extend( { - // Abort handling of the native event - event.stopImmediatePropagation(); - } - } - } ); -} + Deferred: function( func ) { + var tuples = [ -jQuery.removeEvent = function( elem, type, handle ) { + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; -jQuery.Event = function( src, props ) { + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; + returned = handler.apply( that, args ); - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && - // Event type - } else { - this.type = src; - } + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } + // Handle a returned thenable + if ( isFunction( then ) ) { - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); - // Mark it as fixed - this[ jQuery.expando ] = true; -}; + // Normal processors (resolve) also hook into progress + } else { -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, + // ...and disregard older resolution values + maxDepth++; - preventDefault: function() { - var e = this.originalEvent; + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } - this.isDefaultPrevented = returnTrue; + // Handle all other returned values + } else { - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } - this.isPropagationStopped = returnTrue; + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { - this.isImmediatePropagationStopped = returnTrue; + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.error ); + } - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { - this.stopPropagation(); - } -}; + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } + deferred.rejectWith( that, args ); + } + } + }; - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { - if ( button & 2 ) { - return 3; - } + // Call an optional hook to record the error, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getErrorHook ) { + process.error = jQuery.Deferred.getErrorHook(); + + // The deprecated alias of the above. While the name suggests + // returning the stack, not an error instance, jQuery just passes + // it directly to `console.warn` so both will work; an instance + // just better cooperates with source maps. + } else if ( jQuery.Deferred.getStackHook ) { + process.error = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } - if ( button & 4 ) { - return 2; - } + return jQuery.Deferred( function( newDefer ) { - return 0; - } + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); - return event.which; - } -}, jQuery.event.addProp ); + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - jQuery.event.special[ type ] = { + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, expectSync ); + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; - // Return false to allow normal processing in the caller - return false; - }, - trigger: function() { + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; - // Force setup before trigger - leverageNative( this, type ); + // Handle state + if ( stateString ) { + list.add( + function() { - // Return non-false to allow normal event-path propagation - return true; - }, + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, - delegateType: delegateType - }; -} ); + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); } - return ret; - } - }; -} ); -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); - } -} ); - - -var - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + // All done! + return deferred; + }, - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } + // Deferred helper + when: function( singleValue ) { + var - return elem; -} + // count of uncompleted subordinates + remaining = arguments.length, -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } + // count of unprocessed arguments + i = remaining, - return elem; -} + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; + // the primary Deferred + primary = jQuery.Deferred(), - if ( dest.nodeType !== 1 ) { - return; - } + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); - if ( events ) { - dataPriv.remove( dest, "handle events" ); + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } + return primary.then(); } } - } - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } - dataUser.set( dest, udataCur ); + return primary.promise(); } -} +} ); -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; +// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error +// captured before the async barrier to get the original error cause +// which may otherwise be hidden. +jQuery.Deferred.exceptionHook = function( error, asyncError ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, + error.stack, asyncError ); } -} +}; -function domManip( collection, args, callback, ignored ) { - // Flatten any nested arrays - args = flat( args ); - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); +jQuery.fn.ready = function( fn ) { - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { + readyList + .then( fn ) - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); - callback.call( collection[ i ], node, i ); - } + return this; +}; - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; +jQuery.extend( { - // Reenable scripts - jQuery.map( scripts, restoreScript ); + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { + // A counter to track how many items to wait for before + // the ready event fires. See trac-6781 + readyWait: 1, - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + // Handle when the DOM is ready + ready: function( wait ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; } - } - - return collection; -} -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; + // Remember that the DOM is ready + jQuery.isReady = true; - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; } - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); } +} ); - return elem; +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); } -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { +} else { - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - // Return the cloned set - return clone; - }, +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); } - } -} ); -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, + // Sets one value + } else if ( value !== undefined ) { + chainable = true; - remove: function( selector ) { - return remove( this, selector ); - }, + if ( !isFunction( value ) ) { + raw = true; + } - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, + if ( bulk ) { - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; } - } ); - }, + } - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); } - } ); - }, + } + } - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, + if ( chainable ) { + return elems; + } - empty: function() { - var elem, - i = 0; + // Gets + if ( bulk ) { + return fn.call( elems ); + } - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - // Remove any remaining nodes - elem.textContent = ""; - } - } +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; - return this; - }, +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (trac-9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - value = jQuery.htmlPrefilter( value ); +function Data() { + this.expando = jQuery.expando + Data.uid++; +} - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; +Data.uid = 1; - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } +Data.prototype = { - elem = 0; + cache: function( owner ) { - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } + // Check if the owner object already has a cache + var value = owner[ this.expando ]; - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, + // If not, create one + if ( !value ) { + value = {}; - replaceWith: function() { - var ignored = []; + // We can accept data for non-element nodes in modern browsers, + // but we should not, see trac-8335. + // Always return an empty object. + if ( acceptData( owner ) ) { - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); } } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); } - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); -var getStyles = function( elem ) { + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; + // Handle: [ owner, { properties } ] args + } else { - if ( !view || !view.opener ) { - view = window; + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { - ret = callback.call( elem ); + return this.get( owner, key ); + } - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); - return ret; -}; + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + if ( cache === undefined ) { + return; + } -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + if ( key !== undefined ) { + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); -( function() { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { + i = key.length; - // This is a singleton, we need to execute it only once - if ( !div ) { - return; + while ( i-- ) { + delete cache[ key[ i ] ]; + } } - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; +var dataUser = new Data(); - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - documentElement.removeChild( container ); +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; +function getData( data ) { + if ( data === "true" ) { + return true; } - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); + if ( data === "false" ) { + return false; } - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; + if ( data === "null" ) { + return null; } - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); + return data; +} - table.style.cssText = "position:absolute;left:-11111px"; - tr.style.height = "1px"; - trChild.style.height = "9px"; +function dataAttr( elem, key, data ) { + var name; - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; } - } ); -} )(); - + } + return data; +} -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, - computed = computed || getStyles( elem ); + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; + // Support: IE 11 only + // The attrs elements can be null (trac-14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; } - } - return ret !== undefined ? + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} + return access( this, function( value ) { + var data; + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { -function addGetHookIf( conditionFn, hookFn ) { + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; + // We tried really hard, but the data doesn't exist. return; } - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - + // Set the data... + this.each( function() { -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + dequeue: function( elem, type ) { + type = type || "fx"; -var + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } -function setPositiveNumber( _elem, value, subtract ) { + if ( fn ) { - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); } +} ); - for ( ; i < 4; i += 2 ) { +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; - // Both box models exclude margin - if ( box === "margin" ) { - delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; } - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); } } + resolve(); + return defer.promise( obj ); } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - return delta; -} +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; -function getWidthOrHeight( elem, dimension, extra ) { +var documentElement = document.documentElement; - // Start with computed style - var styles = getStyles( elem ), - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; } +var isHiddenWithinTree = function( elem, el ) { + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || + jQuery.css( elem, "display" ) === "none"; + }; - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - // Make sure the element is visible & connected - elem.getClientRects().length ) { - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); - // Normalize "" and auto - val = parseFloat( val ) || 0; + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; -jQuery.extend( { + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { + while ( maxIterations-- ) { - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; } + initialInUnit = initialInUnit / scale; + } - }, - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "gridArea": true, - "gridColumn": true, - "gridColumnEnd": true, - "gridColumnStart": true, - "gridRow": true, - "gridRowEnd": true, - "gridRowStart": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; } + } + return adjusted; +} - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } +var defaultDisplayMap = {}; - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; + if ( display ) { + return display; + } - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); - // Fixes bug #9237 - type = "number"; - } + temp.parentNode.removeChild( temp ); - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } + return display; +} - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; } } - + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } } else { + if ( display !== "none" ) { + values[ index ] = "none"; - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); } + } + } - // Otherwise just get the value from the style object - return style[ name ]; + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; } - }, + } - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); + return elements; +} - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); } - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - return val; - } -} ); +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (trac-11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (trac-14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + div.appendChild( input ); - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } +// We have to close these tags to support XHTML (trac-13200) +var wrapMap = { - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } + _default: [ 0, "", "" ] +}; - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; +function getAll( context, tag ) { - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) + var ret; - return expanded; - } - }; + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; } -} ); -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; + return ret; +} - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - return map; - } +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); } -} ); +} -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; +var rhtml = /<|&#?\w+;/; -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; + for ( ; i < l; i++ ) { + elem = elems[ i ]; - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; + if ( elem || elem === 0 ) { - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } + // Add nodes directly + if ( toType( elem ) === "object" ) { - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); -Tween.prototype.init.prototype = Tween.prototype; + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (trac-12392) + tmp.textContent = ""; } } } -}; -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; + // Remove wrapper from fragment + fragment.textContent = ""; -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { -jQuery.fx = Tween.prototype.init; + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } -// Back compat <1.8 extension point -jQuery.fx.step = {}; + attached = isAttached( elem ); + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; + return fragment; +} -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - jQuery.fx.tick(); - } +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; } -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); +function returnFalse() { + return false; } -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; +function on( elem, types, selector, data, fn, one ) { + var origFn, type; - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} + // Types can be a map of types/handlers + if ( typeof types === "object" ) { -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { - // We're done with this property - return tween; + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); } + return elem; } -} -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); + if ( data == null && fn == null ) { - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { - anim.always( function() { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; } - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { + global: {}, - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + add: function( elem, types, handler, data, selector ) { - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; } - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; } - } - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; } - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; - /* eslint-disable no-loop-func */ + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; - anim.done( function() { + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; - /* eslint-enable no-loop-func */ + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } } - } ); - } + } - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } } - } - } -} -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; } - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } + }, - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; } - } -} -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - deferred.notifyWith( elem, [ animation, percent, remaining ] ); + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } } - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); + jQuery.removeEvent( elem, type, elemData.handle ); } - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; + delete events[ type ]; } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); + } - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); } - } + }, - jQuery.map( props, createTween, animation ); + dispatch: function( nativeEvent ) { - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; - return animation; -} + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; -jQuery.Animation = jQuery.extend( Animation, { + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, + event.delegateTarget = this; - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; } - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - prefilters: [ defaultPrefilter ], + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; + event.handleObj = handleObj; + event.data = handleObj.data; - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); - } else { - opt.duration = jQuery.fx.speeds._default; + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } } } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); } - }; - - return opt; -}; -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { + return event.result; + }, - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { + // Find delegate handlers + if ( delegateCount && - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; + for ( ; cur !== this; cur = cur.parentNode || this ) { - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } + // Don't check non-elements (trac-13208) + // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); + // Don't conflict with Object.prototype properties (trac-13203) + sel = handleObj.selector + " "; - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } + } - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } + return handlerQueue; + }, - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); } } ); }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - // Enable finishing flag on private data - data.finish = true; + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, - // Empty the queue first - jQuery.queue( this, type, [] ); + special: { + load: { - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", true ); } - } - // Turn off finishing flag - delete data.finish; - } ); - } -} ); + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; + leverageNative( el, "click" ); + } - fxNow = Date.now(); + // Return non-false to allow normal event-path propagation + return true; + }, - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } + beforeunload: { + postDispatch: function( event ) { - if ( !timers.length ) { - jQuery.fx.stop(); + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } } - fxNow = undefined; }; -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, isSetup ) { -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { + // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add + if ( !isSetup ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } return; } - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var result, + saved = dataPriv.get( this, type ); - // Default speed - _default: 400 -}; + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + // Interrupt processing of the outer synthetic .trigger()ed event + if ( !saved ) { -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; + // Trigger the native event and capture its result + this[ type ](); + result = dataPriv.get( this, type ); + dataPriv.set( this, type, false ); + if ( saved !== result ) { -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); - input.type = "checkbox"; + return result; + } - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering + // the native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved ) { - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); + // ...and capture the result + dataPriv.set( this, type, jQuery.event.trigger( + saved[ 0 ], + saved.slice( 1 ), + this + ) ); + + // Abort handling of the native event by all jQuery handlers while allowing + // native handlers on the same element to run. On target, this is achieved + // by stopping immediate propagation just on the jQuery event. However, + // the native event is re-wrapped by a jQuery one on each level of the + // propagation so the only way to stop it for jQuery is to stop it for + // everyone via native `stopPropagation()`. This is not a problem for + // focus/blur which don't bubble, but it does also stop click on checkboxes + // and radios. We accept this limitation. + event.stopPropagation(); + event.isImmediatePropagationStopped = returnTrue; + } + } + } ); +} +jQuery.removeEvent = function( elem, type, handle ) { -var boolHook, - attrHandle = jQuery.expr.attrHandle; + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, +jQuery.Event = function( src, props ) { - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); } -} ); -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (trac-504, trac-13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } + // Event type + } else { + this.type = src; + } - elem.setAttribute( name, value + "" ); - return value; - } + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); - ret = jQuery.find.attr( elem, name ); + // Mark it as fixed + this[ jQuery.expando ] = true; +}; - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); } }, + stopPropagation: function() { + var e = this.originalEvent; - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); + this.isPropagationStopped = returnTrue; - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } + if ( e && !this.isSimulated ) { + e.stopPropagation(); } - } -} ); + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { + this.isImmediatePropagationStopped = returnTrue; - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); } - return name; + + this.stopPropagation(); } }; -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - if ( !isXML ) { + function focusMappedHandler( nativeEvent ) { + if ( document.documentMode ) { - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); + // Support: IE 11+ + // Attach a single focusin/focusout handler on the document while someone wants + // focus/blur. This is because the former are synchronous in IE while the latter + // are async. In other browsers, all those handlers are invoked synchronously. + + // `handle` from private data would already wrap the event, but we need + // to change the `type` here. + var handle = dataPriv.get( this, "handle" ), + event = jQuery.event.fix( nativeEvent ); + event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; + event.isSimulated = true; + + // First, handle focusin/focusout + handle( nativeEvent ); + + // ...then, handle focus/blur + // + // focus/blur don't bubble while focusin/focusout do; simulate the former by only + // invoking the handler at the lower level. + if ( event.target === event.currentTarget ) { + + // The setup part calls `leverageNative`, which, in turn, calls + // `jQuery.event.add`, so event handle will already have been set + // by this point. + handle( event ); + } + } else { + // For non-IE browsers, attach a single capturing handler on the document + // while someone wants focusin/focusout. + jQuery.event.simulate( delegateType, nativeEvent.target, + jQuery.event.fix( nativeEvent ) ); + } + } + jQuery.event.special[ type ] = { + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; + var attaches; -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, true ); - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); + if ( document.documentMode ) { -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; + // Support: IE 9 - 11+ + // We use the same native handler for focusin & focus (and focusout & blur) + // so we need to coordinate setup & teardown parts between those events. + // Use `delegateType` as the key as `type` is already used by `leverageNative`. + attaches = dataPriv.get( this, delegateType ); + if ( !attaches ) { + this.addEventListener( delegateType, focusMappedHandler ); + } + dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); + } else { - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } + // Return false to allow normal processing in the caller + return false; + } + }, + trigger: function() { - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + // Force setup before trigger + leverageNative( this, type ); - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } + // Return non-false to allow normal event-path propagation + return true; + }, - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } + teardown: function() { + var attaches; - return ( elem[ name ] = value ); - } + if ( document.documentMode ) { + attaches = dataPriv.get( this, delegateType ) - 1; + if ( !attaches ) { + this.removeEventListener( delegateType, focusMappedHandler ); + dataPriv.remove( this, delegateType ); + } else { + dataPriv.set( this, delegateType, attaches ); + } + } else { - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } + // Return false to indicate standard teardown should be applied + return false; + } + }, - return elem[ name ]; - }, + // Suppress native focus or blur if we're currently inside + // a leveraged native-event stack + _default: function( event ) { + return dataPriv.get( event.target, type ); + }, - propHooks: { - tabIndex: { - get: function( elem ) { + delegateType: delegateType + }; - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); + // Support: Firefox <=44 + // Firefox doesn't have focus(in | out) events + // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 + // + // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 + // focus(in | out) events fire after focus & blur events, + // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order + // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 + // + // Support: IE 9 - 11+ + // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, + // attach a single handler for both events in IE. + jQuery.event.special[ delegateType ] = { + setup: function() { - if ( tabindex ) { - return parseInt( tabindex, 10 ); + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + dataHolder = document.documentMode ? this : doc, + attaches = dataPriv.get( dataHolder, delegateType ); + + // Support: IE 9 - 11+ + // We use the same native handler for focusin & focus (and focusout & blur) + // so we need to coordinate setup & teardown parts between those events. + // Use `delegateType` as the key as `type` is already used by `leverageNative`. + if ( !attaches ) { + if ( document.documentMode ) { + this.addEventListener( delegateType, focusMappedHandler ); + } else { + doc.addEventListener( type, focusMappedHandler, true ); } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; + } + dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + dataHolder = document.documentMode ? this : doc, + attaches = dataPriv.get( dataHolder, delegateType ) - 1; + + if ( !attaches ) { + if ( document.documentMode ) { + this.removeEventListener( delegateType, focusMappedHandler ); + } else { + doc.removeEventListener( type, focusMappedHandler, true ); } - - return -1; + dataPriv.remove( dataHolder, delegateType ); + } else { + dataPriv.set( dataHolder, delegateType, attaches ); } } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } + }; } ); -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, - /* eslint no-unused-expressions: "off" */ + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; } - return null; - }, - set: function( elem ) { + return ret; + } + }; +} ); - /* eslint no-unused-expressions: "off" */ +jQuery.fn.extend( { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); } + return this; } - }; -} + if ( selector === false || typeof selector === "function" ) { -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } } ); +var + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } - return []; + + return elem; } -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } + return elem; +} - classes = classesToArray( value ); +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } + if ( events ) { + dataPriv.remove( dest, "handle events" ); - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); } } } + } - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } + dataUser.set( dest, udataCur ); + } +} - if ( !arguments.length ) { - return this.attr( "class", "" ); - } +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); - classes = classesToArray( value ); + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); +function domManip( collection, args, callback, ignored ) { - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { + // Flatten any nested arrays + args = flat( args ); - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); } - } - - return this; - }, + domManip( self, args, callback, ignored ); + } ); + } - toggleClass: function( value, stateVal ) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); + if ( fragment.childNodes.length === 1 ) { + fragment = first; } - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; - return this.each( function() { - var className, i, self, classNames; + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (trac-8070). + for ( ; i < l; i++ ) { + node = fragment; - if ( isValidValue ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = classesToArray( value ); + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); - while ( ( className = classNames[ i++ ] ) ) { + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); } } - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { + callback.call( collection[ i ], node, i ); + } - // Store className if set - dataPriv.set( this, "__className__", className ); - } + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); + // Re-enable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + + // Unwrap a CDATA section containing script contents. This shouldn't be + // needed as in XML documents they're already not visible when + // inspecting element contents and in HTML documents they have no + // meaning but we're preserving that logic for backwards compatibility. + // This will be removed completely in 4.0. See gh-4904. + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } } } - } ); - }, + } + } - hasClass: function( selector ) { - var className, elem, - i = 0; + return collection; +} - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); } - return false; + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } } -} ); - + return elem; +} +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, -var rreturn = /\r/g; + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + // We eschew jQuery#find here for performance reasons: + // https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } - ret = elem.value; + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; + } else { + cloneCopyEvent( elem, clone ); } + } - return; + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } - valueIsFunction = isFunction( value ); + // Return the cloned set + return clone; + }, - return this.each( function( i ) { - var val; + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; - if ( this.nodeType !== 1 ) { - return; - } + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } } + } + } +} ); - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, - } else if ( typeof val === "number" ) { - val += ""; + remove: function( selector ) { + return remove( this, selector ); + }, - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); } + } ); + }, - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); } } ); - } -} ); + }, -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : + empty: function() { + var elem, + i = 0; - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; + } - if ( index < 0 ) { - i = max; + return this; + }, - } else { - i = one ? index : 0; - } + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } - // Get the specific value for the option - value = jQuery( option ).val(); + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - // We don't need an array for one selects - if ( one ) { - return value; - } + value = jQuery.htmlPrefilter( value ); - // Multi-Selects return an array - values.push( value ); - } - } + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; - return values; - }, + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; + elem = 0; - while ( i-- ) { - option = options[ i ]; + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } - /* eslint-disable no-cond-assign */ + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } + replaceWith: function() { + var ignored = []; - /* eslint-enable no-cond-assign */ - } + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); } - return values; } - } + + // Force callback invocation + }, ignored ); } } ); -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); } + + return this.pushStack( ret ); }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } } ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); +var rcustomProp = /^--/; +var getStyles = function( elem ) { -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; + // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + if ( !view || !view.opener ) { + view = window; + } -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); + return view.getComputedStyle( elem ); }; -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } - cur = lastElement = tmp = elem = elem || document; + ret = callback.call( elem ); - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } + return ret; +}; - if ( type.indexOf( "." ) > -1 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } +( function() { - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + // This is a singleton, we need to execute it only once + if ( !div ) { return; } - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( - dataPriv.get( cur, "events" ) || Object.create( null ) - )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; + documentElement.removeChild( container ); - if ( tmp ) { - elem[ ontype ] = null; - } + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); - elem[ type ](); + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (trac-8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; - jQuery.event.triggered = undefined; + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); - return event.result; - }, + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "box-sizing:content-box;border:1px solid"; - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; - jQuery.event.trigger( e, null, elem ); - } + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is `display: block` + // gets around this issue. + trChild.style.display = "block"; -} ); + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); -jQuery.fn.extend( { + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; } - } -} ); + } ); +} )(); -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + isCustomProp = rcustomProp.test( name ), - jQuery.event.special[ fix ] = { - setup: function() { + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ); + computed = computed || getStyles( elem ); - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ) - 1; + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, trac-12537) + // .css('--customProperty) (gh-3144) + if ( computed ) { - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); + // Support: IE <=9 - 11+ + // IE only supports `"float"` in `getPropertyValue`; in computed styles + // it's only available as `"cssFloat"`. We no longer modify properties + // sent to `.css()` apart from camelCasing, so we need to check both. + // Normally, this would create difference in behavior: if + // `getPropertyValue` returns an empty string, the value returned + // by `.css()` would be `undefined`. This is usually the case for + // disconnected elements. However, in IE even disconnected elements + // with no styles return `"none"` for `getPropertyValue( "float" )` + ret = computed.getPropertyValue( name ) || computed[ name ]; - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; + if ( isCustomProp && ret ) { + + // Support: Firefox 105+, Chrome <=105+ + // Spec requires trimming whitespace for custom properties (gh-4926). + // Firefox only trims leading whitespace. Chrome just collapses + // both leading & trailing whitespace to a single space. + // + // Fall back to `undefined` if empty string returned. + // This collapses a missing definition with property defined + // and set to an empty string but there's no standard API + // allowing us to differentiate them without a performance penalty + // and returning `undefined` aligns with older jQuery. + // + // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED + // as whitespace while CSS does not, but this is not a problem + // because CSS preprocessing replaces them with U+000A LINE FEED + // (which *is* CSS whitespace) + // https://www.w3.org/TR/css-syntax-3/#input-preprocessing + ret = ret.replace( rtrimCSS, "$1" ) || undefined; + } -var nonce = { guid: Date.now() }; + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } -var rquery = ( /\?/ ); + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } } - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } + return ret !== undefined ? - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; +function addGetHookIf( conditionFn, hookFn ) { -function buildParams( prefix, obj, traditional, add ) { - var name; + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { - if ( Array.isArray( obj ) ) { + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} - // Treat each array item as a scalar. - add( prefix, v ); - } else { +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { - } else if ( !traditional && toType( obj ) === "object" ) { + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; } + } +} - } else { +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - // Serialize scalar item. - add( prefix, obj ); + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; } + return vendorProps[ name ] = vendorPropName( name ) || name; } -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; +var - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; - if ( a == null ) { - return ""; - } +function setPositiveNumber( _elem, value, subtract ) { - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} - } else { +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0, + marginDelta = 0; - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; } - // Return the resulting serialization - return s.join( "&" ); -}; + for ( ; i < 4; i += 2 ) { -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { + // Both box models exclude margin + // Count margin delta separately to only add it after scroll gutter adjustment. + // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). + if ( box === "margin" ) { + marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( _i, elem ) { - var val = jQuery( this ).val(); + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - if ( val == null ) { - return null; + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } } -} ); - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, + return delta + marginDelta; +} - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), +function getWidthOrHeight( elem, dimension, extra ) { - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; + // Start with computed style + var styles = getStyles( elem ), -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; } + val = "auto"; + } - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - if ( isFunction( func ) ) { + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); + // Make sure the element is visible & connected + elem.getClientRects().length ) { - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } } - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; + // Normalize "" and auto + val = parseFloat( val ) || 0; - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, - return target; + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; } -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; +jQuery.extend( { - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } } } - } + }, - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + animationIterationCount: true, + aspectRatio: true, + borderImageSlice: true, + columnCount: true, + flexGrow: true, + flexShrink: true, + fontWeight: true, + gridArea: true, + gridColumn: true, + gridColumnEnd: true, + gridColumnStart: true, + gridRow: true, + gridRowEnd: true, + gridRowStart: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + scale: true, + widows: true, + zIndex: true, + zoom: true, + + // SVG-related + fillOpacity: true, + floodOpacity: true, + stopOpacity: true, + strokeMiterlimit: true, + strokeOpacity: true + }, - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, - // Or just use first one - finalDataType = finalDataType || firstDataType; - } + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); } - } - current = dataTypes.shift(); + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - // Convert to each sequential dataType - while ( current ) { + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } + // Convert "+=" or "-=" to relative numbers (trac-7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } + // Fixes bug trac-9237 + type = "number"; + } - prev = current; - current = dataTypes.shift(); + // Make sure that null and NaN values aren't set (trac-7116) + if ( value == null || value !== value ) { + return; + } - if ( current ) { + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } - current = prev; + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + } else { - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { + return ret; + } - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { + // Otherwise just get the value from the style object + return style[ name ]; + } + }, - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } - // Apply converter (if not an equivalence) - if ( conv !== true ) { + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); } - } - - return { state: "success", data: response }; -} -jQuery.extend( { + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } - // Counter for holding the number of active queries - active: 0, + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", + return val; + } +} ); - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } }, - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", - // Convert anything to text - "* text": String, + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; - // Text to html (true = no transformation) - "text html": true, + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } - // Evaluate text as a json expression - "text json": JSON.parse, + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { - // Parse text as xml - "text xml": jQuery.parseXML - }, + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true + return setPositiveNumber( elem, value, subtract ); } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? + }; +} ); - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; - // Main method - ajax: function( url, options ) { + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; + return expanded; } + }; - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); - // timeout handle - timeoutTimer, +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; - // Url cleanup var - urlAnchor, + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; - // Request state (becomes false upon send and true upon completion) - completed, + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } - // To know if global events are to be dispatched - fireGlobals, + return map; + } - // Loop variable - i, + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); - // uncached part of the url - uncached, - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; - // Callbacks context - callbackContext = s.context || s, +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; - // Status-dependent callbacks - statusCode = s.statusCode || {}, + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; - // Default abort message - strAbort = "canceled", +Tween.prototype.init.prototype = Tween.prototype; - // Fake xhr - jqXHR = { - readyState: 0, +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, +jQuery.fx = Tween.prototype.init; - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; +// Back compat <1.8 extension point +jQuery.fx.step = {}; - // Attach deferreds - deferred.promise( jqXHR ); - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; + jQuery.fx.tick(); + } +} - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } + return attrs; +} - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); + // We're done with this property + return tween; } + } +} - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; - // More options handling for requests with no content - if ( !s.hasContent ) { + anim.always( function() { - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; + // Ignore all other no-op show/hide data + } else { + continue; + } } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } + } - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } } - // Aborting is no longer a cancellation - strAbort = "abort"; + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; } - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); } - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { + /* eslint-disable no-loop-func */ - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } + anim.done( function() { - // Propagate others as results - done( -1, e ); - } - } + /* eslint-enable no-loop-func */ - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } - // Ignore repeat invocations - if ( completed ) { - return; + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; } + } + } +} - completed = true; +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } - // Cache response headers - responseHeadersString = headers || ""; + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - // Use a noop converter for missing script - if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { - s.converters[ "text script" ] = function() {}; - } + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } - // If successful, handle type chaining - if ( isSuccess ) { + deferred.notifyWith( elem, [ animation, percent, remaining ] ); - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); } - } else { - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); } + return this; } + } ), + props = animation.props; - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + propFilter( props, animation.opts.specialEasing ); - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); } + return result; + } + } - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; + jQuery.map( props, createTween, animation ); - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } + return animation; +} - return jqXHR; +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] }, - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } }, - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } } } ); -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; + } else { + opt.duration = jQuery.fx.speeds._default; + } } } -} ); + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, + // Queueing + opt.old = opt.complete; - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); } - } ); -}; + }; + return opt; +}; jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } + fadeTo: function( speed, to, easing, callback ) { - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { - wrap.map( function() { - var elem = this; + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); } + }; - return elem; - } ).append( this ); - } + doAnimation.finish = doAnimation; - return this; + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); } return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } } else { - self.append( html ); + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } } - } ); - }, - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } } ); }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; } ); - return this; } } ); +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + fxNow = Date.now(); + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; }; -var xhrSuccessStatus = { +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; + inProgress = true; + schedule(); +}; -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; +jQuery.fx.stop = function() { + inProgress = null; +}; - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); +jQuery.fx.speeds = { + slow: 600, + fast: 200, - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); + // Default speed + _default: 400 +}; - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } +// Based off of the plugin by Clint Helfers, with permission. +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { + input.type = "checkbox"; - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { +var boolHook, + attrHandle = jQuery.expr.attrHandle; - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); - // Create the abort callback - callback = callback( "abort" ); +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; - try { + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } - abort: function() { - if ( callback ) { - callback(); - } + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; } - }; - } -} ); + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + elem.setAttribute( name, value + "" ); + return value; + } + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); + ret = jQuery.find.attr( elem, name ); -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; }, - contents: { - script: /\b(?:java|ecma)script\b/ + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } } } } ); -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; } -} ); +}; -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " - \ No newline at end of file + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ca72062b9..2684e0ae1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -135,6 +135,7 @@ FILE (GLOB dmanHeaderFiles ../src/base/consts.h ../src/base/eventlogutils.h ../src/base/utils.h + ../src/base/eventlogutils.h ../src/controller/*.h ../src/dbus/*.h ../src/dbus/dbusvariant/*.h diff --git a/tests/src/base/ut_utils.cpp b/tests/src/base/ut_utils.cpp index 0749535ba..b1ee6038a 100644 --- a/tests/src/base/ut_utils.cpp +++ b/tests/src/base/ut_utils.cpp @@ -57,7 +57,8 @@ TEST_F(ut_utils_test, getSystemManualDir) Utils *m_utils = new Utils; QString str = DMAN_MANUAL_DIR; - ASSERT_EQ(m_utils->getSystemManualDir(), str); + QStringList strList = QStringList() << str; + ASSERT_EQ(m_utils->getSystemManualDir(), strList); delete m_utils; } @@ -227,21 +228,21 @@ struct ReplyStruct { TEST_F(ut_utils_test, launcherInterface) { - Utils *m_utils = new Utils; - QList applist = m_utils->launcherInterface(); - ASSERT_TRUE(applist.size() >= 0); +// Utils *m_utils = new Utils; +// QList applist = m_utils->launcherInterface(); +// ASSERT_TRUE(applist.size() >= 0); - Stub s; - s.set(ADDR(QDBusInterface, isValid), stub_isValid); - s.set(ADDR(QDBusReply>, isValid), stub_isValid); - QList applist2 = m_utils->launcherInterface(); - s.reset(ADDR(QDBusInterface, isValid)); - ASSERT_TRUE(applist2.size() == 0); +// Stub s; +// s.set(ADDR(QDBusInterface, isValid), stub_isValid); +// s.set(ADDR(QDBusReply>, isValid), stub_isValid); +// QList applist2 = m_utils->launcherInterface(); +// s.reset(ADDR(QDBusInterface, isValid)); +// ASSERT_TRUE(applist2.size() == 0); - QList applist3 = m_utils->launcherInterface(); - ASSERT_TRUE(applist2.size() == 0); +// QList applist3 = m_utils->launcherInterface(); +// ASSERT_TRUE(applist2.size() == 0); - delete m_utils; +// delete m_utils; } QStringList manaulapplist() diff --git a/tests/src/controller/ut_filewatcher.cpp b/tests/src/controller/ut_filewatcher.cpp index 74443525a..31439b3c1 100644 --- a/tests/src/controller/ut_filewatcher.cpp +++ b/tests/src/controller/ut_filewatcher.cpp @@ -25,14 +25,14 @@ void ut_fileWatcher::TearDown() TEST_F(ut_fileWatcher, onChangeFile) { - QString dbPath = Utils::getSystemManualDir(); + QString dbPath = Utils::getSystemManualDir().first(); dbPath += "/search.db"; m_fw->onChangeFile(dbPath); ASSERT_TRUE(m_fw->timerObj->isActive()); } TEST_F(ut_fileWatcher, onChangeDirSlot) { - QString assetsPath = Utils::getSystemManualDir(); + QString assetsPath = Utils::getSystemManualDir().first(); m_fw->onChangeDirSlot(assetsPath); ASSERT_TRUE(m_fw->timerObj->isActive()); } diff --git a/tests/src/controller/ut_helpermanager.cpp b/tests/src/controller/ut_helpermanager.cpp index 849bf706d..c8bc07574 100644 --- a/tests/src/controller/ut_helpermanager.cpp +++ b/tests/src/controller/ut_helpermanager.cpp @@ -75,22 +75,22 @@ QString ut_helperManager::stub_writableLocation(QStandardPaths::StandardLocation TEST_F(ut_helperManager, initDbConfig) { - Stub s; +// Stub s; - s.set((QWebEnginePage* (QWebEngineView::*)())ADDR(QWebEngineView, page), ADDR(ut_helperManager, stub_page)); - s.set((void (QWebEnginePage::*)(QWebChannel *))ADDR(QWebEnginePage, setWebChannel), ADDR(ut_helperManager,stub_setWeb)); - s.set((void (QWebEngineView::*)(const QUrl &))ADDR(QWebEngineView, load), stub_initweb); - s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_helperManager, stub_writableLocation)); - m_hm->initWeb(); - m_hm->initDbConfig(); +// s.set((QWebEnginePage* (QWebEngineView::*)())ADDR(QWebEngineView, page), ADDR(ut_helperManager, stub_page)); +// s.set((void (QWebEnginePage::*)(QWebChannel *))ADDR(QWebEnginePage, setWebChannel), ADDR(ut_helperManager,stub_setWeb)); +// s.set((void (QWebEngineView::*)(const QUrl &))ADDR(QWebEngineView, load), stub_initweb); +// s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_helperManager, stub_writableLocation)); +// m_hm->initWeb(); +// m_hm->initDbConfig(); - QString dbdir = Utils::mkMutiDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).append("/.local/share/deepin/deepin-manual")); - QString databasePath = dbdir.append("/search.db"); +// QString dbdir = Utils::mkMutiDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).append("/.local/share/deepin/deepin-manual")); +// QString databasePath = dbdir.append("/search.db"); - QFileInfo fileinfo(databasePath); - ASSERT_TRUE(fileinfo.exists()); +// QFileInfo fileinfo(databasePath); +// ASSERT_TRUE(fileinfo.exists()); - delete webchannel; +// delete webchannel; } TEST_F(ut_helperManager, handleDb) @@ -124,45 +124,45 @@ TEST_F(ut_helperManager, handleDb) TEST_F(ut_helperManager, getModuleInfo) { - Stub s; - s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_helperManager, stub_writableLocation)); - QString dbdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).append("/.local/share/deepin/deepin-manual"); - QString databasePath1 = dbdir.append("/search.db"); - QFile::remove(databasePath1); - - QDir dir; - dir.mkpath("./manual-assets/system/dde/dde/zh_CN/"); - dir.mkpath("./manual-assets/system/dde/dde11/zh_CN/"); - dir.mkpath("./manual-assets/application/deepin-voice-note/voice-note/zh_CN/"); - dir.mkpath("./manual-assets/professional/deepin-voice-note/zh_CN/"); - - QFile file("./manual-assets/system/dde/dde/zh_CN/index.md"); - file.open(QIODevice::ReadWrite | QIODevice::Text); - file.close(); - QFile file1("./manual-assets/application/deepin-voice-note/voice-note/zh_CN/index.md"); - file1.open(QIODevice::ReadWrite | QIODevice::Text); - file1.close(); - QFile file2("./manual-assets/professional/deepin-voice-note/zh_CN/index.md"); - file2.open(QIODevice::ReadWrite | QIODevice::Text); - file2.close(); - - Utils ut; - - s.set(ADDR(Utils, getSystemManualDir), ut_fileWatcher::stub_getSystemManualDir); - s.set((QWebEnginePage * (QWebEngineView::*)()) ADDR(QWebEngineView, page), ADDR(ut_helperManager, stub_page)); - s.set((void (QWebEnginePage::*)(QWebChannel *))ADDR(QWebEnginePage, setWebChannel), ADDR(ut_helperManager, stub_setWeb)); - s.set((void (QWebEngineView::*)(const QUrl &))ADDR(QWebEngineView, load), stub_initweb); - m_hm->initWeb(); - m_hm->initDbConfig(); - m_hm->getModuleInfo(); - qWarning() << m_hm->addTList; - qWarning() << m_hm->deleteTList; - ASSERT_TRUE(m_hm->timerObj->isActive()); - ASSERT_EQ(m_hm->watcherObj->mapOld.count(), 2); - - QDir dirRemove; - dirRemove.rmpath("./manual-assets/"); - delete webchannel; +// Stub s; +// s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_helperManager, stub_writableLocation)); +// QString dbdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation).append("/.local/share/deepin/deepin-manual"); +// QString databasePath1 = dbdir.append("/search.db"); +// QFile::remove(databasePath1); + +// QDir dir; +// dir.mkpath("./manual-assets/system/dde/dde/zh_CN/"); +// dir.mkpath("./manual-assets/system/dde/dde11/zh_CN/"); +// dir.mkpath("./manual-assets/application/deepin-voice-note/voice-note/zh_CN/"); +// dir.mkpath("./manual-assets/professional/deepin-voice-note/zh_CN/"); + +// QFile file("./manual-assets/system/dde/dde/zh_CN/index.md"); +// file.open(QIODevice::ReadWrite | QIODevice::Text); +// file.close(); +// QFile file1("./manual-assets/application/deepin-voice-note/voice-note/zh_CN/index.md"); +// file1.open(QIODevice::ReadWrite | QIODevice::Text); +// file1.close(); +// QFile file2("./manual-assets/professional/deepin-voice-note/zh_CN/index.md"); +// file2.open(QIODevice::ReadWrite | QIODevice::Text); +// file2.close(); + +// Utils ut; + +// s.set(ADDR(Utils, getSystemManualDir), ut_fileWatcher::stub_getSystemManualDir); +// s.set((QWebEnginePage * (QWebEngineView::*)()) ADDR(QWebEngineView, page), ADDR(ut_helperManager, stub_page)); +// s.set((void (QWebEnginePage::*)(QWebChannel *))ADDR(QWebEnginePage, setWebChannel), ADDR(ut_helperManager, stub_setWeb)); +// s.set((void (QWebEngineView::*)(const QUrl &))ADDR(QWebEngineView, load), stub_initweb); +// m_hm->initWeb(); +//// m_hm->initDbConfig(); +// m_hm->getModuleInfo(); +// qWarning() << m_hm->addTList; +// qWarning() << m_hm->deleteTList; +// ASSERT_TRUE(m_hm->timerObj->isActive()); +// ASSERT_EQ(m_hm->watcherObj->mapOld.count(), 2); + +// QDir dirRemove; +// dirRemove.rmpath("./manual-assets/"); +// delete webchannel; } TEST_F(ut_helperManager, initConnect) diff --git a/tests/src/controller/ut_search_db.cpp b/tests/src/controller/ut_search_db.cpp index efad641b2..205e01723 100644 --- a/tests/src/controller/ut_search_db.cpp +++ b/tests/src/controller/ut_search_db.cpp @@ -88,12 +88,12 @@ bool stub_exec() TEST_F(ut_search_db_test, SearchDb) { - Stub s; - s.set(ADDR(QSqlDatabase, isOpen), stub_open); - s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_search_db_test, stub_writableLocation)); +// Stub s; +// s.set(ADDR(QSqlDatabase, isOpen), stub_open); +// s.set(ADDR(QStandardPaths, writableLocation), ADDR(ut_search_db_test, stub_writableLocation)); - SearchDb db; - ASSERT_GT(db.strlistApp.size(), 0); +// SearchDb db; +// ASSERT_GT(db.strlistApp.size(), 0); } TEST_F(ut_search_db_test, initSearchTable) diff --git a/tests/src/dbus/ut_manual_search_proxy.cpp b/tests/src/dbus/ut_manual_search_proxy.cpp index 08147f87b..59b188be3 100644 --- a/tests/src/dbus/ut_manual_search_proxy.cpp +++ b/tests/src/dbus/ut_manual_search_proxy.cpp @@ -76,23 +76,23 @@ QDBusMessage ut_call(QDBus::CallMode mode, TEST_F(ut_manual_search_proxy, OnNewWindowOpen) { - msp->m_bWindowState = true; - msp->OnNewWindowOpen("dde"); - - Stub st; - st.set(ADDR(QDBusReply, isValid), stub_isValid); - - st.set((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call), - ut_call); - - msp->OnNewWindowOpen("dde"); - ASSERT_TRUE(ut_ActivateWindow); - st.reset(ADDR(QDBusReply, isValid)); - st.reset((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call)); +// msp->m_bWindowState = true; +// msp->OnNewWindowOpen("dde"); + +// Stub st; +// st.set(ADDR(QDBusReply, isValid), stub_isValid); + +// st.set((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call), +// ut_call); + +// msp->OnNewWindowOpen("dde"); +// ASSERT_TRUE(ut_ActivateWindow); +// st.reset(ADDR(QDBusReply, isValid)); +// st.reset((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call)); } TEST_F(ut_manual_search_proxy, ManualExists) diff --git a/tests/src/view/ut_manual_proxy.cpp b/tests/src/view/ut_manual_proxy.cpp index 274ee0693..55987d81a 100644 --- a/tests/src/view/ut_manual_proxy.cpp +++ b/tests/src/view/ut_manual_proxy.cpp @@ -58,7 +58,7 @@ QString ut_manual_proxy_test::stub_LocalNameug_bo_CN() TEST_F(ut_manual_proxy_test, getSystemManualDir) { - QString str = m_mp->getSystemManualDir(); + QString str = m_mp->getSystemManualDir().first(); QString tmp = "manual-assets"; ASSERT_TRUE(str.contains(tmp)); } diff --git a/tests/src/view/ut_web_window.cpp b/tests/src/view/ut_web_window.cpp index 6a433d52d..b2ba982c2 100644 --- a/tests/src/view/ut_web_window.cpp +++ b/tests/src/view/ut_web_window.cpp @@ -130,24 +130,24 @@ QDBusMessage ut_HelpSupport(QDBus::CallMode mode, TEST_F(ut_web_window_test, slot_HelpSupportTriggered) { - WebWindow *web = new WebWindow; - web->HelpSupportTriggered(); - - Stub st; - st.set(ADDR(QDBusReply, isValid), ADDR(ut_web_window_test, stub_isValid)); - st.set((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &, - const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call), - ut_HelpSupport); - - web->HelpSupportTriggered(true); - ASSERT_TRUE(ut_HelpSupportTriggered); - st.reset(ADDR(QDBusReply, isValid)); - st.set(ADDR(QDBusReply, isValid), ADDR(ut_web_window_test, stub_isValidfalse)); - web->HelpSupportTriggered(true); - ASSERT_TRUE(ut_HelpSupportTriggered); - st.reset(ADDR(QDBusReply, isValid)); - delete web; +// WebWindow *web = new WebWindow; +// web->HelpSupportTriggered(); + +// Stub st; +// st.set(ADDR(QDBusReply, isValid), ADDR(ut_web_window_test, stub_isValid)); +// st.set((QDBusMessage(QDBusAbstractInterface::*)(QDBus::CallMode, const QString &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &, +// const QVariant &, const QVariant &, const QVariant &, const QVariant &))ADDR(QDBusAbstractInterface, call), +// ut_HelpSupport); + +// web->HelpSupportTriggered(true); +// ASSERT_TRUE(ut_HelpSupportTriggered); +// st.reset(ADDR(QDBusReply, isValid)); +// st.set(ADDR(QDBusReply, isValid), ADDR(ut_web_window_test, stub_isValidfalse)); +// web->HelpSupportTriggered(true); +// ASSERT_TRUE(ut_HelpSupportTriggered); +// st.reset(ADDR(QDBusReply, isValid)); +// delete web; } diff --git a/translations/deepin-manual.ts b/translations/deepin-manual.ts index 44fff57ed..fdd0ab4c3 100644 --- a/translations/deepin-manual.ts +++ b/translations/deepin-manual.ts @@ -1,10 +1,20 @@ - + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment @@ -12,81 +22,107 @@ QObject - - Manual + + + Search for "%1" in the full text - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + The content was updated + + + + + Search + + + + + + Support - + + Copy + + + + + Quick Start + + + + + Video Guide + + + + System - + Applications - + No search results - + Home - + result - + results - - Search + + Click to view - - Support + + View all - - The content was updated + + App Store - - Copy + + Manual - - - Search for "%1" in the full text + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. WebWindow - + Ctrl+Alt+F - + Ctrl+F diff --git a/translations/deepin-manual_am_ET.ts b/translations/deepin-manual_am_ET.ts index 4617a43ce..8f3f9b471 100755 --- a/translations/deepin-manual_am_ET.ts +++ b/translations/deepin-manual_am_ET.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - + + The content was updated + - + + Search + መፈለጊያ + + + + + Support + + + + Copy ኮፒ - + + Quick Start + + + + + Video Guide + + + + System ስርአት - + Applications መተግበሪያ - - Sorry, there are no search results of "%1" - + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - - - - + Home ቤት - - Deepin Wiki - የ ዲፕኢን ዊኪ + + result + - - - Search "%1" in the full text - መፈለጊያ "%1" በ ሙሉ ጽሁፍ + + results + - - Search - መፈለጊያ + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_ar.ts b/translations/deepin-manual_ar.ts index d1e842979..e75a35acb 100755 --- a/translations/deepin-manual_ar.ts +++ b/translations/deepin-manual_ar.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - كتيّب + + + Search for "%1" in the full text + البحث عن "%1" في كامل النص - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - كتيّب التعليمات مصمم لمساعدة المستخدمين على تعلم نظام التشغيل وتطبيقاته عن طريق تزويدهم بإرشادات مخصصة ووصف للوظائف التي يقوم لها النظام. + + The content was updated + + + + + Search + بحث + + + + + Support + + + + + Copy + نسخ + + + + Quick Start + - + + Video Guide + + + + System النظام - + Applications التطبيقات - + No search results لا يوجد نتائج لبحثك - + Home البداية - + result النتيجة - + results النتائج - - Search - بحث + + Click to view + - - Support - + + View all + - - The content was updated - + + App Store + - - Copy - نسخ + + Manual + كتيّب - - - Search for "%1" in the full text - البحث عن "%1" في كامل النص + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + كتيّب التعليمات مصمم لمساعدة المستخدمين على تعلم نظام التشغيل وتطبيقاته عن طريق تزويدهم بإرشادات مخصصة ووصف للوظائف التي يقوم لها النظام. WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ast.ts b/translations/deepin-manual_ast.ts index 8fe84df3f..cbe214771 100755 --- a/translations/deepin-manual_ast.ts +++ b/translations/deepin-manual_ast.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + Entornu d'escritoriu + + QObject - - Deepin Manual - Deepin Manual + + + Search for "%1" in the full text + + + + + The content was updated + Anovóse'l conteníu - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - Deepin Manual ta diseñáu p'ayudar a los usuarios a saber cómo s'usen les aplicaiciones de Deepin forniendo instrucciones y descripciones pa funciones específiques. + + Search + Buscar - + + + Support + Sofitu + + + Copy Copiar - + + Quick Start + + + + + Video Guide + + + + System Sistema - + Applications Aplicaciones - - Sorry, there are no search results of "%1" - Perdona pero nun hai resultaos de gueta pa «%1» + + No search results + Nun hai resultaos - - Change your keywords and try again, or search it in Deepin Wiki - Camuda les pallabres clave y volvi tentalo, o gueta na wiki de Deepin - - - + Home Aniciu - - Deepin Wiki - Wiki de Deepin + + result + resultáu - - - Search "%1" in the full text - Guetar «%1» en testu completu + + results + resultaos - - Search - Guetar + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + Ctrl+Alt+F + + + + Ctrl+F + Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_az.ts b/translations/deepin-manual_az.ts index 21cdadd78..2b4505004 100644 --- a/translations/deepin-manual_az.ts +++ b/translations/deepin-manual_az.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + İş masası mühiti QObject - - Manual - Təlimat + + + Search for "%1" in the full text + Tam mətndə "%1" axtarmaq - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Təlimat, xüsusi təlimatlar və funksiyaların açıqlamasını verərək, istifadəçilərə əməliyyat sistemi və tətbiqləri öyrənməyə kömək etmək üçün hazırlanmışdır. + + The content was updated + Məzmun yeniləndi + + + + Search + Axtarış + + + + + Support + Dəstək + + + + Copy + Kopyalamaq - + + Quick Start + + + + + Video Guide + + + + System Sistem - + Applications Tətbiqlər - + No search results Axtarış nəticələri yoxdur - + Home Ev - + result nəticə - + results nəticələr - - Search - Axtarış + + Click to view + - - Support - Dəstək + + View all + - - The content was updated - Məzmun yeniləndi + + App Store + - - Copy - Kopyalamaq + + Manual + Təlimat - - - Search for "%1" in the full text - Tam mətndə "%1" axtarmaq + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + Təlimat, xüsusi təlimatlar və funksiyaların açıqlamasını verərək, istifadəçilərə əməliyyat sistemi və tətbiqləri öyrənməyə kömək etmək üçün hazırlanmışdır. WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_bg.ts b/translations/deepin-manual_bg.ts index ea3f9ea87..226c84e31 100755 --- a/translations/deepin-manual_bg.ts +++ b/translations/deepin-manual_bg.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - Deepin ръководство + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - Deepin ръководство е предназначен да помогне на потребителите да се запознаят с Deepin и Deepin приложенията, като предоставят конкретни инструкции и описания на функциите. + + The content was updated + - + + Search + Търсене + + + + + Support + + + + Copy Копиране - + + Quick Start + + + + + Video Guide + + + + System Система - + Applications Приложения - - Sorry, there are no search results of "%1" - За съжаление няма резултати от търсенето на "%1" + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - Променете ключовите си думи и опитайте отново или ги потърсете Deepin Wiki - - - + Home Начало - - Deepin Wiki - Deepin Wiki + + result + - - - Search "%1" in the full text - Търси "%1" в пълния текст + + results + - - Search - Търсене + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_bn.ts b/translations/deepin-manual_bn.ts index 21550d33e..10fc1b47c 100755 --- a/translations/deepin-manual_bn.ts +++ b/translations/deepin-manual_bn.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - ডিপিন ম্যানুয়াল + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - ডিপিন ম্যানুয়াল তৈরী করা হয়েছে ব্যাবহারকারীদের ডিপিন এবং ডিপিন এপ্লিকেশন সম্পর্কে সুনির্দিষ্ট নির্দেশনা এবং কার্যবলীর বর্ণনা দিয়ে সাহায্য করতে। + + The content was updated + - + + Search + অনুসন্ধান করুন + + + + + Support + + + + Copy কপি - + + Quick Start + + + + + Video Guide + + + + System সিস্টেম - + Applications এপ্লিকেশন - - Sorry, there are no search results of "%1" - দুঃখিত, এখানে "%1" এর কোনো ফলাফল নেই + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - আপনার আপনার কীওয়ার্ড পরিবর্তন করুন এবং আবার চেষ্টা করুন, বা Deepin Wiki তে এটি অনুসন্ধান করুন - - - + Home হোম - - Deepin Wiki - ডিপিন উইকি + + result + - - - Search "%1" in the full text - সম্পূর্ণ টেক্সটে "%1" অনুসন্ধান করুন + + results + - - Search - অনুসন্ধান করুন + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_bo.ts b/translations/deepin-manual_bo.ts index 473bcb3b7..4da38e5b9 100644 --- a/translations/deepin-manual_bo.ts +++ b/translations/deepin-manual_bo.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + གཞི་རྩའི་བཀོལ་སྤྱོད་ལ་རྒྱུས་ལོན། + + + + Common Application Libraries + རྒྱུན་སྤྱོད་ཉེར་སྤྱོད་མཛོད། + + + Desktop Environment ཅོག་ངོས་ཁོར་ཡུག @@ -10,83 +22,109 @@ QObject - - Manual - རོགས་རམ་ལག་དེབ། + + + Search for "%1" in the full text + ཡིག་ཆ་ཚང་མའི་ནང་དུ་“%1”འཚོལ་བ། - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - རོགས་རམ་ལག་དེབ་ནི་སྤྱོད་མཁན་གྱིས་བཀོལ་སྤྱོད་མ་ལག་དང་དེའི་མ་ལག་ཉེར་སྤྱོད་ལ་རྒྱུས་ལོན་བྱེད་རོགས་བྱེད་པ་དང་། ཞིབ་ཕྲའི་སྤྱོད་ཐབས་དང་ནུས་པའི་གསལ་བཤད་འདོན་སྤྲོད་བྱེད་ཐུབ། + + The content was updated + མིག་སྔའི་ནང་དོན་གསར་བརྗེ་བྱས་ཟིན། + + + + Search + འཚོལ་ཞིབ། + + + + + Support + ཞབས་ཞུ་དང་རོགས་སྐྱོར། + + + + Copy + པར་སློག - + + Quick Start + མགྱོགས་པོ་འཛུལ་བ། + + + + Video Guide + བརྙན་འཕྲིན་ཕྱོགས་སྟོན། + + + System མ་ལག - + Applications ཉེར་སྤྱོད། - + No search results འཚོལ་ཞིབ་བྱས་འབྲས་མེད། - + Home གཙོ་ངོས་སུ་ཕྱིར་ལོག་པ། - + result འབྲས་བུ། - + results འབྲས་བུ། - - Search - འཚོལ་ཞིབ། + + Click to view + མནན་ནས་ལྟ་བ། - - Support - ཞབས་ཞུ་དང་རོགས་སྐྱོར། + + View all + ཆ་ཚང་ལ་ལྟ་བ། - - The content was updated - མིག་སྔའི་ནང་དོན་གསར་བརྗེ་བྱས་ཟིན། + + App Store + - - Copy - པར་སློག + + Manual + རོགས་རམ་ལག་དེབ། - - - Search for "%1" in the full text - ཡིག་ཆ་ཚང་མའི་ནང་དུ་“%1”འཚོལ་བ། + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + རོགས་རམ་ལག་དེབ་ནི་སྤྱོད་མཁན་གྱིས་བཀོལ་སྤྱོད་མ་ལག་དང་དེའི་མ་ལག་ཉེར་སྤྱོད་ལ་རྒྱུས་ལོན་བྱེད་རོགས་བྱེད་པ་དང་། ཞིབ་ཕྲའི་སྤྱོད་ཐབས་དང་ནུས་པའི་གསལ་བཤད་འདོན་སྤྲོད་བྱེད་ཐུབ། WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_br.ts b/translations/deepin-manual_br.ts index e239e2881..b2a21fdd5 100644 --- a/translations/deepin-manual_br.ts +++ b/translations/deepin-manual_br.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - Dornlevr + + + Search for "%1" in the full text + Klask war-lerc'h "%1" en destenn en he fezh - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - An dornlevr a zo soñjet evit sikour gant an implijaderien evit deskiñ penaos ober gant ar sistem oberata hag e arloadoù; en ur bourveziñ pezhioù-titouroù spis ha deskrivadurioù eus an arc'hweladurioù. + + The content was updated + + + + + Search + Klask + + + + + Support + + + + + Copy + Eilañ + + + + Quick Start + - + + Video Guide + + + + System Sistem - + Applications Arloadoù - + No search results Disoc'h ebet kavet - + Home Degemer - + result disoc'h - + results disoc'hoù - - Search - Klask + + Click to view + - - Support - + + View all + - - The content was updated - + + App Store + - - Copy - Eilañ + + Manual + - - - Search for "%1" in the full text - Klask war-lerc'h "%1" en destenn en he fezh + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ktrl+Alt+F - + Ctrl+F Ktrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ca.ts b/translations/deepin-manual_ca.ts index 840f75141..df4b7d1f3 100755 --- a/translations/deepin-manual_ca.ts +++ b/translations/deepin-manual_ca.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Aprendre les operacions bàsiques + + + + Common Application Libraries + Biblioteques d'aplicacions comunes + + + Desktop Environment Entorn d'escriptori @@ -10,83 +22,109 @@ QObject - - Manual - Manual + + + Search for "%1" in the full text + Cerca "%1" a tot el text - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - El Manual està dissenyat per ajudar els usuaris a aprendre com funciona el sistema operatiu i les aplicacions. Proporciona instruccions específiques i descripció de funcions. + + The content was updated + S'ha carregat el contingut. + + + + Search + Cerca + + + + + Support + Assistència + + + + Copy + Copia + + + + Quick Start + Començament ràpid - + + Video Guide + Guia de vídeo + + + System Sistema - + Applications Aplicacions - + No search results No hi ha cap resultat de la cerca. - + Home Inici - + result resultat - + results resultats - - Search - Cerca + + Click to view + Cliqueu-hi per veure-ho - - Support - Assistència + + View all + Mostra-ho tot - - The content was updated - S'ha carregat el contingut. + + App Store + - - Copy - Copia + + Manual + - - - Search for "%1" in the full text - Cerca "%1" a tot el text + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_cs.ts b/translations/deepin-manual_cs.ts index 037dc5361..3675d7f17 100755 --- a/translations/deepin-manual_cs.ts +++ b/translations/deepin-manual_cs.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + Desktopové prostředí QObject - - Manual - Příručka + + + Search for "%1" in the full text + Vyhledat „%1“ napříč celým textem - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Příručka je navržena tak, aby pomáhala uživatelům naučit se pracovat s operačním systémem a přidruženými aplikacemi. Poskytuje pokyny k jeho specifikům a popisy fungování. + + The content was updated + Obsah byl aktualizován + + + + Search + Hledat + + + + + Support + Podpora + + + + Copy + Zkopírovat - + + Quick Start + + + + + Video Guide + + + + System Systém - + Applications Aplikace - + No search results Nic nenalezeno - + Home Domů - + result výsledek - + results výsledky - - Search - Hledat + + Click to view + - - Support - Podpora + + View all + - - The content was updated - Obsah byl aktualizován + + App Store + - - Copy - Zkopírovat + + Manual + Příručka - - - Search for "%1" in the full text - Vyhledat „%1“ napříč celým textem + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + Příručka je navržena tak, aby pomáhala uživatelům naučit se pracovat s operačním systémem a přidruženými aplikacemi. Poskytuje pokyny k jeho specifikům a popisy fungování. WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_da.ts b/translations/deepin-manual_da.ts index 55db23635..6f214c842 100755 --- a/translations/deepin-manual_da.ts +++ b/translations/deepin-manual_da.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - Manual + + + Search for "%1" in the full text + Søg efter "%1" i den fulde tekst - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Manual er designet til at hjælpe brugere med at lære styresystemet og dets programmer, ved at levere bestemte instruktioner og beskrivelser af funktioner. + + The content was updated + + + + + Search + Søg + + + + + Support + + + + + Copy + Kopiér + + + + Quick Start + - + + Video Guide + + + + System System - + Applications Programmer - + No search results Ingen søgeresultater - + Home Hjem - + result resultat - + results resultater - - Search - Søg + + Click to view + - - Support - + + View all + - - The content was updated - + + App Store + - - Copy - Kopiér + + Manual + - - - Search for "%1" in the full text - Søg efter "%1" i den fulde tekst + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_de.ts b/translations/deepin-manual_de.ts index 878496e0d..93ea91ceb 100755 --- a/translations/deepin-manual_de.ts +++ b/translations/deepin-manual_de.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + Desktop-Umgebung QObject - - Manual - Handbuch + + + Search for "%1" in the full text + Nach „%1“ im Volltext suchen - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Das Benutzerhandbuch wurde entwickelt, um Anwender dabei zu unterstützen, das Betriebssystem und die Anwendungen mithilfe zugeschnittener Anleitungen und Funktionsbeschreibungen zu erlernen und kennen zu lernen. + + The content was updated + Der Inhalt wurde aktualisiert + + + + Search + Suchen + + + + + Support + Unterstützung + + + + Copy + Kopieren + + + + Quick Start + Schnellstart - + + Video Guide + + + + System System - + Applications Anwendungen - + No search results Keine Suchergebnisse - + Home Startseite - + result Ergebnis - + results Ergebnisse - - Search - Suchen + + Click to view + Zum Ansehen klicken - - Support - Unterstützung + + View all + Alle ansehen - - The content was updated - Der Inhalt wurde aktualisiert + + App Store + - - Copy - Kopieren + + Manual + - - - Search for "%1" in the full text - Suche nach "%1" im Volltext + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F - Ctrl+Alt+F + Strg+Alt+F - + Ctrl+F - Ctrl+F + Strg+F - \ No newline at end of file + diff --git a/translations/deepin-manual_el.ts b/translations/deepin-manual_el.ts index 6cd62b7a6..88fb45db6 100755 --- a/translations/deepin-manual_el.ts +++ b/translations/deepin-manual_el.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - Εγχειρίδιο Deepin + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - Το Deepin Manual έχει σχεδιαστεί για να βοηθήσει τους χρήστες να μάθουν το Deepin περιβάλλον αλλά και τις εφαρμογές, παρέχοντας λεπτομερής οδηγίες και περιγραφές λειτουργιών. + + The content was updated + - + + Search + Αναζήτηση + + + + + Support + + + + Copy Αντιγραφή - + + Quick Start + + + + + Video Guide + + + + System Σύστημα - + Applications Εφαρμογές - - Sorry, there are no search results of "%1" - Συγνώμη δεν βρέθηκαν αποτελέσματα για την αναζήτηση "%1" + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - Άλλαξε τις λέξεις κλειδιά και ξανα προσπάθησε, ή αναζήτησε βοήθεια στο Deepin Wiki - - - + Home Αρχική - - Deepin Wiki - Deepin Wiki + + result + - - - Search "%1" in the full text - Αναζήτηση για “%1” σε όλο το κείμενο + + results + - - Search - Αναζήτηση + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_en.ts b/translations/deepin-manual_en.ts index 546757a0d..2ec2bc2ea 100644 --- a/translations/deepin-manual_en.ts +++ b/translations/deepin-manual_en.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Desktop Environment @@ -10,68 +22,94 @@ QObject - + Manual Manual - + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - + + Quick Start + + + + + Video Guide + + + + System System - + Applications Applications - + No search results No search results - + Home Home - + result result - + results results - + + Click to view + + + + + View all + + + + + App Store + App Store + + + Search Search - + + Support Support - + The content was updated The content was updated - + Copy Copy - - + + Search for "%1" in the full text Search for "%1" in the full text @@ -79,14 +117,14 @@ WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_es.ts b/translations/deepin-manual_es.ts index 32ef76735..fb8b07e4b 100755 --- a/translations/deepin-manual_es.ts +++ b/translations/deepin-manual_es.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Aprenda operaciones básicas + + + + Common Application Libraries + Bibliotecas de aplicaciones comunes + + + Desktop Environment Entorno de escritorio @@ -10,83 +22,109 @@ QObject - - Manual - Manual + + + Search for "%1" in the full text + Buscar "%1" en el texto completo - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Manual de Deepin es una guía del sistema operativo y sus aplicaciones, proporcionando instrucciones específicas y descripciones de sus funciones. + + The content was updated + El contenido fue actualizado + + + + Search + Buscar + + + + + Support + Soporte + + + + Copy + Copiar + + + + Quick Start + Inicio rápido - + + Video Guide + Guía de vídeo + + + System Sistema - + Applications Aplicaciones - + No search results No hay resultados de la búsqueda - + Home Inicio - + result resultado - + results resultados - - Search - Buscar + + Click to view + Click para ver - - Support - Soporte + + View all + Ver todo - - The content was updated - El contenido fue actualizado + + App Store + - - Copy - Copiar + + Manual + - - - Search for "%1" in the full text - Buscar "%1" en el texto completo + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl + Alt + F - + Ctrl+F Ctrl + F - \ No newline at end of file + diff --git a/translations/deepin-manual_fi.ts b/translations/deepin-manual_fi.ts index abc1b3892..bba79cd22 100755 --- a/translations/deepin-manual_fi.ts +++ b/translations/deepin-manual_fi.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Opettele perustoiminnot + + + + Common Application Libraries + Yleiset sovelluskirjastot + + + Desktop Environment Työpöytäympäristö @@ -10,83 +22,109 @@ QObject - - Manual - Käyttöohje + + + Search for "%1" in the full text + Etsi "%1" koko tekstistä - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Käyttöjärjestelmän käsikirja on suunniteltu auttamaan käyttäjiä tarjoamalla erityisiä ohjeita ja toimintokuvauksia ohjelmista. + + The content was updated + Sisältö päivitettiin + + + + Search + Etsi + + + + + Support + Tuki + + + + Copy + Kopio + + + + Quick Start + Nopea aloitus - + + Video Guide + Video opas + + + System Järjestelmä - + Applications Sovellukset - + No search results Ei hakutuloksia - + Home Koti - + result tulos - + results tulokset - - Search - Etsi + + Click to view + Paina ja katso - - Support - Tuki + + View all + Näytä kaikki - - The content was updated - Sisältö päivitettiin + + App Store + - - Copy - Kopio + + Manual + - - - Search for "%1" in the full text - Etsi "%1" koko tekstistä + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_fr.ts b/translations/deepin-manual_fr.ts index 9998096c8..9e240537b 100755 --- a/translations/deepin-manual_fr.ts +++ b/translations/deepin-manual_fr.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Environnement de bureau @@ -10,83 +22,109 @@ QObject - - Manual - Manuel + + + Search for "%1" in the full text + Rechercher "%1" dans tout le texte - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Le manuel est conçu pour aider les utilisateurs à utiliser le système d'exploitation et ses applications, en fournissant des instructions spécifiques et des descriptions de fonctions. + + The content was updated + Le contenu a été mis à jour + + + + Search + Rechercher + + + + + Support + Support + + + + Copy + Copie + + + + Quick Start + - + + Video Guide + + + + System Système - + Applications Applications - + No search results Aucun résultat trouvé - + Home Accueil - + result résultat - + results résultats - - Search - Rechercher + + Click to view + - - Support - Support + + View all + - - The content was updated - Le contenu a été mis à jour + + App Store + - - Copy - Copie + + Manual + - - - Search for "%1" in the full text - Rechercher "%1" dans tout le texte + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_gl_ES.ts b/translations/deepin-manual_gl_ES.ts index 5d6619bd3..7288a814e 100755 --- a/translations/deepin-manual_gl_ES.ts +++ b/translations/deepin-manual_gl_ES.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - Manual + + + Search for "%1" in the full text + Buscar por "%1" en todo o texto - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - O manual está deseñado para axudar aos usuarios a aprender o sistema operativo e os seus aplicativos, proporcionando instrucións específicas e descricións de funcións. + + The content was updated + Actualizouse o contido + + + + Search + Buscar + + + + + Support + Axuda + + + + Copy + Copiar + + + + Quick Start + - + + Video Guide + + + + System Sistema - + Applications Aplicativos - + No search results Non hai resultados para a súa busca - + Home Inicio - + result resultado - + results resultados - - Search - Buscar + + Click to view + - - Support - Axuda + + View all + - - The content was updated - Actualizouse o contido + + App Store + - - Copy - Copiar + + Manual + - - - Search for "%1" in the full text - Buscar por "%1" en todo o texto + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_hi_IN.ts b/translations/deepin-manual_hi_IN.ts index b8f46c1d6..90753508c 100644 --- a/translations/deepin-manual_hi_IN.ts +++ b/translations/deepin-manual_hi_IN.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + डेस्कटॉप वातावरण QObject - - Manual - गाइड + + + Search for "%1" in the full text + "%1" को संपूर्ण टेक्स्ट में खोजें - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - इस गाइड का उद्देश्य उपयोक्ताओं को ऑपरेटिंग सिस्टम व अनुप्रयोगों को सीखने में सहायता करना, विशिष्ट निर्देशों व विशेषताओं के विवरण प्रदान करना है। + + The content was updated + सामग्री अपडेट की गई + + + + Search + खोजें + + + + + Support + समर्थन + + + + Copy + कॉपी करें + + + + Quick Start + - + + Video Guide + + + + System सिस्टम - + Applications अनुप्रयोग - + No search results खोज का कोई परिणाम नहीं मिला - + Home होम - + result परिणाम - + results परिणाम - - Search - खोजें + + Click to view + - - Support - समर्थन + + View all + - - The content was updated - सामग्री अपडेट की गई + + App Store + - - Copy - कॉपी करें + + Manual + - - - Search for "%1" in the full text - "%1" को संपूर्ण टेक्स्ट में खोजें + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_hr.ts b/translations/deepin-manual_hr.ts index 3ebe7e220..b7671335e 100644 --- a/translations/deepin-manual_hr.ts +++ b/translations/deepin-manual_hr.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - Priručnik + + + Search for "%1" in the full text + Traži "%1" u cijelom tekstu - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Priručnik je oblikovan da pomogne korisnicima učiti o operativnom sustavu i programima, donoseći specifične savjete i opise funkcija. + + The content was updated + + + + + Search + Traži + + + + + Support + Podrška + + + + Copy + Kopiraj + + + + Quick Start + - + + Video Guide + + + + System Sustav - + Applications Programi - + No search results Nema razultata pretrage - + Home Osobna mapa - + result razultat - + results rezultati - - Search - Traži + + Click to view + - - Support - Podrška + + View all + - - The content was updated - + + App Store + - - Copy - Kopiraj + + Manual + - - - Search for "%1" in the full text - Traži "%1" u cijelom tekstu + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_hu.ts b/translations/deepin-manual_hu.ts index e690bd126..3a58b1fee 100644 --- a/translations/deepin-manual_hu.ts +++ b/translations/deepin-manual_hu.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Alapvető műveletek megismerése + + + + Common Application Libraries + Közös alkalmazás könyvtárak + + + Desktop Environment Asztali Környezet @@ -10,83 +22,109 @@ QObject - - Manual - Kézikönyv + + + Search for "%1" in the full text + "% 1" kifejezés keresése a teljes szövegben - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - A Kézikönyv célja, hogy segítse a felhasználókat az operációs rendszer és alkalmazásainak megismerésében, konkrét utasításokat és funkcióleírásokat biztosítva. + + The content was updated + A tartalom frissítve + + + + Search + Keresés + + + + + Support + Támogatás + + + + Copy + Másolás + + + + Quick Start + Gyors Kezdés - + + Video Guide + Videó útmutató + + + System Rendszer - + Applications Alkalmazások - + No search results Nincs keresési eredmény - + Home Főoldal - + result eredmény - + results eredmények - - Search - Keresés + + Click to view + Kattintson a megtekintéshez - - Support - Támogatás + + View all + Összes megtekintése - - The content was updated - A tartalom frissítve + + App Store + - - Copy - Másolás + + Manual + - - - Search for "%1" in the full text - "% 1" kifejezés keresése a teljes szövegben + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_id.ts b/translations/deepin-manual_id.ts index 0d0927c49..027cdfcfb 100755 --- a/translations/deepin-manual_id.ts +++ b/translations/deepin-manual_id.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - Manual Deepin + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - Deepin Manual di desain untuk membantu pengguna dalam mempelajari deepin dan aplikasi Deepin, menyediakan instruksi yang spesifik dan juga deskripsi fungsi nya. + + The content was updated + - + + Search + Pencarian + + + + + Support + + + + Copy Salin - + + Quick Start + + + + + Video Guide + + + + System Sistem - + Applications Aplikasi - - Sorry, there are no search results of "%1" - Maaf, hasil pencarian dari "%1" tidak di temukan + + No search results + Tidak ada hasil pencarian - - Change your keywords and try again, or search it in Deepin Wiki - Ganti kata kunci anda dan coba lagi, atau cari di Deepin Wiki - - - + Home Home - - Deepin Wiki - Deepin Wiki + + result + hasil - - - Search "%1" in the full text - Cari "%1" in dalam kalimat + + results + hasil - - Search - Pencarian + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + Ctrl+Alt+F + + + + Ctrl+F + Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_it.ts b/translations/deepin-manual_it.ts index 0b9219eaf..086fd0010 100755 --- a/translations/deepin-manual_it.ts +++ b/translations/deepin-manual_it.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Desktop Environment @@ -10,84 +22,109 @@ QObject - - Manual - Manual + + + Search for "%1" in the full text + Ricerca di "%1" anche nei contenuti - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Manual nasce per aiutare l'utenza all'utilizzo del Sistema Operativo ed alle Applicazioni native, fornendo istruzioni specifiche e descrivendo le singole funzionalità. -Localizzazione italiana a cura di Massimo A. Carofano. + + The content was updated + Il contenuto è stato aggiornato + + + + Search + Cerca + + + + + Support + Supporto + + + + Copy + Copia + + + + Quick Start + - + + Video Guide + + + + System Sistema - + Applications Applicazioni - + No search results Nessun risultato - + Home Home - + result risultato - + results risultati - - Search - Cerca + + Click to view + - - Support - Supporto + + View all + - - The content was updated - Il contenuto è stato aggiornato + + App Store + - - Copy - Copia + + Manual + - - - Search for "%1" in the full text - Ricerca di "%1" anche nei contenuti + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ja.ts b/translations/deepin-manual_ja.ts index d478cd496..c8e142ea7 100755 --- a/translations/deepin-manual_ja.ts +++ b/translations/deepin-manual_ja.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - Deepin マニュアル + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - DeepinマニュアルはユーザーがdeepinやDeepinアプリケーションについて学ぶために設計されており、具体的な指示や機能の説明などを提供します。 + + The content was updated + - + + Search + 検索 + + + + + Support + + + + Copy コピー - + + Quick Start + + + + + Video Guide + + + + System システム - + Applications アプリケーション - - Sorry, there are no search results of "%1" - "%1"の検索結果が見つかりませんでした + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - キーワードを変えてもう一度検索するか、Deepin Wikiで検索してください - - - + Home ホーム - - Deepin Wiki - Deepin Wiki + + result + - - - Search "%1" in the full text - "%1"を全文検索 + + results + - - Search - 検索 + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_ko.ts b/translations/deepin-manual_ko.ts index a0ee5d43a..314798e77 100755 --- a/translations/deepin-manual_ko.ts +++ b/translations/deepin-manual_ko.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - 설명서 + + + Search for "%1" in the full text + 전체 텍스트에서 "%1" 검색 - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - 설명서는 사용자가 특정 지침 및 기능 설명을 제공, 운영 체제와 응용 프로그램을 배울 수 있도록 설계되었습니다. + + The content was updated + + + + + Search + 검색 + + + + + Support + 지원 + + + + Copy + 복사 + + + + Quick Start + - + + Video Guide + + + + System 시스템 - + Applications 응용프로그램 - + No search results 검색 결과 없음 - + Home - + result 결과 - + results 결과 - - Search - 검색 + + Click to view + - - Support - 지원 + + View all + - - The content was updated - + + App Store + - - Copy - 복사 + + Manual + - - - Search for "%1" in the full text - 전체 텍스트에서 "%1" 검색 + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_lt.ts b/translations/deepin-manual_lt.ts index 3bedf7d76..050a09a52 100755 --- a/translations/deepin-manual_lt.ts +++ b/translations/deepin-manual_lt.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + QObject - - Manual - Žinynas + + + Search for "%1" in the full text + Ieškoti "%1" visame tekste - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Žinynas yra sukurtas, kad padėtų naudotojams išmokti naudotis operacine sistema ir jos programomis, jame yra pateikiamos tam tikros instrukcijos ir funkcijų aprašai. + + The content was updated + + + + + Search + Ieškoti + + + + + Support + + + + + Copy + Kopijuoti + + + + Quick Start + - + + Video Guide + + + + System Sistema - + Applications Programos - + No search results Nėra jokių paieškos rezultatų - + Home Pradžia - + result rezultatas - + results rezultatų(-ai) - - Search - Ieškoti + + Click to view + - - Support - + + View all + - - The content was updated - + + App Store + - - Copy - Kopijuoti + + Manual + - - - Search for "%1" in the full text - Ieškoti "%1" visame tekste + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Vald+Alt+F - + Ctrl+F Vald+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ms.ts b/translations/deepin-manual_ms.ts index 33684a015..1b2eb0731 100755 --- a/translations/deepin-manual_ms.ts +++ b/translations/deepin-manual_ms.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + Persekitaran Atas Meja QObject - - Manual - Panduan + + + Search for "%1" in the full text + Gelintar "%1" dalam teks penuh - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Panduan Deepin direka untuk membantu pengguna mempelajari sistem pengoperasian deepin dan aplikasi-aplikasinya, menyediakan arahan dan keterangan fungsi dengan lebih mendalam. + + The content was updated + Kandungan telah dikemas kini + + + + Search + Gelintar + + + + + Support + Sokongan + + + + Copy + Salin + + + + Quick Start + - + + Video Guide + + + + System Sistem - + Applications Aplikasi - + No search results Tiada keputusan gelintar - + Home Rumah - + result keputusan - + results keputusan - - Search - Gelintar + + Click to view + - - Support - + + View all + - - The content was updated - + + App Store + - - Copy - Salin + + Manual + - - - Search for "%1" in the full text - Gelintar "%1" dalam teks penuh + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_nl.ts b/translations/deepin-manual_nl.ts index 9ebf2d887..e7a497fe5 100755 --- a/translations/deepin-manual_nl.ts +++ b/translations/deepin-manual_nl.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + Basishandelingen leren + + + + Common Application Libraries + Veelvoorkomende programmabibliotheken + + + Desktop Environment - + Werkomgeving QObject - - Manual - Handleiding + + + Search for "%1" in the full text + '%1' zoeken in de hele tekst - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Handleiding is ontworpen om gebruikers te helpen met het besturingssysteem en de programma's. Het bevat instructies en functie-omschrijvingen, zodat gebruikers het systeem kunnen leren gebruiken. + + The content was updated + De inhoud is bijgewerkt + + + + Search + Zoeken + + + + + Support + Ondersteuning + + + + Copy + Kopiëren + + + + Quick Start + Snelstartgids - + + Video Guide + Videogids + + + System Systeem - + Applications Programma's - + No search results Geen zoekresultaten - + Home Start - + result resultaat - + results resultaten - - Search - Zoeken + + Click to view + Klik om te bekijken - - Support - Ondersteuning + + View all + Alles bekijken - - The content was updated - De inhoud is bijgewerkt + + App Store + - - Copy - Kopiëren + + Manual + - - - Search for "%1" in the full text - '%1' zoeken in de hele tekst + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_pl.ts b/translations/deepin-manual_pl.ts index d270d2009..255df250b 100755 --- a/translations/deepin-manual_pl.ts +++ b/translations/deepin-manual_pl.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + Poznaj podstawowe operacje + + + + Common Application Libraries + Powszechne biblioteki aplikacji + + + Desktop Environment - + Środowisko pulpitowe QObject - - Manual - Podręcznik + + + Search for "%1" in the full text + Szukaj „%1” w całym tekście - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Podręcznik ma na celu pomóc użytkownikom w nauce systemu operacyjnego i jego aplikacji, zapewniając szczegółowe instrukcje i opisy funkcji. + + The content was updated + Zawartość została zaktualizowana + + + + Search + Szukaj + + + + + Support + Wsparcie - + + Copy + Kopiuj + + + + Quick Start + Szybki start + + + + Video Guide + Poradnik wideo + + + System System - + Applications Programy - + No search results Brak wyników wyszukiwania - + Home - Start + Główna - + result - wynik + wynik - + results - wyniki + wyniki - - Search - Szukaj + + Click to view + Kliknij, aby wyświetlić - - Support - Wsparcie + + View all + Zobacz wszystko - - The content was updated - + + App Store + - - Copy - Kopiuj + + Manual + - - - Search for "%1" in the full text - Wyszukaj „%1” w pełnym tekście + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_pt.ts b/translations/deepin-manual_pt.ts index cebcb6d7d..14d7c7ddd 100755 --- a/translations/deepin-manual_pt.ts +++ b/translations/deepin-manual_pt.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Ambiente de trabalho @@ -10,83 +22,109 @@ QObject - - Manual - Manual + + + Search for "%1" in the full text + Pesquisar por "%1" no texto todo - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - O Manual foi projetado para ajudar os utilizadores a aprender mais sobre o sistema operativo e suas aplicações, fornecendo instruções específicas e descrições de funções. + + The content was updated + O conteúdo foi atualizado + + + + Search + Pesquisar + + + + + Support + Suporte + + + + Copy + Copiar + + + + Quick Start + - + + Video Guide + + + + System Sistema - + Applications Aplicações - + No search results Nenhum resultado correspondente à pesquisa - + Home Início - + result resultado - + results resultados - - Search - Pesquisar + + Click to view + - - Support - Suporte + + View all + - - The content was updated - O conteúdo foi atualizado + + App Store + - - Copy - Copiar + + Manual + - - - Search for "%1" in the full text - Pesquisar por "%1" no texto todo + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_pt_BR.ts b/translations/deepin-manual_pt_BR.ts index a66888dd0..f200f7c9b 100755 --- a/translations/deepin-manual_pt_BR.ts +++ b/translations/deepin-manual_pt_BR.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Desktop Environment @@ -10,83 +22,109 @@ QObject - - Manual - Manual + + + Search for "%1" in the full text + Pesquisar por "%1" em todo o texto - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - O Manual foi desenvolvido para ajudar os usuários a aprender a usar o sistema operacional e aplicativos; fornecendo instruções específicas e descrição das funções. + + The content was updated + O conteúdo foi atualizado + + + + Search + Pesquisar + + + + + Support + Suporte + + + + Copy + Copiar + + + + Quick Start + - + + Video Guide + + + + System Sistema - + Applications Aplicativos - + No search results Nenhum resultado de pesquisa - + Home Início - + result resultado - + results resultados - - Search - Pesquisar + + Click to view + - - Support - Suporte + + View all + - - The content was updated - O conteúdo foi atualizado + + App Store + - - Copy - Copiar + + Manual + - - - Search for "%1" in the full text - Pesquisar por "%1" em todo o texto + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ru.ts b/translations/deepin-manual_ru.ts index 8f8b1eca9..7c581a4f3 100755 --- a/translations/deepin-manual_ru.ts +++ b/translations/deepin-manual_ru.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + Среда рабочего стола QObject - - Manual - Руководство + + + Search for "%1" in the full text + Искать «%1» во всём тексте - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Руководство предназначено для того, чтобы помочь пользователям изучить операционную систему и её приложения, предоставляя конкретные инструкции и описания функций. + + The content was updated + Содержание было обновлено + + + + Search + Поиск + + + + + Support + Поддержка + + + + Copy + Копировать + + + + Quick Start + - + + Video Guide + + + + System Система - + Applications Приложения - + No search results Поиск не дал результатов - + Home Главная - + result результат - + results результаты - - Search - Поиск + + Click to view + - - Support - Поддержка + + View all + - - The content was updated - Содержание было обновлено + + App Store + - - Copy - Копировать + + Manual + - - - Search for "%1" in the full text - Искать «%1» во всём тексте + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_sk.ts b/translations/deepin-manual_sk.ts index 50a587ec3..685a63d50 100755 --- a/translations/deepin-manual_sk.ts +++ b/translations/deepin-manual_sk.ts @@ -1,61 +1,130 @@ - + + + + + ManualProxy + + + Learn Basic Operations + + + + + Common Application Libraries + + + + + Desktop Environment + + + QObject - - Deepin Manual - Deepin Manuál + + + Search for "%1" in the full text + - - Deepin Manual is designed to help users learn deepin and Deepin applications, providing specific instructions and function descriptions. - Deepin Manual je navrhnutý tak, aby pomohol používateľom učiť sa z aplikácií Deepin, ktoré poskytujú špecifické pokyny a popisy funkcií. + + The content was updated + - + + Search + Vyhľadávanie + + + + + Support + + + + Copy Kopírovať - + + Quick Start + + + + + Video Guide + + + + System Systém - + Applications Aplikácie - - Sorry, there are no search results of "%1" - Ľutujeme, ale neexistujú žiadne výsledky vyhľadávania pre "%1" + + No search results + - - Change your keywords and try again, or search it in Deepin Wiki - Zmeňte svoje kľúčové slová a skúste to znova alebo ich vyhľadajte na Deepin Wiki - - - + Home Domov - - Deepin Wiki - Deepin Wiki + + result + - - - Search "%1" in the full text - Vyhľadať "%1" v plnom znení + + results + - - Search - Vyhľadávanie + + Click to view + + + + + View all + + + + + App Store + + + + + Manual + + + + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + + + + + WebWindow + + + Ctrl+Alt+F + + + + + Ctrl+F + - \ No newline at end of file + diff --git a/translations/deepin-manual_sl.ts b/translations/deepin-manual_sl.ts index 89ff658dd..0256e669b 100755 --- a/translations/deepin-manual_sl.ts +++ b/translations/deepin-manual_sl.ts @@ -1,92 +1,130 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment - + Namizno okolje QObject - - Manual - Priročnik + + + Search for "%1" in the full text + Poišči "%1" v celotnem besedilu - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Priročnik je zasnovan za pomoč uporabnikom pri učenju rabe operacijskega sistema in njegovih programov. Vsebuje specifična navodila in opise funkcij. + + The content was updated + Vsebina je bila posodobljena + + + + Search + Išči + + + + + Support + Podpora + + + + Copy + Kopija + + + + Quick Start + - + + Video Guide + + + + System Sistem - + Applications Programi - + No search results Ni rezultatov iskanj - + Home Domov - + result rezultat - + results rezultati - - Search - Išči + + Click to view + - - Support - Podpora + + View all + - - The content was updated - Vsebina je bila posodobljena + + App Store + - - Copy - Kopija + + Manual + - - - Search for "%1" in the full text - Poišči "%1" v celotnem besedilu + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_sq.ts b/translations/deepin-manual_sq.ts index 976dba659..f28c17c22 100644 --- a/translations/deepin-manual_sq.ts +++ b/translations/deepin-manual_sq.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Mësoni Veprime Elementare + + + + Common Application Libraries + Biblioteka të Rëndomta Aplikacionesh + + + Desktop Environment Mjedis Desktop @@ -10,83 +22,109 @@ QObject - - Manual - Doracak + + + Search for "%1" in the full text + Kërko për "%1" në tërë tekstin - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Doracaku është konceptuar të ndihmojë përdoruesit të mësojnë sistemin operativ dhe aplikacionet e tij, duke dhënë udhëzime specifike dhe përshkrime funksionesh. + + The content was updated + Lënda u përditësua + + + + Search + Kërko + + + + + Support + Asistencë + + + + Copy + Kopjoje + + + + Quick Start + Nisje e Shpejtë - + + Video Guide + Udhërrëfyes Video + + + System Sistem - + Applications Aplikacione - + No search results S’ka përfundime kërkimi - + Home Kreu - + result përfundim - + results përfundime - - Search - Kërko + + Click to view + Klikoni për ta parë - - Support - Asistencë + + View all + Shihini krejt - - The content was updated - Lënda u përditësua + + App Store + - - Copy - Kopjoje + + Manual + - - - Search for "%1" in the full text - Kërko për "%1" në tërë tekstin + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_sr.ts b/translations/deepin-manual_sr.ts index f7b194fb7..49234a646 100755 --- a/translations/deepin-manual_sr.ts +++ b/translations/deepin-manual_sr.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Радно окружење @@ -10,83 +22,109 @@ QObject - - Manual - Приручник + + + Search for "%1" in the full text + Тражи "%1" у целом тексту - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Приручник је састављен тако да помогне корисницима да изуче оперативни систем и програме, нудећи усмерена упутства и описе функција. + + The content was updated + Садржај је ажуриран + + + + Search + Претражи + + + + + Support + Подршка + + + + Copy + Копирај + + + + Quick Start + - + + Video Guide + + + + System Систем - + Applications Програми - + No search results Нема резултата претраге - + Home Почетак - + result резултат - + results резултата - - Search - Претражи + + Click to view + - - Support - Подршка + + View all + - - The content was updated - Садржај је ажуриран + + App Store + - - Copy - Копирај + + Manual + - - - Search for "%1" in the full text - Тражи "%1" у целом тексту + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_tr.ts b/translations/deepin-manual_tr.ts index dc63e42a0..90ad4485b 100755 --- a/translations/deepin-manual_tr.ts +++ b/translations/deepin-manual_tr.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + + + + + Common Application Libraries + + + + Desktop Environment Masaüstü Ortamı @@ -10,83 +22,109 @@ QObject - - Manual - Kılavuz + + + Search for "%1" in the full text + Tam metinde "%1" ifadesini ara - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - Kılavuz, kullanıcıların işletim sistemini ve uygulamalarını öğrenmelerine yardımcı olmak için özel talimatlar ve işlev açıklamaları sağlamak üzere tasarlanmıştır. + + The content was updated + İçerik güncellendi + + + + Search + Ara + + + + + Support + Destek + + + + Copy + Kopyala + + + + Quick Start + - + + Video Guide + + + + System Sistem - + Applications Uygulamalar - + No search results Arama sonucu bulunamadı - + Home Ana Sayfa - + result sonuç - + results sonuçlar - - Search - Ara + + Click to view + - - Support - Destek + + View all + - - The content was updated - İçerik güncellendi + + App Store + - - Copy - Kopyala + + Manual + - - - Search for "%1" in the full text - Tam metinde "%1" ifadesini ara + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_ug.ts b/translations/deepin-manual_ug.ts index 620ab5d0c..90ffa34bd 100755 --- a/translations/deepin-manual_ug.ts +++ b/translations/deepin-manual_ug.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + ئاساسىي مەشغۇلاتنى چۈشىنىش + + + + Common Application Libraries + دائىملىق ئەپلەر + + + Desktop Environment ئۈستەليۈزى مۇھىتى @@ -10,83 +22,109 @@ QObject - - Manual - قوللانما + + + Search for "%1" in the full text + “%1”پۈتۈن مەزمۇن ئىچىدىن ئىزدەۋاتىدۇ - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - قوللانما ئىشلەتكۈچىلەرنىڭ مەشغۇلات سىستېمىسى ۋە ئۇنىڭ قوللىنىشچان پىروگراممىلىرىنى چۈشىنىشىگە ياردەم بېرىش ھەمدە كونكرېت چۈشەندۈرۈش ۋە ئىقتىدار چۈشەندۈرۈشى بىلەن تەمىنلەشنى مەقسەت قىلغان + + The content was updated + نۆۋەتتتىكى مەزمۇن يېڭىلانغان + + + + Search + ئىزدەش + + + + + Support + قوللاش + + + + Copy + نۇسخىلاش + + + + Quick Start + تېزدىن تونۇشۇش - + + Video Guide + سىن كۆرسەتمىسى + + + System سېستىما - + Applications پروگراممىلار - + No search results ئىزدەش نەتىجىسى يوق - + Home باش بەت - + result نەتىجە - + results نەتىجە - - Search - ئىزدەش + + Click to view + چېكىپ كۆرۈش - - Support - قوللاش + + View all + ھەممىنى كۆرۈش - - The content was updated - نۆۋەتتتىكى مەزمۇن يېڭىلانغان + + App Store + - - Copy - نۇسخىلاش + + Manual + - - - Search for "%1" in the full text - “%1”پۈتۈن مەزمۇن ئىچىدىن ئىزدەۋاتىدۇ + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_uk.ts b/translations/deepin-manual_uk.ts index 8b94e3118..d78b02c8f 100755 --- a/translations/deepin-manual_uk.ts +++ b/translations/deepin-manual_uk.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + Вивчення основних дій + + + + Common Application Libraries + Загальні бібліотеки програм + + + Desktop Environment Стільничне середовище @@ -10,83 +22,109 @@ QObject - - Manual - Підручник + + + Search for "%1" in the full text + Шукати «%1» у всьому тексті - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - «Підручник» створено для того, щоб допомогти користувачам, які вивчають операційну систему та її програми. За допомогою цієї програми ви знайдете специфічні настанови та описи функціональних можливостей. + + The content was updated + Дані було оновлено + + + + Search + Шукати + + + + + Support + Підтримка + + + + Copy + Копіювати + + + + Quick Start + Короткий довідник - + + Video Guide + Відеопідручник + + + System Система - + Applications Програми - + No search results Нічого не знайдено - + Home Домівка - + result результат - + results результатів - - Search - Шукати + + Click to view + Натисніть, щоб переглянути - - Support - Підтримка + + View all + Переглянути усе - - The content was updated - Дані було оновлено + + App Store + - - Copy - Копіювати + + Manual + - - - Search for "%1" in the full text - Шукати «%1» у всьому тексті + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_zh_CN.ts b/translations/deepin-manual_zh_CN.ts index c404f46b3..687b15017 100755 --- a/translations/deepin-manual_zh_CN.ts +++ b/translations/deepin-manual_zh_CN.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + 了解基本操作 + + + + Common Application Libraries + 常用应用库 + + + Desktop Environment 桌面环境 @@ -10,83 +22,109 @@ QObject - - Manual - 帮助手册 + + + Search for "%1" in the full text + 在全文中搜索“%1” - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - 帮助手册为帮助用户了解此操作系统及其系列应用,提供具体的使用方法和功能说明。 + + The content was updated + 当前内容已更新 + + + + Search + 搜索 + + + + + Support + 服务与支持 + + + + Copy + 复制 - + + Quick Start + 快速入门 + + + + Video Guide + 视频指南 + + + System 系统 - + Applications 应用 - + No search results 无搜索结果 - + Home 返回主页 - + result 个结果 - + results 个结果 - - Search - 搜索 + + Click to view + 点击查看 - - Support - 服务与支持 + + View all + 查看全部 - - The content was updated - 当前内容已更新 + + App Store + 应用商店 - - Copy - 复制 + + Manual + 帮助手册 - - - Search for "%1" in the full text - 在全文中搜索“%1” + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + 帮助手册为帮助用户了解此操作系统及其系列应用,提供具体的使用方法和功能说明。 WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_zh_HK.ts b/translations/deepin-manual_zh_HK.ts index 32f298e73..429f2612a 100644 --- a/translations/deepin-manual_zh_HK.ts +++ b/translations/deepin-manual_zh_HK.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + 了解基本操作 + + + + Common Application Libraries + 常用應用庫 + + + Desktop Environment 桌面環境 @@ -10,83 +22,109 @@ QObject - - Manual - 幫助手冊 + + + Search for "%1" in the full text + 在全文中搜索“%1” - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - 幫助手冊為幫助用戶了解此操作系統及其系列應用,提供具體的使用方法和功能說明。 + + The content was updated + 當前內容已更新 + + + + Search + 搜索 + + + + + Support + 服務與支持 + + + + Copy + 複製 - + + Quick Start + 快速入門 + + + + Video Guide + 影片指南 + + + System 系統 - + Applications 應用 - + No search results 無搜索結果 - + Home 返回主頁 - + result 個結果 - + results 個結果 - - Search - 搜索 + + Click to view + 點擊查看 - - Support - 服務與支持 + + View all + 查看全部 - - The content was updated - 當前內容已更新 + + App Store + 應用商店 - - Copy - 複製 + + Manual + 幫助手冊 - - - Search for "%1" in the full text - 在全文中搜索“%1” + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + 幫助手冊為幫助用戶了解此操作系統及其系列應用,提供具體的使用方法和功能說明。 WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/deepin-manual_zh_TW.ts b/translations/deepin-manual_zh_TW.ts index 3db14212e..8d146ad0a 100755 --- a/translations/deepin-manual_zh_TW.ts +++ b/translations/deepin-manual_zh_TW.ts @@ -1,8 +1,20 @@ - + + + ManualProxy - + + Learn Basic Operations + 了解基本操作 + + + + Common Application Libraries + 常用應用庫 + + + Desktop Environment 桌面環境 @@ -10,83 +22,109 @@ QObject - - Manual - 說明書 + + + Search for "%1" in the full text + 「%1」的搜尋結果 - - Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. - 說明書提供詳細的使用步驟與功能解釋,能幫助使用者了解系統與應用程式的使用。 + + The content was updated + 當前內容已更新 + + + + Search + 搜尋 + + + + + Support + 服務與支持 + + + + Copy + 複製 - + + Quick Start + 快速入門 + + + + Video Guide + 影片指南 + + + System 系統 - + Applications 應用程式 - + No search results 無搜索結果 - + Home 首頁 - + result 個結果 - + results 個結果 - - Search - 搜尋 + + Click to view + 點擊查看 - - Support - 服務與支持 + + View all + 查看全部 - - The content was updated - 當前內容已更新 + + App Store + 應用商店 - - Copy - 複製 + + Manual + 說明書 - - - Search for "%1" in the full text - 「%1」的搜尋結果 + + Manual is designed to help users learn the operating system and its applications, providing specific instructions and function descriptions. + 說明書提供詳細的使用步驟與功能解釋,能幫助使用者了解系統與應用程式的使用。 WebWindow - + Ctrl+Alt+F Ctrl+Alt+F - + Ctrl+F Ctrl+F - \ No newline at end of file + diff --git a/translations/desktop/desktop_am_ET.ts b/translations/desktop/desktop_am_ET.ts index 28510c1cf..f692d1a7c 100755 --- a/translations/desktop/desktop_am_ET.ts +++ b/translations/desktop/desktop_am_ET.ts @@ -1 +1 @@ -desktopDeepin Manualየ ዲፕኢን መምርሪያManualdocumentation;information;manual;help; \ No newline at end of file +desktopDeepin Manualየ ዲፕኢን መምርሪያManualdocumentation;information;manual;help;የ ሰነድ መምሪያ መረጃ እርዳታ \ No newline at end of file diff --git a/translations/desktop/desktop_cs.ts b/translations/desktop/desktop_cs.ts index f2c027293..567ced302 100755 --- a/translations/desktop/desktop_cs.ts +++ b/translations/desktop/desktop_cs.ts @@ -1 +1 @@ -desktopDeepin ManualPříručka k DeepinuManualPříručkadocumentation;information;manual;help;dokumentace;informace;příručka;nápověda; \ No newline at end of file +desktopDeepin ManualPříručka k systému DeepinManualPříručkadocumentation;information;manual;help;dokumentace;informace;příručka;nápověda; \ No newline at end of file diff --git a/translations/desktop/desktop_pl.ts b/translations/desktop/desktop_pl.ts index 81abd825e..63559b08d 100755 --- a/translations/desktop/desktop_pl.ts +++ b/translations/desktop/desktop_pl.ts @@ -1 +1 @@ -desktopDeepin ManualInstrukcja DeepinManualInstrukcjadocumentation;information;manual;help;documentation;information;manual;help;dokumentacja;informacje;instrukcja;pomoc; \ No newline at end of file +desktopDeepin ManualInstrukcja obsługi DeepinManualInstrukcja obsługidocumentation;information;manual;help;documentation;information;manual;help;dokumentacja;informacje;instrukcja;pomoc; \ No newline at end of file