diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..f31620d --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,66 @@ +# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程 +# +name: Deploy VitePress site to Pages + +on: + # 在针对 `main` 分支的推送上运行。如果你 + # 使用 `master` 分支作为默认分支,请将其更改为 `master` + push: + branches: [master] + + # 允许你从 Actions 选项卡手动运行此工作流程 + workflow_dispatch: + +# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列 +# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # 构建工作 + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 如果未启用 lastUpdated,则不需要 + # - uses: pnpm/action-setup@v3 # 如果使用 pnpm,请取消此区域注释 + # with: + # version: 9 + # - uses: oven-sh/setup-bun@v1 # 如果使用 Bun,请取消注释 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm # 或 pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci # 或 pnpm install / yarn install / bun install + - name: Build with VitePress + run: npm run docs:build # 或 pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # 部署工作 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 69b9a1f..7dd5fff 100755 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ _site +.vitepress/cache +docs/.vitepress/cache +docs/.vitepress/dist node_modules npm-debug.log .DS_Store */.DS_Store */*/.DS_Store #*.sh -.vitepress/cache -docs/.vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/dist/404.html b/docs/.vitepress/dist/404.html index ce3d67b..6fb0428 100644 --- a/docs/.vitepress/dist/404.html +++ b/docs/.vitepress/dist/404.html @@ -3,20 +3,20 @@ - 404 | my blog project + 404 | 前端技术知识库 - + - +
- + \ No newline at end of file diff --git a/docs/.vitepress/dist/README.zh.html b/docs/.vitepress/dist/README.zh.html new file mode 100644 index 0000000..b8db5ed --- /dev/null +++ b/docs/.vitepress/dist/README.zh.html @@ -0,0 +1,25 @@ + + + + + + Fei blog | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Fei blog

我的博客在这里 →

致谢

  1. 这个模板是从这里IronSummitMedia/startbootstrap-clean-blog-jekyll fork 的。 感谢这个作者
  2. 感谢 Jekyll、Github Pages 和 Bootstrap!

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/api-examples.html b/docs/.vitepress/dist/api-examples.html deleted file mode 100644 index a27cdb1..0000000 --- a/docs/.vitepress/dist/api-examples.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - Runtime API Examples | my blog project - - - - - - - - - - - - - - -
Skip to content

Runtime API Examples

This page demonstrates usage of some of the runtime APIs provided by VitePress.

The main useData() API can be used to access site, theme, and page data for the current page. It works in both .md and .vue files:

md
<script setup>
-import { useData } from 'vitepress'
-
-const { theme, page, frontmatter } = useData()
-</script>
-
-## Results
-
-### Theme Data
-<pre>{{ theme }}</pre>
-
-### Page Data
-<pre>{{ page }}</pre>
-
-### Page Frontmatter
-<pre>{{ frontmatter }}</pre>

Results

Theme Data

{
-  "nav": [
-    {
-      "text": "Home",
-      "link": "/"
-    },
-    {
-      "text": "Examples",
-      "link": "/markdown-examples"
-    }
-  ],
-  "sidebar": [
-    {
-      "text": "Examples",
-      "items": [
-        {
-          "text": "Markdown Examples",
-          "link": "/markdown-examples"
-        },
-        {
-          "text": "Runtime API Examples",
-          "link": "/api-examples"
-        }
-      ]
-    }
-  ],
-  "socialLinks": [
-    {
-      "icon": "github",
-      "link": "https://github.com/vuejs/vitepress"
-    }
-  ]
-}

Page Data

{
-  "title": "Runtime API Examples",
-  "description": "",
-  "frontmatter": {
-    "outline": "deep"
-  },
-  "headers": [],
-  "relativePath": "api-examples.md",
-  "filePath": "api-examples.md"
-}

Page Frontmatter

{
-  "outline": "deep"
-}

More

Check out the documentation for the full list of runtime APIs.

- - - - \ No newline at end of file diff --git a/docs/.vitepress/dist/assets/Attributes Inspector@2x.B2mpndFp.png b/docs/.vitepress/dist/assets/Attributes Inspector@2x.B2mpndFp.png new file mode 100644 index 0000000..7b50008 Binary files /dev/null and b/docs/.vitepress/dist/assets/Attributes Inspector@2x.B2mpndFp.png differ diff --git a/docs/.vitepress/dist/assets/DAG_2x.NtzGJ5bn.png b/docs/.vitepress/dist/assets/DAG_2x.NtzGJ5bn.png new file mode 100644 index 0000000..3c15390 Binary files /dev/null and b/docs/.vitepress/dist/assets/DAG_2x.NtzGJ5bn.png differ diff --git a/docs/.vitepress/dist/assets/Identity Inspector@2x.CkbcHy2u.png b/docs/.vitepress/dist/assets/Identity Inspector@2x.CkbcHy2u.png new file mode 100644 index 0000000..7caece9 Binary files /dev/null and b/docs/.vitepress/dist/assets/Identity Inspector@2x.CkbcHy2u.png differ diff --git a/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.js b/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.js new file mode 100644 index 0000000..c6dd4a3 --- /dev/null +++ b/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"Fei blog","description":"","frontmatter":{},"headers":[],"relativePath":"README.zh.md","filePath":"README.zh.md"}'),l={name:"README.zh.md"};function i(s,a,h,n,p,_){return r(),t("div",null,a[0]||(a[0]=[o('

Fei blog

我的博客在这里 →

致谢

  1. 这个模板是从这里IronSummitMedia/startbootstrap-clean-blog-jekyll fork 的。 感谢这个作者
  2. 感谢 Jekyll、Github Pages 和 Bootstrap!
',5)]))}const g=e(l,[["render",i]]);export{d as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.lean.js b/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.lean.js new file mode 100644 index 0000000..8bc3a58 --- /dev/null +++ b/docs/.vitepress/dist/assets/README.zh.md.CUr6FBXy.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"Fei blog","description":"","frontmatter":{},"headers":[],"relativePath":"README.zh.md","filePath":"README.zh.md"}'),l={name:"README.zh.md"};function i(s,a,h,n,p,_){return r(),t("div",null,a[0]||(a[0]=[o("",5)]))}const g=e(l,[["render",i]]);export{d as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.lean.js b/docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.lean.js deleted file mode 100644 index 8b69099..0000000 --- a/docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{u as p,c as h,o,ae as d,j as a,t,k as i,a as s}from"./chunks/framework.B8KKhRA6.js";const f=JSON.parse('{"title":"Runtime API Examples","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api-examples.md","filePath":"api-examples.md"}'),m={name:"api-examples.md"},E=Object.assign(m,{setup(k){const{site:g,theme:n,page:l,frontmatter:r}=p();return(c,e)=>(o(),h("div",null,[e[0]||(e[0]=d("",6)),a("pre",null,t(i(n)),1),e[1]||(e[1]=a("h3",{id:"page-data",tabindex:"-1"},[s("Page Data "),a("a",{class:"header-anchor",href:"#page-data","aria-label":'Permalink to "Page Data"'},"​")],-1)),a("pre",null,t(i(l)),1),e[2]||(e[2]=a("h3",{id:"page-frontmatter",tabindex:"-1"},[s("Page Frontmatter "),a("a",{class:"header-anchor",href:"#page-frontmatter","aria-label":'Permalink to "Page Frontmatter"'},"​")],-1)),a("pre",null,t(i(r)),1),e[3]||(e[3]=a("h2",{id:"more",tabindex:"-1"},[s("More "),a("a",{class:"header-anchor",href:"#more","aria-label":'Permalink to "More"'},"​")],-1)),e[4]||(e[4]=a("p",null,[s("Check out the documentation for the "),a("a",{href:"https://vitepress.dev/reference/runtime-api#usedata",target:"_blank",rel:"noreferrer"},"full list of runtime APIs"),s(".")],-1))]))}});export{f as __pageData,E as default}; diff --git a/docs/.vitepress/dist/assets/app.BzPgNzxg.js b/docs/.vitepress/dist/assets/app.CBlqR7aR.js similarity index 81% rename from docs/.vitepress/dist/assets/app.BzPgNzxg.js rename to docs/.vitepress/dist/assets/app.CBlqR7aR.js index e112d51..e157280 100644 --- a/docs/.vitepress/dist/assets/app.BzPgNzxg.js +++ b/docs/.vitepress/dist/assets/app.CBlqR7aR.js @@ -1 +1 @@ -import{R as p}from"./chunks/theme.D24d9p6K.js";import{R as s,a1 as i,a2 as u,a3 as c,a4 as l,a5 as f,a6 as d,a7 as m,a8 as h,a9 as g,aa as A,d as v,u as R,v as w,s as y,ab as C,ac as P,ad as b,a0 as E}from"./chunks/framework.B8KKhRA6.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp}; +import{R as p}from"./chunks/theme.Cwh4Yq8A.js";import{R as s,a3 as i,a4 as u,a5 as c,a6 as l,a7 as f,a8 as d,a9 as m,aa as h,ab as g,ac as A,d as v,u as R,v as w,s as y,ad as C,ae as P,af as b,a2 as E}from"./chunks/framework.BHpayLOB.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp}; diff --git a/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.js b/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.js new file mode 100644 index 0000000..3f18061 --- /dev/null +++ b/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.js @@ -0,0 +1,15 @@ +import{_ as e,C as s,c as o,o as p,ag as r,G as i,j as n}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"Tomcat 介绍","description":"","frontmatter":{},"headers":[],"relativePath":"backend/container/tomcat.md","filePath":"backend/container/tomcat.md"}'),l={name:"backend/container/tomcat.md"};function c(u,a,m,d,g,h){const t=s("Connector");return p(),o("div",null,[a[0]||(a[0]=r(`

Tomcat 介绍

Tomcat用户密码 修改conf-> tomcat-users.xml 文件,添加角色、用户、密码

<tomcat-users>
+<!--
+  NOTE:  By default, no user is included in the "manager-gui" role required
+  to operate the "/manager/html" web application.  If you wish to use this app,
+  you must define such a user - the username and password are arbitrary. It is
+  strongly recommended that you do NOT use one of the users in the commented out
+  section below since they are intended for use with the examples web
+  application.
+-->
+
+<role rolename="manager-gui"/>
+<role rolename="manager-script"/>
+<user username="tomcat" password="123456" roles="manager-gui,manager-script"/>
+
+</tomcat-users>

注意:使用Linux 开发过程 需要修改tomcat的访问权限

1.get 请求传送的参数包含中文字符

常用的解决方式: 1.当客户端使用的UTF-8编码 将中文参数传送过来时,tomcat 默认采用iso8859-1解码 ''' String name = request.getParameter("name"); name = new String(name.getBytes("iso8859-1"),"utf-8"); '''

2.在tomcat中找到server.xml文件 增加字段 URIEncoding useBodyEncodingForURI '''

`,7)),i(t,{connectionTimeout:"20000",port:"8080",protocol:"HTTP/1.1",redirectPort:"8443",URIEncoding:"UTF-8",useBodyEncodingForURI:"true"}),a[1]||(a[1]=n("p",null,"'''",-1)),a[2]||(a[2]=n("p",null,'date: 2018-08-12 16:00:00 author: "Gao Fei"',-1))])}const f=e(l,[["render",c]]);export{_ as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.lean.js b/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.lean.js new file mode 100644 index 0000000..e12da88 --- /dev/null +++ b/docs/.vitepress/dist/assets/backend_container_tomcat.md.Dg9oMqSB.lean.js @@ -0,0 +1 @@ +import{_ as e,C as s,c as o,o as p,ag as r,G as i,j as n}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"Tomcat 介绍","description":"","frontmatter":{},"headers":[],"relativePath":"backend/container/tomcat.md","filePath":"backend/container/tomcat.md"}'),l={name:"backend/container/tomcat.md"};function c(u,a,m,d,g,h){const t=s("Connector");return p(),o("div",null,[a[0]||(a[0]=r("",7)),i(t,{connectionTimeout:"20000",port:"8080",protocol:"HTTP/1.1",redirectPort:"8443",URIEncoding:"UTF-8",useBodyEncodingForURI:"true"}),a[1]||(a[1]=n("p",null,"'''",-1)),a[2]||(a[2]=n("p",null,'date: 2018-08-12 16:00:00 author: "Gao Fei"',-1))])}const f=e(l,[["render",c]]);export{_ as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.js b/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.js new file mode 100644 index 0000000..2dbe194 --- /dev/null +++ b/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.js @@ -0,0 +1,4 @@ +import{_ as e,c as s,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const v=JSON.parse('{"title":"maven 介绍","description":"","frontmatter":{},"headers":[],"relativePath":"backend/release/maven-first.md","filePath":"backend/release/maven-first.md"}'),p={name:"backend/release/maven-first.md"};function i(l,a,o,c,r,d){return n(),s("div",null,a[0]||(a[0]=[t(`

maven 介绍

maven 安装

  1. 下载 maven
  2. 解压
mv apache-maven-3.5.4 /usr/local/maven3
# maven home
+MAVEN_HOME=/usr/local/maven3
+export MAVEN_HOME
+export PATH=$PATH:$MAVEN_HOME/bin

date: 2017-11-27 16:00:00 author: "Gao Fei"

`,6)]))}const h=e(p,[["render",i]]);export{v as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.lean.js b/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.lean.js new file mode 100644 index 0000000..93ffe08 --- /dev/null +++ b/docs/.vitepress/dist/assets/backend_release_maven-first.md.fbrMtubv.lean.js @@ -0,0 +1 @@ +import{_ as e,c as s,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const v=JSON.parse('{"title":"maven 介绍","description":"","frontmatter":{},"headers":[],"relativePath":"backend/release/maven-first.md","filePath":"backend/release/maven-first.md"}'),p={name:"backend/release/maven-first.md"};function i(l,a,o,c,r,d){return n(),s("div",null,a[0]||(a[0]=[t("",6)]))}const h=e(p,[["render",i]]);export{v as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/bridgingheader_2x.CFOipoi_.png b/docs/.vitepress/dist/assets/bridgingheader_2x.CFOipoi_.png new file mode 100644 index 0000000..e93ae4b Binary files /dev/null and b/docs/.vitepress/dist/assets/bridgingheader_2x.CFOipoi_.png differ diff --git a/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.BXBjdp4i.js b/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.BXBjdp4i.js new file mode 100644 index 0000000..47f6c05 --- /dev/null +++ b/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.BXBjdp4i.js @@ -0,0 +1 @@ +const t='{"documentCount":398,"nextId":398,"documentIds":{"0":"/README.zh.html#fei-blog","1":"/README.zh.html#致谢","2":"/backend/container/tomcat.html#tomcat-介绍","3":"/backend/container/tomcat.html#_1-get-请求传送的参数包含中文字符","4":"/backend/release/maven-first.html#maven-介绍","5":"/engineering/#前端工程化","6":"/frontend/base/xml-tips.html#xml-常见转义字符","7":"/frontend/base/xml-tips.html#xml常见用转义字符","8":"/frontend/base/xml-tips.html#html-转义字符","9":"/frontend/ios/appstore-share.html#appstore","10":"/frontend/ios/apple-update-cert.html#更新-app-store-发布证书","11":"/frontend/ios/apple-update-cert.html#分三步去更新","12":"/frontend/ios/apple-update-cert.html#示例","13":"/frontend/ios/apple-update-cert.html#_1-确定已过期的-app-id","14":"/frontend/ios/apple-update-cert.html#_2-根据app-id重新生成certifictes","15":"/frontend/ios/download-share.html#download-issues","16":"/frontend/ios/download-share.html#下载问题","17":"/frontend/ios/download-share.html#nsoperation-的使用","18":"/frontend/ios/cocoapods.html#cocoapods-入门","19":"/frontend/ios/cocoapods.html#cocoapods-入门-1","20":"/frontend/ios/cocoapods.html#_1-cocoapods","21":"/frontend/ios/cocoapods.html#_2-初始化项目","22":"/frontend/ios/flutter.html#flutter-入门","23":"/frontend/ios/flutter.html#_1-flutter-介绍","24":"/frontend/ios/flutter.html#_2-flutter","25":"/frontend/ios/flutter.html#_3-dart","26":"/frontend/ios/framework-share.html#cocoa-touch-framework","27":"/frontend/ios/get-ipa.html#使用itunes获取ipa","28":"/frontend/ios/im-first.html#im-introduction","29":"/frontend/ios/im-first.html#im-即时通讯技术-介绍","30":"/frontend/ios/im-first.html#应用场景","31":"/frontend/ios/im-first.html#基本的发展阶段","32":"/frontend/ios/im-first.html#数据传输格式","33":"/frontend/ios/im-first.html#常见的实现方式","34":"/frontend/ios/im-first.html#重连机制","35":"/frontend/ios/image-on-iphone.html#image","36":"/frontend/ios/image-on-iphone.html#iphone拍照的部分图片在windows上显示被旋转的问题","37":"/frontend/ios/#ios-app-程序启动过程","38":"/frontend/ios/jailbreak.html#jailbreak-入门","39":"/frontend/ios/jailbreak.html#_1-jailbreak-工具","40":"/frontend/ios/jailbreak.html#_2-添加仓库源","41":"/frontend/ios/lock-share.html#琐碎的记录","42":"/frontend/ios/lock-share.html#数据存储方式对比","43":"/frontend/ios/lock-share.html#关于锁","44":"/frontend/ios/lock-share.html#磁盘缓存","45":"/frontend/ios/macro-define.html#macro-define","46":"/frontend/ios/macro-define.html#_1-debug-log","47":"/frontend/ios/macro-define.html#_2-ios版本兼容","48":"/frontend/ios/macro-define.html#编译设置","49":"/frontend/ios/macro-define.html#ios宏定义","50":"/frontend/ios/macro-define.html#静态检查","51":"/frontend/ios/macro-define.html#动态检查","52":"/frontend/ios/macro-define.html#corefoudation-nsfoundation版本宏","53":"/frontend/ios/macro-define.html#检查运行的ios系统版本","54":"/frontend/ios/network-share.html#ios-网络状态检测","55":"/frontend/ios/note-share.html#琐碎的记录","56":"/frontend/ios/note-share.html#免费的二级域名申请","57":"/frontend/ios/note-share.html#免费的ssl证书","58":"/frontend/ios/post-current-controller.html#get-current-viewcontroller","59":"/frontend/ios/post-current-controller.html#_1-get-the-current-view-controller-from-the-app-delegate","60":"/frontend/ios/post-dispatch-group.html#dispatch-group","61":"/frontend/ios/post-dispatch-group.html#dispatch-group-日常使用","62":"/frontend/ios/post-facebook-share.html#facebook-分享","63":"/frontend/ios/post-facebook-share.html#在移动平台上分享-—-分步指南","64":"/frontend/ios/post-facebook-share.html#第一步-info-plist-文件配置","65":"/frontend/ios/post-facebook-share.html#第二步-注册facebook","66":"/frontend/ios/post-facebook-share.html#第三步-实现分享功能","67":"/frontend/ios/post-instagram-share.html#instagram-分享","68":"/frontend/ios/post-twitter-share.html#twitter-share","69":"/frontend/ios/post-twitter-share.html#twitter-分享","70":"/frontend/ios/post-twitter-share.html#_1-开发者账号申请注意事项","71":"/frontend/ios/post-twitter-share.html#_2-安装步骤","72":"/frontend/ios/post-twitter-share.html#_3-重要注解","73":"/frontend/ios/post-twitter-share.html#_4-twitter-分享文档","74":"/frontend/ios/post-twitter-share.html#_5-问题","75":"/frontend/ios/post-view-tips.html#view-tips","76":"/frontend/ios/post-view-tips.html#将视图显示在最前方","77":"/frontend/ios/post-view-tips.html#下拉取消回弹效果","78":"/frontend/ios/post-view-tips.html#检测某个api是否可用","79":"/frontend/ios/post-whatsapp-share.html#whatsapp-分享","80":"/frontend/ios/reactnative.html#react-native-入门","81":"/frontend/ios/reactnative.html#_1-配置环境","82":"/frontend/ios/reactnative.html#_1-1-切换淘宝镜像","83":"/frontend/ios/reactnative.html#_1-2-cocoapods-镜像使用帮助","84":"/frontend/ios/reactnative.html#_2-初始化项目","85":"/frontend/ios/reactnative.html#_3-使用","86":"/frontend/ios/url-codeing.html#url-coding","87":"/frontend/ios/version-share.html#version","88":"/frontend/ios/version-share.html#开发版本对比","89":"/frontend/ios/webScoket.html#webscoket-introduction","90":"/frontend/ios/webScoket.html#webscoket","91":"/frontend/ios/webview-share.html#webview","92":"/frontend/ios/webview-share.html#wkwebview-发送post请求","93":"/frontend/ios/xcode build.html#ios-自动打包脚本","94":"/frontend/ios/xcode build.html#_1-配置导出plist文件","95":"/frontend/ios/xcode build.html#_1-配置shell脚本","96":"/frontend/js/#js-的使用","97":"/frontend/js/#web-js的组成","98":"/frontend/js/#输出语句","99":"/frontend/js/#数据类型","100":"/frontend/js/#函数","101":"/frontend/other/2020-03-12-ionic.html#ionic-入门","102":"/frontend/other/2020-03-12-ionic.html#_1-通过npm搭建开发环境","103":"/frontend/other/2020-03-12-ionic.html#_2-初始化项目","104":"/frontend/other/2020-03-22-angular.html#angular-入门","105":"/frontend/other/2020-03-22-angular.html#_1-angular","106":"/frontend/other/2020-03-22-angular.html#_2-初始化项目","107":"/frontend/other/2020-03-22-angular.html#_2-1-安装插件","108":"/frontend/other/2020-03-22-angular.html#_3-组件","109":"/frontend/other/2020-03-22-angular.html#_3-1-插值语法和表达式","110":"/frontend/other/2020-03-22-angular.html#_3-2-绑定","111":"/frontend/other/2020-03-22-angular.html#_3-3-内置结构型指令用法","112":"/frontend/other/2020-03-22-angular.html#_3-3-内置属性型指令用法","113":"/frontend/other/2020-03-22-angular.html#_4-组件间通讯","114":"/frontend/other/2020-03-22-angular.html#_5-路由","115":"/frontend/other/#react-入门","116":"/frontend/other/#_1-通过npm搭建开发环境","117":"/frontend/other/#_2-初始化项目","118":"/frontend/other/#_3-jsx-语法","119":"/frontend/other/#组件","120":"/frontend/other/#声明","121":"/frontend/other/#props-属性","122":"/frontend/other/#事件处理","123":"/frontend/other/#state","124":"/frontend/other/#生命周期函数","125":"/frontend/other/#setstate-更新时同步还是异步","126":"/frontend/other/#条件渲染","127":"/frontend/other/#列表-key","128":"/frontend/other/#导入-antd","129":"/frontend/other/#fetch","130":"/frontend/other/#router","131":"/frontend/other/#redux","132":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#与-objective-c-api-交互","133":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#初始化","134":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#类工厂方法和便利构造器","135":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#可失败初始化","136":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#访问属性","137":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#方法","138":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#id-兼容性","139":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#将-any-向下转换","140":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#动态方法查找","141":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#无法识别的选择器和可选链语法","142":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#为空性和可选类型","143":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#将可选值桥接为-nsnull-实例","144":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#协议限定类","145":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#轻量泛型","146":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#扩展","147":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#闭包","148":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#在捕获-self-时避免强引用循环","149":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#对象比较","150":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#哈希","151":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#swift-类型兼容性","152":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#配置-swift-在-objective-c-中的接口","153":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#需要动态分派","154":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#选择器","155":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#objective-c-方法的不安全调用","156":"/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html#键和键路径","157":"/frontend/swift/01-Getting Started/Basic Setup.html#基本设置","158":"/frontend/swift/01-Getting Started/Basic Setup.html#搭建-swift-环境","159":"/frontend/swift/01-Getting Started/Basic Setup.html#在-xcode-中创建一个-swift-项目","160":"/frontend/swift/01-Getting Started/Basic Setup.html#要求","161":"/frontend/swift/01-Getting Started/Basic Setup.html#理解-swift-导入过程","162":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#使用-objective-c-特性编写-swift-类和协议","163":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#继承-objective-c-类","164":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#nscoding-协议","165":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#采用协议","166":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#编写构造器和析构器","167":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#兼容使用-swift-类名的-objective-c-api","168":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#与-interface-builder-结合","169":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#使用-outlet-和-action","170":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#实时渲染","171":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#指定属性特性","172":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#强引用和弱引用","173":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#读写和只读","174":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#拷贝语义","175":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#实现-core-data-的-nsmanagedobject-子类","176":"/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html#声明协议","177":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#使用-cocoa-框架","178":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#foundation","179":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#被桥接的类型","180":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#被重命名的类型","181":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#字符串","182":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#数值","183":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#数组","184":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#集合","185":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#字典","186":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#core-foundation","187":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#重映射类型","188":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#内存受管理的对象","189":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#非托管对象","190":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#统一日志","191":"/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html#cocoa-结构体","192":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#采用-cocoa-设计模式","193":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#代理","194":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#惰性初始化","195":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#错误处理","196":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#捕获和处理错误","197":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#将错误转换为可选值","198":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#抛出错误","199":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#处理异常","200":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#捕获和处理自定义错误","201":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#键值观察","202":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#目标-动作","203":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#单例","204":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#内省","205":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#序列化","206":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#本地化","207":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#自动释放池","208":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#api-可用性","209":"/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html#处理命令行参数","210":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#与-c-语言-api-交互","211":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#基本类型","212":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#全局常量","213":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#导入的常量枚举和结构体","214":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#函数","215":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#变参函数","216":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#结构体","217":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#导入函数作为类型成员","218":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#枚举","219":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#选项集","220":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#联合体","221":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#位字段","222":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#匿名结构体和联合体字段","223":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#指针","224":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#常量指针","225":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#可变指针","226":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#自动释放指针","227":"/frontend/swift/02-Interoperability/05-Interacting with C APIs.html#函数指针","228":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#迁移-objective-c-代码到-swift","229":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#为-objective-c-代码做好迁移准备","230":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#迁移过程","231":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#准备迁移","232":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#开始迁移","233":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#完成迁移","234":"/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html#故障排除贴士","235":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在项目中同时使用-swift-和-objective-c","236":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#混搭概述","237":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在应用程序-target-中导入代码","238":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#将-objective-c-代码导入到-swift","239":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-target-中将-objective-c-代码导入到-swift","240":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#将-swift-代码导入到-objective-c","241":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-target-中将-swift-代码导入到-objective-c","242":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在框架-target-中导入代码","243":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#将-objective-c-代码导入到-swift-1","244":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-target-中将-objective-c-代码导入到-swift-1","245":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#将-swift-代码导入到-objective-c-1","246":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-target-中将-swift-代码导入到-objective-c-1","247":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#导入外部框架","248":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-objective-c-中使用-swift","249":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-objective-c-头文件中引用-swift-类或协议","250":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#声明可被-objective-c-类遵守的-swift-协议","251":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#在-objective-c-的实现文件中采用-swift-协议","252":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#声明可在-objective-c-中使用的-swift-错误类型","253":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#为-objective-c-接口提供-swift-命名","254":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#类工厂方法","255":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#枚举","256":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#让-objective-c-接口在-swift-中不可用","257":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#优化-objective-c-声明","258":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#将可用性信息添加到-objective-c-api","259":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#为产品模块命名","260":"/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html#故障排除贴士","261":"/frontend/swift/#目录","262":"/frontend/swift/#开始","263":"/frontend/swift/#交互","264":"/frontend/swift/#混搭","265":"/frontend/swift/#迁移","266":"/guide/about.html#关于本知识库","267":"/frontend/vue/#vue-前端","268":"/guide/api-examples.html#runtime-api-examples","269":"/guide/api-examples.html#results","270":"/guide/api-examples.html#theme-data","271":"/guide/api-examples.html#page-data","272":"/guide/api-examples.html#page-frontmatter","273":"/guide/api-examples.html#more","274":"/guide/#markdown-语法","275":"/guide/markdown-examples.html#markdown-extension-examples","276":"/guide/markdown-examples.html#syntax-highlighting","277":"/guide/markdown-examples.html#custom-containers","278":"/guide/markdown-examples.html#more","279":"/guide/markdown-extension.html#markdown-extensions","280":"/guide/markdown-extension.html#header-anchors","281":"/guide/markdown-extension.html#custom-anchors","282":"/guide/markdown-extension.html#links","283":"/guide/markdown-extension.html#internal-links","284":"/guide/markdown-extension.html#page-suffix","285":"/guide/markdown-extension.html#external-links","286":"/guide/markdown-extension.html#frontmatter","287":"/guide/markdown-extension.html#github-style-tables","288":"/guide/markdown-extension.html#emoji","289":"/guide/markdown-extension.html#table-of-contents","290":"/guide/markdown-extension.html#custom-containers","291":"/guide/markdown-extension.html#default-title","292":"/guide/markdown-extension.html#custom-title","293":"/guide/markdown-extension.html#raw","294":"/guide/markdown-extension.html#github-flavored-alerts","295":"/guide/markdown-extension.html#syntax-highlighting-in-code-blocks","296":"/guide/markdown-extension.html#line-highlighting-in-code-blocks","297":"/guide/markdown-extension.html#focus-in-code-blocks","298":"/guide/markdown-extension.html#colored-diffs-in-code-blocks","299":"/guide/markdown-extension.html#errors-and-warnings-in-code-blocks","300":"/guide/markdown-extension.html#line-numbers","301":"/guide/markdown-extension.html#import-code-snippets","302":"/guide/markdown-extension.html#code-groups","303":"/guide/markdown-extension.html#markdown-file-inclusion","304":"/guide/markdown-extension.html#math-equations","305":"/guide/markdown-extension.html#image-lazy-loading","306":"/guide/markdown-extension.html#advanced-configuration","307":"/guide/markdown.html#markdown基础语法","308":"/guide/markdown.html#目录","309":"/guide/markdown.html#横线","310":"/guide/markdown.html#标题","311":"/guide/markdown.html#一级标题","312":"/guide/markdown.html#二级标题","313":"/guide/markdown.html#三级标题","314":"/guide/markdown.html#四级标题","315":"/guide/markdown.html#五级标题","316":"/guide/markdown.html#六级标题","317":"/guide/markdown.html#文本","318":"/guide/markdown.html#普通文本","319":"/guide/markdown.html#单行文本","320":"/guide/markdown.html#文本块","321":"/guide/markdown.html#语法1","322":"/guide/markdown.html#语法2","323":"/guide/markdown.html#文字高亮","324":"/guide/markdown.html#换行","325":"/guide/markdown.html#斜体、粗体、删除线","326":"/guide/markdown.html#图片","327":"/guide/markdown.html#链接","328":"/guide/markdown.html#链接外部url","329":"/guide/markdown.html#链接本仓库里的url","330":"/guide/markdown.html#图片链接","331":"/guide/markdown.html#锚点","332":"/guide/markdown.html#列表","333":"/guide/markdown.html#无序列表","334":"/guide/markdown.html#语法","335":"/guide/markdown.html#效果","336":"/guide/markdown.html#多级无序列表","337":"/guide/markdown.html#语法-1","338":"/guide/markdown.html#效果-1","339":"/guide/markdown.html#一级有序列表","340":"/guide/markdown.html#语法-2","341":"/guide/markdown.html#效果-2","342":"/guide/markdown.html#多级有序列表","343":"/guide/markdown.html#语法-3","344":"/guide/markdown.html#效果-3","345":"/guide/markdown.html#复选框列表","346":"/guide/markdown.html#语法-4","347":"/guide/markdown.html#效果-4","348":"/guide/markdown.html#块引用","349":"/guide/markdown.html#常用于引用文本","350":"/guide/markdown.html#文本摘自《深入理解计算机系统》p27","351":"/guide/markdown.html#块引用有多级结构","352":"/guide/markdown.html#语法-5","353":"/guide/markdown.html#效果-5","354":"/guide/markdown.html#代码高亮","355":"/guide/markdown.html#语法-6","356":"/guide/markdown.html#效果-6","357":"/guide/markdown.html#表格","358":"/guide/markdown.html#对齐","359":"/guide/markdown.html#混合其他语法","360":"/guide/markdown.html#使用普通文本的删除线-斜体等效果","361":"/guide/markdown.html#表格中嵌入图片-链接","362":"/guide/markdown.html#diff语法","363":"/guide/markdown.html#语法-7","364":"/guide/markdown.html#效果-7","365":"/guide/markdown.html#常用html语法","366":"/guide/markdown.html#折叠","367":"/guide/markdown.html#编译","368":"/guide/markdown.html#安装","369":"/guide/markdown.html#居中","370":"/guide/profile.html#简介","371":"/network/https-tips.html#https网站访问过程","372":"/network/https-tips.html#nsurlsession-模拟https证书认证","373":"/network/#网络","374":"/network/#网络协议","375":"/network/#应用","376":"/utils/mac-tips.html#mac-tips","377":"/utils/mac-tips.html#显示任何来源","378":"/utils/git-tips.html#git-使用汇总","379":"/utils/git-tips.html#git配置多个ssh-key","380":"/utils/git-tips.html#解决方法","381":"/utils/git-tips.html#常见的git命令","382":"/utils/git-tips.html#新建代码库","383":"/utils/git-tips.html#配置","384":"/utils/git-tips.html#增加-删除文件","385":"/utils/git-tips.html#代码提交","386":"/utils/git-tips.html#分支","387":"/utils/git-tips.html#标签","388":"/utils/git-tips.html#查看信息","389":"/utils/git-tips.html#远程同步","390":"/utils/git-tips.html#回滚","391":"/utils/git-tips.html#pull-request-基本操作流程","392":"/utils/git-tips.html#一-在合并远程代码的时候-或许会出现以下问题","393":"/utils/xcode-tips.html#xcode-tips","394":"/utils/xcode-tips.html#xcode-ide","395":"/utils/xcode-tips.html#xcode-symbol-s-not-found-for-architecture-armv7","396":"/utils/xcode-tips.html#how-to-trap-on-uiviewalertforunsatisfiableconstraints","397":"/utils/xcode-tips.html#how-to-define-preprocessor-macros-in-xcode"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[2,1,1],"1":[1,2,15],"2":[2,1,75],"3":[3,2,35],"4":[2,1,31],"5":[1,1,2],"6":[2,1,1],"7":[1,2,1],"8":[2,3,36],"9":[1,1,38],"10":[4,1,1],"11":[1,4,7],"12":[1,4,1],"13":[4,5,13],"14":[3,5,147],"15":[2,1,1],"16":[1,2,47],"17":[2,2,12],"18":[2,1,1],"19":[2,2,1],"20":[2,3,39],"21":[2,3,34],"22":[2,1,1],"23":[3,2,64],"24":[2,2,6],"25":[2,2,41],"26":[3,1,58],"27":[1,1,65],"28":[2,1,1],"29":[3,2,1],"30":[1,4,18],"31":[1,4,26],"32":[1,4,8],"33":[1,4,41],"34":[1,4,24],"35":[1,1,6],"36":[1,1,99],"37":[3,1,67],"38":[2,1,1],"39":[3,2,29],"40":[2,2,16],"41":[1,1,1],"42":[1,1,31],"43":[2,1,36],"44":[1,1,150],"45":[2,1,2],"46":[3,1,30],"47":[2,1,1],"48":[1,2,16],"49":[1,2,1],"50":[1,3,32],"51":[1,3,1],"52":[2,4,43],"53":[1,4,71],"54":[2,1,35],"55":[1,1,1],"56":[1,1,14],"57":[1,1,16],"58":[3,1,10],"59":[9,3,79],"60":[4,1,1],"61":[3,1,95],"62":[2,1,9],"63":[2,2,52],"64":[4,4,72],"65":[2,4,42],"66":[2,4,181],"67":[2,1,150],"68":[4,1,1],"69":[2,1,10],"70":[3,2,8],"71":[3,2,25],"72":[3,2,1],"73":[4,2,90],"74":[3,2,95],"75":[2,1,1],"76":[1,2,5],"77":[1,2,15],"78":[1,2,31],"79":[2,1,117],"80":[3,1,1],"81":[2,3,2],"82":[2,5,33],"83":[4,5,24],"84":[2,3,21],"85":[2,3,11],"86":[4,1,155],"87":[1,1,1],"88":[1,1,39],"89":[2,1,1],"90":[1,2,398],"91":[3,1,1],"92":[2,3,111],"93":[2,1,1],"94":[2,2,61],"95":[2,2,155],"96":[2,1,1],"97":[2,2,14],"98":[1,2,19],"99":[1,2,19],"100":[1,2,13],"101":[2,1,1],"102":[2,2,10],"103":[2,2,88],"104":[2,1,1],"105":[2,2,11],"106":[2,2,24],"107":[3,4,11],"108":[2,2,1],"109":[3,4,11],"110":[3,4,27],"111":[2,4,22],"112":[2,4,8],"113":[2,2,77],"114":[2,2,1],"115":[2,1,1],"116":[2,2,22],"117":[2,2,15],"118":[3,2,7],"119":[1,5,1],"120":[1,5,21],"121":[2,5,4],"122":[1,5,3],"123":[1,5,1],"124":[1,5,44],"125":[2,5,4],"126":[1,5,1],"127":[3,5,1],"128":[2,5,1],"129":[1,5,6],"130":[1,5,15],"131":[1,5,1],"132":[5,1,55],"133":[1,5,70],"134":[1,6,26],"135":[1,6,44],"136":[1,5,68],"137":[1,5,29],"138":[2,5,25],"139":[3,7,35],"140":[1,7,28],"141":[1,7,59],"142":[1,5,82],"143":[3,6,63],"144":[1,5,34],"145":[1,5,74],"146":[1,5,60],"147":[1,5,44],"148":[3,6,42],"149":[1,5,33],"150":[1,6,46],"151":[2,5,130],"152":[6,7,94],"153":[1,7,43],"154":[1,5,71],"155":[3,6,97],"156":[1,5,82],"157":[1,1,46],"158":[3,1,10],"159":[5,4,37],"160":[1,4,35],"161":[3,1,89],"162":[6,1,47],"163":[4,6,44],"164":[2,8,29],"165":[1,6,40],"166":[1,6,37],"167":[6,6,54],"168":[4,6,17],"169":[4,10,56],"170":[1,10,42],"171":[1,6,7],"172":[1,7,14],"173":[1,7,18],"174":[1,7,16],"175":[6,6,58],"176":[1,6,56],"177":[3,1,48],"178":[1,3,8],"179":[1,4,87],"180":[1,4,38],"181":[1,4,48],"182":[1,4,54],"183":[1,4,50],"184":[1,4,54],"185":[1,4,61],"186":[2,3,21],"187":[1,5,15],"188":[1,5,37],"189":[1,5,74],"190":[1,3,84],"191":[2,3,24],"192":[3,1,40],"193":[1,3,42],"194":[1,3,76],"195":[1,3,82],"196":[1,4,64],"197":[1,4,55],"198":[1,4,85],"199":[1,4,38],"200":[1,4,55],"201":[1,3,50],"202":[2,3,21],"203":[1,3,52],"204":[1,3,59],"205":[1,3,111],"206":[1,3,60],"207":[1,3,26],"208":[2,3,100],"209":[1,3,35],"210":[5,1,35],"211":[1,5,45],"212":[1,5,8],"213":[1,6,86],"214":[1,5,38],"215":[1,6,69],"216":[1,5,28],"217":[1,6,70],"218":[1,5,74],"219":[1,5,97],"220":[1,5,43],"221":[1,5,9],"222":[1,5,55],"223":[1,5,28],"224":[1,6,49],"225":[1,6,40],"226":[1,6,40],"227":[1,6,75],"228":[5,1,31],"229":[4,5,20],"230":[1,5,20],"231":[1,6,51],"232":[1,6,57],"233":[1,6,27],"234":[1,5,43],"235":[5,1,47],"236":[1,5,16],"237":[3,5,11],"238":[5,8,44],"239":[7,10,55],"240":[5,8,73],"241":[7,10,30],"242":[3,5,9],"243":[5,8,15],"244":[7,10,44],"245":[5,8,59],"246":[7,10,40],"247":[1,5,26],"248":[5,5,29],"249":[6,7,28],"250":[6,7,25],"251":[6,7,24],"252":[6,7,44],"253":[6,5,21],"254":[1,8,27],"255":[1,8,21],"256":[6,5,35],"257":[4,5,60],"258":[4,5,53],"259":[1,5,35],"260":[1,5,98],"261":[1,1,1],"262":[1,1,2],"263":[1,1,14],"264":[1,1,6],"265":[1,1,6],"266":[1,1,1],"267":[2,1,2],"268":[3,1,51],"269":[1,3,1],"270":[2,4,2],"271":[2,4,2],"272":[2,4,2],"273":[1,3,11],"274":[2,1,1],"275":[3,1,14],"276":[2,3,26],"277":[2,3,21],"278":[1,3,11],"279":[2,1,5],"280":[1,2,6],"281":[1,3,8],"282":[1,2,2],"283":[1,3,35],"284":[1,3,5],"285":[1,3,12],"286":[1,2,16],"287":[2,2,21],"288":[2,2,10],"289":[3,2,19],"290":[1,2,3],"291":[1,3,21],"292":[1,3,42],"293":[1,3,52],"294":[2,2,19],"295":[1,2,35],"296":[1,2,58],"297":[1,2,22],"298":[1,2,20],"299":[5,2,19],"300":[1,2,42],"301":[1,2,51],"302":[1,2,43],"303":[3,2,52],"304":[1,2,77],"305":[1,2,13],"306":[1,2,50],"307":[1,1,9],"308":[1,1,32],"309":[1,2,2],"310":[1,1,8],"311":[1,1,1],"312":[1,1,1],"313":[1,2,1],"314":[1,3,1],"315":[1,4,1],"316":[1,5,1],"317":[1,1,1],"318":[1,2,2],"319":[1,2,5],"320":[1,2,1],"321":[1,3,9],"322":[1,3,9],"323":[1,2,14],"324":[1,3,7],"325":[3,3,19],"326":[1,1,48],"327":[1,1,1],"328":[1,2,32],"329":[1,2,7],"330":[1,2,25],"331":[1,2,15],"332":[1,1,1],"333":[1,2,1],"334":[1,3,7],"335":[1,3,7],"336":[1,2,1],"337":[1,3,4],"338":[1,3,4],"339":[1,2,1],"340":[1,3,11],"341":[1,3,5],"342":[1,2,3],"343":[1,3,8],"344":[1,3,7],"345":[1,2,1],"346":[1,3,8],"347":[1,3,12],"348":[1,1,1],"349":[1,2,1],"350":[3,3,37],"351":[1,2,1],"352":[1,3,11],"353":[1,3,6],"354":[1,1,1],"355":[1,2,5],"356":[1,2,35],"357":[1,1,8],"358":[1,2,21],"359":[1,2,3],"360":[2,3,11],"361":[3,3,8],"362":[1,1,6],"363":[1,3,11],"364":[1,3,6],"365":[1,1,5],"366":[1,2,9],"367":[1,4,2],"368":[1,4,2],"369":[1,2,16],"370":[1,1,1],"371":[1,1,73],"372":[2,1,97],"373":[1,1,1],"374":[1,1,1],"375":[1,1,1],"376":[2,1,1],"377":[1,2,20],"378":[2,1,1],"379":[2,2,9],"380":[1,4,49],"381":[1,2,1],"382":[1,3,12],"383":[1,3,14],"384":[2,3,28],"385":[1,3,22],"386":[1,3,40],"387":[1,3,27],"388":[1,4,7],"389":[1,4,45],"390":[1,4,31],"391":[3,2,178],"392":[4,2,109],"393":[2,1,1],"394":[2,1,1],"395":[8,2,59],"396":[6,2,32],"397":[7,2,114]},"averageFieldLength":[1.881909547738694,3.193467336683417,31.902010050251242],"storedFields":{"0":{"title":"Fei blog","titles":[]},"1":{"title":"致谢","titles":["Fei blog"]},"2":{"title":"Tomcat 介绍","titles":[]},"3":{"title":"1.get 请求传送的参数包含中文字符","titles":["Tomcat 介绍"]},"4":{"title":"maven 介绍","titles":[]},"5":{"title":"前端工程化","titles":[]},"6":{"title":"XML 常见转义字符","titles":[]},"7":{"title":"XML常见用转义字符","titles":["XML 常见转义字符"]},"8":{"title":"html 转义字符","titles":["XML 常见转义字符","XML常见用转义字符"]},"9":{"title":"Appstore","titles":[]},"10":{"title":"更新 App store 发布证书","titles":[]},"11":{"title":"分三步去更新","titles":["更新 App store 发布证书"]},"12":{"title":"示例","titles":["更新 App store 发布证书"]},"13":{"title":"1.确定已过期的 APP ID","titles":["更新 App store 发布证书","示例"]},"14":{"title":"2.根据APP ID重新生成Certifictes","titles":["更新 App store 发布证书","示例"]},"15":{"title":"Download issues","titles":[]},"16":{"title":"下载问题","titles":["Download issues"]},"17":{"title":"NSOperation 的使用","titles":["Download issues"]},"18":{"title":"cocoapods 入门","titles":[]},"19":{"title":"COCOAPODS 入门","titles":["cocoapods 入门"]},"20":{"title":"1. cocoapods","titles":["cocoapods 入门","COCOAPODS 入门"]},"21":{"title":"2. 初始化项目","titles":["cocoapods 入门","COCOAPODS 入门"]},"22":{"title":"Flutter 入门","titles":[]},"23":{"title":"1. Flutter 介绍","titles":["Flutter 入门"]},"24":{"title":"2. Flutter","titles":["Flutter 入门"]},"25":{"title":"3. Dart","titles":["Flutter 入门"]},"26":{"title":"Cocoa Touch Framework","titles":[]},"27":{"title":"使用iTunes获取ipa","titles":[]},"28":{"title":"IM Introduction","titles":[]},"29":{"title":"IM 即时通讯技术 介绍","titles":["IM Introduction"]},"30":{"title":"应用场景","titles":["IM Introduction","IM 即时通讯技术 介绍"]},"31":{"title":"基本的发展阶段","titles":["IM Introduction","IM 即时通讯技术 介绍"]},"32":{"title":"数据传输格式","titles":["IM Introduction","IM 即时通讯技术 介绍"]},"33":{"title":"常见的实现方式","titles":["IM Introduction","IM 即时通讯技术 介绍"]},"34":{"title":"重连机制","titles":["IM Introduction","IM 即时通讯技术 介绍"]},"35":{"title":"Image","titles":[]},"36":{"title":"iPhone拍照的部分图片在windows上显示被旋转的问题","titles":["Image"]},"37":{"title":"iOS App 程序启动过程","titles":[]},"38":{"title":"Jailbreak 入门","titles":[]},"39":{"title":"1. Jailbreak 工具","titles":["Jailbreak 入门"]},"40":{"title":"2. 添加仓库源","titles":["Jailbreak 入门"]},"41":{"title":"琐碎的记录","titles":[]},"42":{"title":"数据存储方式对比","titles":["琐碎的记录"]},"43":{"title":"关于锁:","titles":["琐碎的记录"]},"44":{"title":"磁盘缓存","titles":["琐碎的记录"]},"45":{"title":"Macro Define","titles":[]},"46":{"title":"1. DEBUG Log","titles":[]},"47":{"title":"2. ios版本兼容","titles":[]},"48":{"title":"编译设置","titles":["2. ios版本兼容"]},"49":{"title":"iOS宏定义","titles":["2. ios版本兼容"]},"50":{"title":"静态检查","titles":["2. ios版本兼容","iOS宏定义"]},"51":{"title":"动态检查","titles":["2. ios版本兼容","iOS宏定义"]},"52":{"title":"CoreFoudation/NSFoundation版本宏","titles":["2. ios版本兼容","iOS宏定义","动态检查"]},"53":{"title":"检查运行的iOS系统版本","titles":["2. ios版本兼容","iOS宏定义","动态检查"]},"54":{"title":"iOS 网络状态检测","titles":[]},"55":{"title":"琐碎的记录","titles":[]},"56":{"title":"免费的二级域名申请","titles":["琐碎的记录"]},"57":{"title":"免费的ssl证书","titles":["琐碎的记录"]},"58":{"title":"Get Current ViewController","titles":[]},"59":{"title":"1.Get the current view controller from the app delegate","titles":["Get Current ViewController"]},"60":{"title":""Dispatch Group"","titles":[]},"61":{"title":"dispatch_group 日常使用","titles":[]},"62":{"title":"Facebook 分享","titles":[]},"63":{"title":"在移动平台上分享 — 分步指南","titles":["Facebook 分享"]},"64":{"title":"第一步:info.plist 文件配置","titles":["Facebook 分享","在移动平台上分享 — 分步指南"]},"65":{"title":"第二步:注册Facebook","titles":["Facebook 分享","在移动平台上分享 — 分步指南"]},"66":{"title":"第三步:实现分享功能","titles":["Facebook 分享","在移动平台上分享 — 分步指南"]},"67":{"title":"Instagram 分享","titles":[]},"68":{"title":""Twitter share"","titles":[]},"69":{"title":"Twitter 分享","titles":[]},"70":{"title":"1 开发者账号申请注意事项:","titles":["Twitter 分享"]},"71":{"title":"2 安装步骤:","titles":["Twitter 分享"]},"72":{"title":"3 重要注解:","titles":["Twitter 分享"]},"73":{"title":"4 twitter 分享文档:","titles":["Twitter 分享"]},"74":{"title":"5 问题:","titles":["Twitter 分享"]},"75":{"title":"View Tips","titles":[]},"76":{"title":"将视图显示在最前方","titles":["View Tips"]},"77":{"title":"下拉取消回弹效果","titles":["View Tips"]},"78":{"title":"检测某个API是否可用","titles":["View Tips"]},"79":{"title":"WhatsApp 分享","titles":[]},"80":{"title":"React Native 入门","titles":[]},"81":{"title":"1. 配置环境","titles":["React Native 入门"]},"82":{"title":"1.1 切换淘宝镜像","titles":["React Native 入门","1. 配置环境"]},"83":{"title":"1.2 CocoaPods 镜像使用帮助","titles":["React Native 入门","1. 配置环境"]},"84":{"title":"2. 初始化项目","titles":["React Native 入门"]},"85":{"title":"3.使用","titles":["React Native 入门"]},"86":{"title":""Url Coding"","titles":[]},"87":{"title":"Version","titles":[]},"88":{"title":"开发版本对比","titles":["Version"]},"89":{"title":"WebScoket Introduction","titles":[]},"90":{"title":"WebScoket","titles":["WebScoket Introduction"]},"91":{"title":""WebView"","titles":[]},"92":{"title":"WKWebView 发送Post请求","titles":[""WebView""]},"93":{"title":"ios 自动打包脚本","titles":[]},"94":{"title":"1. 配置导出plist文件","titles":["ios 自动打包脚本"]},"95":{"title":"1. 配置shell脚本","titles":["ios 自动打包脚本"]},"96":{"title":"JS 的使用","titles":[]},"97":{"title":"Web JS的组成","titles":["JS 的使用"]},"98":{"title":"输出语句","titles":["JS 的使用"]},"99":{"title":"数据类型","titles":["JS 的使用"]},"100":{"title":"函数","titles":["JS 的使用"]},"101":{"title":"ionic 入门","titles":[]},"102":{"title":"1. 通过npm搭建开发环境","titles":["ionic 入门"]},"103":{"title":"2. 初始化项目","titles":["ionic 入门"]},"104":{"title":"angular 入门","titles":[]},"105":{"title":"1. angular","titles":["angular 入门"]},"106":{"title":"2. 初始化项目","titles":["angular 入门"]},"107":{"title":"2.1 安装插件","titles":["angular 入门","2. 初始化项目"]},"108":{"title":"3. 组件","titles":["angular 入门"]},"109":{"title":"3.1 插值语法和表达式","titles":["angular 入门","3. 组件"]},"110":{"title":"3.2 绑定","titles":["angular 入门","3. 组件"]},"111":{"title":"3.3 内置结构型指令用法","titles":["angular 入门","3. 组件"]},"112":{"title":"3.3 内置属性型指令用法","titles":["angular 入门","3. 组件"]},"113":{"title":"4. 组件间通讯","titles":["angular 入门"]},"114":{"title":"5. 路由","titles":["angular 入门"]},"115":{"title":"React 入门","titles":[]},"116":{"title":"1. 通过npm搭建开发环境","titles":["React 入门"]},"117":{"title":"2. 初始化项目","titles":["React 入门"]},"118":{"title":"3.JSX 语法","titles":["React 入门"]},"119":{"title":"组件","titles":["React 入门","3.JSX 语法"]},"120":{"title":"声明","titles":["React 入门","3.JSX 语法"]},"121":{"title":"props 属性","titles":["React 入门","3.JSX 语法"]},"122":{"title":"事件处理","titles":["React 入门","3.JSX 语法"]},"123":{"title":"state","titles":["React 入门","3.JSX 语法"]},"124":{"title":"生命周期函数","titles":["React 入门","3.JSX 语法"]},"125":{"title":"setState 更新时同步还是异步","titles":["React 入门","3.JSX 语法"]},"126":{"title":"条件渲染","titles":["React 入门","3.JSX 语法"]},"127":{"title":"列表 & key","titles":["React 入门","3.JSX 语法"]},"128":{"title":"导入 antd","titles":["React 入门","3.JSX 语法"]},"129":{"title":"Fetch","titles":["React 入门","3.JSX 语法"]},"130":{"title":"Router","titles":["React 入门","3.JSX 语法"]},"131":{"title":"Redux","titles":["React 入门","3.JSX 语法"]},"132":{"title":"与 Objective-C API 交互","titles":[]},"133":{"title":"初始化","titles":["与 Objective-C API 交互"]},"134":{"title":"类工厂方法和便利构造器","titles":["与 Objective-C API 交互","初始化"]},"135":{"title":"可失败初始化","titles":["与 Objective-C API 交互","初始化"]},"136":{"title":"访问属性","titles":["与 Objective-C API 交互"]},"137":{"title":"方法","titles":["与 Objective-C API 交互"]},"138":{"title":"id 兼容性","titles":["与 Objective-C API 交互"]},"139":{"title":"将 Any 向下转换","titles":["与 Objective-C API 交互","id 兼容性"]},"140":{"title":"动态方法查找","titles":["与 Objective-C API 交互","id 兼容性"]},"141":{"title":"无法识别的选择器和可选链语法","titles":["与 Objective-C API 交互","id 兼容性"]},"142":{"title":"为空性和可选类型","titles":["与 Objective-C API 交互"]},"143":{"title":"将可选值桥接为 NSNull 实例","titles":["与 Objective-C API 交互","为空性和可选类型"]},"144":{"title":"协议限定类","titles":["与 Objective-C API 交互"]},"145":{"title":"轻量泛型","titles":["与 Objective-C API 交互"]},"146":{"title":"扩展","titles":["与 Objective-C API 交互"]},"147":{"title":"闭包","titles":["与 Objective-C API 交互"]},"148":{"title":"在捕获 self 时避免强引用循环","titles":["与 Objective-C API 交互","闭包"]},"149":{"title":"对象比较","titles":["与 Objective-C API 交互"]},"150":{"title":"哈希","titles":["与 Objective-C API 交互","对象比较"]},"151":{"title":"Swift 类型兼容性","titles":["与 Objective-C API 交互"]},"152":{"title":"配置 Swift 在 Objective-C 中的接口","titles":["与 Objective-C API 交互","Swift 类型兼容性"]},"153":{"title":"需要动态分派","titles":["与 Objective-C API 交互","Swift 类型兼容性"]},"154":{"title":"选择器","titles":["与 Objective-C API 交互"]},"155":{"title":"Objective-C 方法的不安全调用","titles":["与 Objective-C API 交互","选择器"]},"156":{"title":"键和键路径","titles":["与 Objective-C API 交互"]},"157":{"title":"基本设置","titles":[]},"158":{"title":"搭建 Swift 环境","titles":["基本设置"]},"159":{"title":"在 Xcode 中创建一个 Swift 项目","titles":["基本设置","搭建 Swift 环境"]},"160":{"title":"要求","titles":["基本设置","搭建 Swift 环境"]},"161":{"title":"理解 Swift 导入过程","titles":["基本设置"]},"162":{"title":"使用 Objective-C 特性编写 Swift 类和协议","titles":[]},"163":{"title":"继承 Objective-C 类","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"164":{"title":"NSCoding 协议","titles":["使用 Objective-C 特性编写 Swift 类和协议","继承 Objective-C 类"]},"165":{"title":"采用协议","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"166":{"title":"编写构造器和析构器","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"167":{"title":"兼容使用 Swift 类名的 Objective-C API","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"168":{"title":"与 Interface Builder 结合","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"169":{"title":"使用 Outlet 和 Action","titles":["使用 Objective-C 特性编写 Swift 类和协议","与 Interface Builder 结合"]},"170":{"title":"实时渲染","titles":["使用 Objective-C 特性编写 Swift 类和协议","与 Interface Builder 结合"]},"171":{"title":"指定属性特性","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"172":{"title":"强引用和弱引用","titles":["使用 Objective-C 特性编写 Swift 类和协议","指定属性特性"]},"173":{"title":"读写和只读","titles":["使用 Objective-C 特性编写 Swift 类和协议","指定属性特性"]},"174":{"title":"拷贝语义","titles":["使用 Objective-C 特性编写 Swift 类和协议","指定属性特性"]},"175":{"title":"实现 Core Data 的 NSManagedObject 子类","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"176":{"title":"声明协议","titles":["使用 Objective-C 特性编写 Swift 类和协议"]},"177":{"title":"使用 Cocoa 框架","titles":[]},"178":{"title":"Foundation","titles":["使用 Cocoa 框架"]},"179":{"title":"被桥接的类型","titles":["使用 Cocoa 框架","Foundation"]},"180":{"title":"被重命名的类型","titles":["使用 Cocoa 框架","Foundation"]},"181":{"title":"字符串","titles":["使用 Cocoa 框架","Foundation"]},"182":{"title":"数值","titles":["使用 Cocoa 框架","Foundation"]},"183":{"title":"数组","titles":["使用 Cocoa 框架","Foundation"]},"184":{"title":"集合","titles":["使用 Cocoa 框架","Foundation"]},"185":{"title":"字典","titles":["使用 Cocoa 框架","Foundation"]},"186":{"title":"Core Foundation","titles":["使用 Cocoa 框架"]},"187":{"title":"重映射类型","titles":["使用 Cocoa 框架","Core Foundation"]},"188":{"title":"内存受管理的对象","titles":["使用 Cocoa 框架","Core Foundation"]},"189":{"title":"非托管对象","titles":["使用 Cocoa 框架","Core Foundation"]},"190":{"title":"统一日志","titles":["使用 Cocoa 框架"]},"191":{"title":"Cocoa 结构体","titles":["使用 Cocoa 框架"]},"192":{"title":"采用 Cocoa 设计模式","titles":[]},"193":{"title":"代理","titles":["采用 Cocoa 设计模式"]},"194":{"title":"惰性初始化","titles":["采用 Cocoa 设计模式"]},"195":{"title":"错误处理","titles":["采用 Cocoa 设计模式"]},"196":{"title":"捕获和处理错误","titles":["采用 Cocoa 设计模式","错误处理"]},"197":{"title":"将错误转换为可选值","titles":["采用 Cocoa 设计模式","错误处理"]},"198":{"title":"抛出错误","titles":["采用 Cocoa 设计模式","错误处理"]},"199":{"title":"处理异常","titles":["采用 Cocoa 设计模式","错误处理"]},"200":{"title":"捕获和处理自定义错误","titles":["采用 Cocoa 设计模式","错误处理"]},"201":{"title":"键值观察","titles":["采用 Cocoa 设计模式"]},"202":{"title":"目标-动作","titles":["采用 Cocoa 设计模式"]},"203":{"title":"单例","titles":["采用 Cocoa 设计模式"]},"204":{"title":"内省","titles":["采用 Cocoa 设计模式"]},"205":{"title":"序列化","titles":["采用 Cocoa 设计模式"]},"206":{"title":"本地化","titles":["采用 Cocoa 设计模式"]},"207":{"title":"自动释放池","titles":["采用 Cocoa 设计模式"]},"208":{"title":"API 可用性","titles":["采用 Cocoa 设计模式"]},"209":{"title":"处理命令行参数","titles":["采用 Cocoa 设计模式"]},"210":{"title":"与 C 语言 API 交互","titles":[]},"211":{"title":"基本类型","titles":["与 C 语言 API 交互"]},"212":{"title":"全局常量","titles":["与 C 语言 API 交互"]},"213":{"title":"导入的常量枚举和结构体","titles":["与 C 语言 API 交互","全局常量"]},"214":{"title":"函数","titles":["与 C 语言 API 交互"]},"215":{"title":"变参函数","titles":["与 C 语言 API 交互","函数"]},"216":{"title":"结构体","titles":["与 C 语言 API 交互"]},"217":{"title":"导入函数作为类型成员","titles":["与 C 语言 API 交互","结构体"]},"218":{"title":"枚举","titles":["与 C 语言 API 交互"]},"219":{"title":"选项集","titles":["与 C 语言 API 交互"]},"220":{"title":"联合体","titles":["与 C 语言 API 交互"]},"221":{"title":"位字段","titles":["与 C 语言 API 交互"]},"222":{"title":"匿名结构体和联合体字段","titles":["与 C 语言 API 交互"]},"223":{"title":"指针","titles":["与 C 语言 API 交互"]},"224":{"title":"常量指针","titles":["与 C 语言 API 交互","指针"]},"225":{"title":"可变指针","titles":["与 C 语言 API 交互","指针"]},"226":{"title":"自动释放指针","titles":["与 C 语言 API 交互","指针"]},"227":{"title":"函数指针","titles":["与 C 语言 API 交互","指针"]},"228":{"title":"迁移 Objective-C 代码到 Swift","titles":[]},"229":{"title":"为 Objective-C 代码做好迁移准备","titles":["迁移 Objective-C 代码到 Swift"]},"230":{"title":"迁移过程","titles":["迁移 Objective-C 代码到 Swift"]},"231":{"title":"准备迁移","titles":["迁移 Objective-C 代码到 Swift","迁移过程"]},"232":{"title":"开始迁移","titles":["迁移 Objective-C 代码到 Swift","迁移过程"]},"233":{"title":"完成迁移","titles":["迁移 Objective-C 代码到 Swift","迁移过程"]},"234":{"title":"故障排除贴士","titles":["迁移 Objective-C 代码到 Swift"]},"235":{"title":"在项目中同时使用 Swift 和 Objective-C","titles":[]},"236":{"title":"混搭概述","titles":["在项目中同时使用 Swift 和 Objective-C"]},"237":{"title":"在应用程序 target 中导入代码","titles":["在项目中同时使用 Swift 和 Objective-C"]},"238":{"title":"将 Objective-C 代码导入到 Swift","titles":["在项目中同时使用 Swift 和 Objective-C","在应用程序 target 中导入代码"]},"239":{"title":"在 target 中将 Objective-C 代码导入到 Swift","titles":["在项目中同时使用 Swift 和 Objective-C","在应用程序 target 中导入代码","将 Objective-C 代码导入到 Swift"]},"240":{"title":"将 Swift 代码导入到 Objective-C","titles":["在项目中同时使用 Swift 和 Objective-C","在应用程序 target 中导入代码"]},"241":{"title":"在 target 中将 Swift 代码导入到 Objective-C","titles":["在项目中同时使用 Swift 和 Objective-C","在应用程序 target 中导入代码","将 Swift 代码导入到 Objective-C"]},"242":{"title":"在框架 target 中导入代码","titles":["在项目中同时使用 Swift 和 Objective-C"]},"243":{"title":"将 Objective-C 代码导入到 Swift","titles":["在项目中同时使用 Swift 和 Objective-C","在框架 target 中导入代码"]},"244":{"title":"在 target 中将 Objective-C 代码导入到 Swift","titles":["在项目中同时使用 Swift 和 Objective-C","在框架 target 中导入代码","将 Objective-C 代码导入到 Swift"]},"245":{"title":"将 Swift 代码导入到 Objective-C","titles":["在项目中同时使用 Swift 和 Objective-C","在框架 target 中导入代码"]},"246":{"title":"在 target 中将 Swift 代码导入到 Objective-C","titles":["在项目中同时使用 Swift 和 Objective-C","在框架 target 中导入代码","将 Swift 代码导入到 Objective-C"]},"247":{"title":"导入外部框架","titles":["在项目中同时使用 Swift 和 Objective-C"]},"248":{"title":"在 Objective-C 中使用 Swift","titles":["在项目中同时使用 Swift 和 Objective-C"]},"249":{"title":"在 Objective-C 头文件中引用 Swift 类或协议","titles":["在项目中同时使用 Swift 和 Objective-C","在 Objective-C 中使用 Swift"]},"250":{"title":"声明可被 Objective-C 类遵守的 Swift 协议","titles":["在项目中同时使用 Swift 和 Objective-C","在 Objective-C 中使用 Swift"]},"251":{"title":"在 Objective-C 的实现文件中采用 Swift 协议","titles":["在项目中同时使用 Swift 和 Objective-C","在 Objective-C 中使用 Swift"]},"252":{"title":"声明可在 Objective-C 中使用的 Swift 错误类型","titles":["在项目中同时使用 Swift 和 Objective-C","在 Objective-C 中使用 Swift"]},"253":{"title":"为 Objective-C 接口提供 Swift 命名","titles":["在项目中同时使用 Swift 和 Objective-C"]},"254":{"title":"类工厂方法","titles":["在项目中同时使用 Swift 和 Objective-C","为 Objective-C 接口提供 Swift 命名"]},"255":{"title":"枚举","titles":["在项目中同时使用 Swift 和 Objective-C","为 Objective-C 接口提供 Swift 命名"]},"256":{"title":"让 Objective-C 接口在 Swift 中不可用","titles":["在项目中同时使用 Swift 和 Objective-C"]},"257":{"title":"优化 Objective-C 声明","titles":["在项目中同时使用 Swift 和 Objective-C"]},"258":{"title":"将可用性信息添加到 Objective-C API","titles":["在项目中同时使用 Swift 和 Objective-C"]},"259":{"title":"为产品模块命名","titles":["在项目中同时使用 Swift 和 Objective-C"]},"260":{"title":"故障排除贴士","titles":["在项目中同时使用 Swift 和 Objective-C"]},"261":{"title":"目录","titles":[]},"262":{"title":"开始","titles":["目录"]},"263":{"title":"交互","titles":["目录"]},"264":{"title":"混搭","titles":["目录"]},"265":{"title":"迁移","titles":["目录"]},"266":{"title":"关于本知识库","titles":[]},"267":{"title":"vue 前端","titles":[]},"268":{"title":"Runtime API Examples","titles":[]},"269":{"title":"Results","titles":["Runtime API Examples"]},"270":{"title":"Theme Data","titles":["Runtime API Examples","Results"]},"271":{"title":"Page Data","titles":["Runtime API Examples","Results"]},"272":{"title":"Page Frontmatter","titles":["Runtime API Examples","Results"]},"273":{"title":"More","titles":["Runtime API Examples"]},"274":{"title":"markdown 语法","titles":[]},"275":{"title":"Markdown Extension Examples","titles":[]},"276":{"title":"Syntax Highlighting","titles":["Markdown Extension Examples"]},"277":{"title":"Custom Containers","titles":["Markdown Extension Examples"]},"278":{"title":"More","titles":["Markdown Extension Examples"]},"279":{"title":"Markdown 扩展","titles":[]},"280":{"title":"标题锚点","titles":["Markdown 扩展"]},"281":{"title":"自定义锚点","titles":["Markdown 扩展","标题锚点"]},"282":{"title":"链接","titles":["Markdown 扩展"]},"283":{"title":"内部链接","titles":["Markdown 扩展","链接"]},"284":{"title":"页面后缀","titles":["Markdown 扩展","链接"]},"285":{"title":"外部链接","titles":["Markdown 扩展","链接"]},"286":{"title":"frontmatter","titles":["Markdown 扩展"]},"287":{"title":"GitHub 风格的表格","titles":["Markdown 扩展"]},"288":{"title":"Emoji 🎉","titles":["Markdown 扩展"]},"289":{"title":"目录表 (TOC)","titles":["Markdown 扩展"]},"290":{"title":"自定义容器","titles":["Markdown 扩展"]},"291":{"title":"默认标题","titles":["Markdown 扩展","自定义容器"]},"292":{"title":"自定义标题","titles":["Markdown 扩展","自定义容器"]},"293":{"title":"raw","titles":["Markdown 扩展","自定义容器"]},"294":{"title":"GitHub 风格的警报","titles":["Markdown 扩展"]},"295":{"title":"代码块中的语法高亮","titles":["Markdown 扩展"]},"296":{"title":"在代码块中实现行高亮","titles":["Markdown 扩展"]},"297":{"title":"代码块中聚焦","titles":["Markdown 扩展"]},"298":{"title":"代码块中的颜色差异","titles":["Markdown 扩展"]},"299":{"title":"高亮“错误”和“警告”","titles":["Markdown 扩展"]},"300":{"title":"行号","titles":["Markdown 扩展"]},"301":{"title":"导入代码片段","titles":["Markdown 扩展"]},"302":{"title":"代码组","titles":["Markdown 扩展"]},"303":{"title":"包含 markdown 文件","titles":["Markdown 扩展"]},"304":{"title":"数学方程","titles":["Markdown 扩展"]},"305":{"title":"图片懒加载","titles":["Markdown 扩展"]},"306":{"title":"高级配置","titles":["Markdown 扩展"]},"307":{"title":"Markdown基础语法","titles":[]},"308":{"title":"目录","titles":["Markdown基础语法"]},"309":{"title":"横线","titles":["Markdown基础语法","目录"]},"310":{"title":"标题","titles":["Markdown基础语法"]},"311":{"title":"一级标题","titles":[]},"312":{"title":"二级标题","titles":["一级标题"]},"313":{"title":"三级标题","titles":["一级标题","二级标题"]},"314":{"title":"四级标题","titles":["一级标题","二级标题","三级标题"]},"315":{"title":"五级标题","titles":["一级标题","二级标题","三级标题","四级标题"]},"316":{"title":"六级标题","titles":["一级标题","二级标题","三级标题","四级标题","五级标题"]},"317":{"title":"文本","titles":["一级标题"]},"318":{"title":"普通文本","titles":["一级标题","文本"]},"319":{"title":"单行文本","titles":["一级标题","文本"]},"320":{"title":"文本块","titles":["一级标题","文本"]},"321":{"title":"语法1","titles":["一级标题","文本","文本块"]},"322":{"title":"语法2","titles":["一级标题","文本","文本块"]},"323":{"title":"文字高亮","titles":["一级标题","文本"]},"324":{"title":"换行","titles":["一级标题","文本","文字高亮"]},"325":{"title":"斜体、粗体、删除线","titles":["一级标题","文本","文字高亮"]},"326":{"title":"图片","titles":["一级标题"]},"327":{"title":"链接","titles":["一级标题"]},"328":{"title":"链接外部URL","titles":["一级标题","链接"]},"329":{"title":"链接本仓库里的URL","titles":["一级标题","链接"]},"330":{"title":"图片链接","titles":["一级标题","链接"]},"331":{"title":"锚点","titles":["一级标题","链接"]},"332":{"title":"列表","titles":["一级标题"]},"333":{"title":"无序列表","titles":["一级标题","列表"]},"334":{"title":"语法","titles":["一级标题","列表","无序列表"]},"335":{"title":"效果","titles":["一级标题","列表","无序列表"]},"336":{"title":"多级无序列表","titles":["一级标题","列表"]},"337":{"title":"语法","titles":["一级标题","列表","多级无序列表"]},"338":{"title":"效果","titles":["一级标题","列表","多级无序列表"]},"339":{"title":"一级有序列表","titles":["一级标题","列表"]},"340":{"title":"语法","titles":["一级标题","列表","一级有序列表"]},"341":{"title":"效果","titles":["一级标题","列表","一级有序列表"]},"342":{"title":"多级有序列表","titles":["一级标题","列表"]},"343":{"title":"语法","titles":["一级标题","列表","多级有序列表"]},"344":{"title":"效果","titles":["一级标题","列表","多级有序列表"]},"345":{"title":"复选框列表","titles":["一级标题","列表"]},"346":{"title":"语法","titles":["一级标题","列表","复选框列表"]},"347":{"title":"效果","titles":["一级标题","列表","复选框列表"]},"348":{"title":"块引用","titles":["一级标题"]},"349":{"title":"常用于引用文本","titles":["一级标题","块引用"]},"350":{"title":"文本摘自《深入理解计算机系统》P27","titles":["一级标题","块引用","常用于引用文本"]},"351":{"title":"块引用有多级结构","titles":["一级标题","块引用"]},"352":{"title":"语法","titles":["一级标题","块引用","块引用有多级结构"]},"353":{"title":"效果","titles":["一级标题","块引用","块引用有多级结构"]},"354":{"title":"代码高亮","titles":["一级标题"]},"355":{"title":"语法","titles":["一级标题","代码高亮"]},"356":{"title":"效果","titles":["一级标题","代码高亮"]},"357":{"title":"表格","titles":["一级标题"]},"358":{"title":"对齐","titles":["一级标题","表格"]},"359":{"title":"混合其他语法","titles":["一级标题","表格"]},"360":{"title":"使用普通文本的删除线,斜体等效果","titles":["一级标题","表格","混合其他语法"]},"361":{"title":"表格中嵌入图片(链接)","titles":["一级标题","表格","混合其他语法"]},"362":{"title":"diff语法","titles":["一级标题"]},"363":{"title":"语法","titles":["一级标题","diff语法","混合其他语法"]},"364":{"title":"效果","titles":["一级标题","diff语法","混合其他语法"]},"365":{"title":"常用HTML语法","titles":["一级标题"]},"366":{"title":"折叠","titles":["一级标题","常用HTML语法"]},"367":{"title":"编译","titles":["一级标题","常用HTML语法","折叠","效果"]},"368":{"title":"安装","titles":["一级标题","常用HTML语法","折叠","效果"]},"369":{"title":"居中","titles":["一级标题","常用HTML语法"]},"370":{"title":"简介","titles":[]},"371":{"title":"HTTPS网站访问过程","titles":[]},"372":{"title":"NSURLSession 模拟HTTPS证书认证","titles":[]},"373":{"title":"网络","titles":[]},"374":{"title":"网络协议","titles":["网络"]},"375":{"title":"应用","titles":["网络"]},"376":{"title":"Mac Tips","titles":[]},"377":{"title":"显示任何来源","titles":["Mac Tips"]},"378":{"title":"git 使用汇总","titles":[]},"379":{"title":"Git配置多个SSH-Key","titles":["git 使用汇总"]},"380":{"title":"解决方法","titles":["git 使用汇总","Git配置多个SSH-Key"]},"381":{"title":"常见的git命令","titles":["git 使用汇总"]},"382":{"title":"新建代码库","titles":["git 使用汇总","常见的git命令"]},"383":{"title":"配置","titles":["git 使用汇总","常见的git命令"]},"384":{"title":"增加/删除文件","titles":["git 使用汇总","常见的git命令"]},"385":{"title":"代码提交","titles":["git 使用汇总","常见的git命令"]},"386":{"title":"分支","titles":["git 使用汇总","常见的git命令"]},"387":{"title":"标签","titles":["git 使用汇总","常见的git命令"]},"388":{"title":"查看信息","titles":["git 使用汇总","常见的git命令","标签"]},"389":{"title":"远程同步","titles":["git 使用汇总","常见的git命令","标签"]},"390":{"title":"回滚","titles":["git 使用汇总","常见的git命令","标签"]},"391":{"title":"pull request 基本操作流程","titles":["git 使用汇总"]},"392":{"title":"一. 在合并远程代码的时候,或许会出现以下问题:","titles":["git 使用汇总"]},"393":{"title":"Xcode Tips","titles":[]},"394":{"title":"Xcode IDE","titles":[]},"395":{"title":"Xcode: symbol(s) not found for architecture armv7","titles":["Xcode IDE"]},"396":{"title":"How to trap on UIViewAlertForUnsatisfiableConstraints?","titles":["Xcode IDE"]},"397":{"title":"How to define Preprocessor Macros in Xcode","titles":["Xcode IDE"]}},"dirtCount":0,"index":[["两种解决方式",{"2":{"392":1}}],["两种可用性说明符在",{"2":{"258":1}}],["整体流程如下",{"2":{"391":1}}],["整数或布尔字面量创建",{"2":{"182":1}}],["远程代码",{"2":{"391":1}}],["远程同步",{"0":{"389":1}}],["退到",{"2":{"390":1}}],["推送所有tag到远程仓库",{"2":{"389":1}}],["推送所有分支到远程仓库",{"2":{"389":1}}],["推送某一个commit",{"2":{"389":1}}],["推荐安装",{"2":{"39":1}}],["推荐",{"2":{"39":1}}],["取回远程仓库的变化",{"2":{"389":1}}],["取消整个请求",{"2":{"372":1}}],["查看信息",{"0":{"388":1}}],["查看tag信息",{"2":{"387":1}}],["查看gem源地址",{"2":{"20":1}}],["合并进当前分支",{"2":{"386":1}}],["合并指定分支到当前分支",{"2":{"386":1}}],["合并模拟器与真机版本",{"2":{"26":1}}],["建立追踪关系",{"2":{"386":1}}],["建立连接",{"2":{"90":1}}],["列出所有tag",{"2":{"387":1}}],["列出所有远程分支",{"2":{"386":1}}],["列出所有本地分支和远程分支",{"2":{"386":1}}],["列出所有本地分支",{"2":{"386":1}}],["列表",{"0":{"127":1,"332":1},"1":{"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"340":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1},"2":{"288":1,"308":1}}],["替代上一次提交",{"2":{"385":1}}],["替换",{"2":{"259":1}}],["替换为产品模块名",{"2":{"241":1}}],["替换为自己的ip地址",{"2":{"90":2}}],["替换为您的应用需要获取照片访问权限的理由",{"2":{"64":1}}],["替换为",{"2":{"64":1}}],["替换变量",{"2":{"25":1}}],["停止追踪指定文件",{"2":{"384":1}}],["新建一个tag在指定commit",{"2":{"387":1}}],["新建一个tag在当前commit",{"2":{"387":1}}],["新建一个分支",{"2":{"386":4,"387":1}}],["新建一个目录",{"2":{"382":1}}],["新建代码库",{"0":{"382":1}}],["新图",{"2":{"36":1}}],["凭据参数被忽略",{"2":{"372":1}}],["凭据参数会被忽略",{"2":{"372":1}}],["认证要求从客户端上传证书",{"2":{"372":1}}],["客户端需要将用户名和密码信息放到凭据中",{"2":{"372":1}}],["客户端需要按照服务端指定的认证方法进行认证",{"2":{"372":1}}],["客户端证书",{"2":{"372":1}}],["客服端也将通过同样的方法产生相同的主通讯密码",{"2":{"371":1}}],["客服端向服务器发送",{"2":{"371":1}}],["客服端申请权限",{"2":{"67":1}}],["完成步骤3",{"2":{"372":1}}],["完成迁移",{"0":{"233":1},"2":{"228":1}}],["防止数据通讯中的任何变化",{"2":{"371":1}}],["防止异步操作阻塞ui",{"2":{"124":1}}],["约定通话密码",{"2":{"371":1}}],["预主密码",{"2":{"371":5}}],["预处理指令",{"2":{"210":1}}],["随机数以及其他信息",{"2":{"371":1}}],["随着这些",{"2":{"161":1}}],["产生的随机数",{"2":{"371":1}}],["产品模块名和产品名一样",{"2":{"259":1}}],["首先当输入完https网址",{"2":{"371":1}}],["首先找到已过期的app",{"2":{"11":1}}],["毕竟那样就丧失了markdown的意义",{"2":{"365":1}}],["虽然不鼓励大量使用html语法",{"2":{"365":1}}],["月出惊山鸟",{"2":{"364":1}}],["夜静春山空",{"2":{"364":1}}],["人闲桂花落",{"2":{"364":1}}],["人们表现得非常情绪化",{"2":{"350":1}}],["红色表示删除",{"2":{"362":1}}],["百度",{"2":{"361":1}}],["百度logo",{"2":{"326":1}}],["混合其他语法",{"0":{"359":1},"1":{"360":1,"361":1,"363":1,"364":1}}],["混搭概述",{"0":{"236":1},"2":{"235":1}}],["混搭和互用会让这一切变得简单可行",{"2":{"228":1}}],["混搭",{"0":{"264":1},"2":{"157":1}}],["右对齐",{"2":{"358":2}}],["左对齐",{"2":{"358":2}}],["左操作数的内存地址作为函数参数传入",{"2":{"224":1,"225":1}}],["另起一行开始写代码",{"2":{"355":1}}],["另外还有有",{"2":{"363":1}}],["另外",{"2":{"67":1,"133":1,"152":1,"166":1}}],["另外内存中的数据是定时",{"2":{"44":1}}],["满二叉树",{"2":{"352":1,"353":1}}],["平衡二叉树",{"2":{"352":1,"353":1}}],["平台名称",{"2":{"208":1}}],["平台特定类",{"2":{"180":1}}],["平台",{"2":{"160":1}}],["二叉树",{"2":{"352":1,"353":1}}],["二级标题",{"0":{"312":1},"1":{"313":1,"314":1,"315":1,"316":1},"2":{"310":1}}],["树",{"2":{"352":1,"353":1}}],["违令者重罚",{"2":{"350":1}}],["吃鸡蛋前",{"2":{"350":1}}],["战争开始是由于以下的原因",{"2":{"350":1}}],["端口号port",{"2":{"372":1}}],["端",{"2":{"350":1}}],["端点",{"2":{"66":1}}],["争论沦为关于社会政治的争论",{"2":{"350":1}}],["格利佛游记",{"2":{"350":1}}],["格式的",{"2":{"286":1}}],["格式如下",{"2":{"9":1}}],["出自jonathan",{"2":{"350":1}}],["出现在方法的圆括号内",{"2":{"137":1}}],["出现的错误日志如下",{"2":{"74":1}}],["出现选择证书的页面",{"2":{"14":1}}],["出现创建csr文件的界面",{"2":{"14":1}}],["令人吃惊的是",{"2":{"350":1}}],["深入理解计算机系统",{"0":{"350":1}}],["交付",{"2":{"346":1,"347":1}}],["交互章节",{"2":{"232":1}}],["交互",{"0":{"132":1,"210":1,"263":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1},"2":{"157":1,"161":1,"263":2}}],["测试",{"2":{"346":1,"347":1}}],["需求分析",{"2":{"346":1,"347":1}}],["需要我们在本地完成证书信任的过程",{"2":{"372":1}}],["需要才进行",{"2":{"371":1}}],["需要安装",{"2":{"304":1}}],["需要做的就是将有效的语言别名附加到代码块的开头",{"2":{"295":1}}],["需要将这些",{"2":{"243":1}}],["需要将p12格式转换为pem格式的",{"2":{"14":1}}],["需要依靠",{"2":{"238":1,"240":1}}],["需要使用一个枚举值时",{"2":{"218":1}}],["需要使用全限定名",{"2":{"167":1}}],["需要进一步学习有关",{"2":{"188":1}}],["需要用cf",{"2":{"188":1}}],["需要在应用的info",{"2":{"167":1}}],["需要对如何搭建",{"2":{"157":1}}],["需要更精确地控制如何将",{"2":{"152":1}}],["需要动态分派",{"0":{"153":1},"2":{"132":1}}],["需要申请",{"2":{"66":1}}],["需要申请public",{"2":{"63":1}}],["需要==public",{"2":{"66":1}}],["需要",{"2":{"61":1,"241":1,"246":1}}],["需要自己定义",{"2":{"52":1}}],["需要从新",{"2":{"39":1}}],["需要考虑替换",{"2":{"20":1}}],["需要回调的结果",{"2":{"16":2}}],["需要双击cer文件",{"2":{"14":1}}],["需要修改tomcat的访问权限",{"2":{"2":1}}],["阿拉伯数字在显示的时候变成了罗马数字",{"2":{"343":1,"344":1}}],["阿里云开源库",{"2":{"113":1}}],["封装",{"2":{"340":1,"341":1}}],["脚本语言",{"2":{"337":1,"338":1}}],["英文名",{"2":{"334":1,"335":1}}],["隔壁老王",{"2":{"334":1,"335":1}}],["果冻虾仁",{"2":{"334":1,"335":1}}],["昵称",{"2":{"334":1,"335":1}}],["见例3",{"2":{"330":1}}],["见代码高亮",{"2":{"322":1}}],["欢迎关注",{"2":{"330":1}}],["欢迎到访",{"2":{"321":1,"322":1}}],["普通的链接中",{"2":{"330":1}}],["普通文本",{"0":{"318":1},"2":{"308":1}}],["给图片加链接的本质是混合图片显示语法和普通的链接语法",{"2":{"330":1}}],["给定以下目录结构",{"2":{"283":1}}],["囧",{"2":{"328":1}}],["姑且称之为url标识符",{"2":{"328":1}}],["悬停显示",{"2":{"328":1}}],["必应",{"2":{"328":2}}],["必须先将相关的自定义",{"2":{"240":1}}],["必须从",{"2":{"234":1}}],["必须将其转换为其他类型",{"2":{"204":1}}],["必须将它转换为能够接受内存管理的对象",{"2":{"189":1}}],["必须使用nsdocument子类的全限定名",{"2":{"167":1}}],["必须使用类的全限定名",{"2":{"167":1}}],["必须为其创建",{"2":{"161":1}}],["必须通过动态分派提供",{"2":{"153":1}}],["必须遵守",{"2":{"37":1}}],["必须有",{"2":{"9":1}}],["收藏",{"2":{"326":1}}],["收到pong回调",{"2":{"90":1}}],["仓库地址",{"2":{"326":1}}],["斜粗体删除线2",{"2":{"325":2}}],["斜粗体删除线1",{"2":{"325":1}}],["斜粗体2",{"2":{"325":2}}],["斜粗体1",{"2":{"325":2}}],["斜体等效果",{"0":{"360":1}}],["斜体2",{"2":{"325":2}}],["斜体1",{"2":{"325":2}}],["斜体",{"0":{"325":1},"2":{"308":1,"325":1}}],["效果",{"0":{"335":1,"338":1,"341":1,"344":1,"347":1,"353":1,"356":1,"364":1},"1":{"367":1,"368":1},"2":{"323":1,"325":1,"326":1,"328":1,"329":1,"330":1,"331":1}}],["效果如下",{"2":{"310":1}}],["晚安",{"2":{"321":1}}],["早上好",{"2":{"321":1}}],["早期版本的",{"2":{"258":2}}],["祝您",{"2":{"321":1}}],["很高兴见到您",{"2":{"321":1}}],["很多地方都会用到居中的效果",{"2":{"369":1}}],["很多",{"2":{"177":1}}],["我们将gitlab",{"2":{"380":1}}],["我们大家都认为",{"2":{"350":1}}],["我们还提供网页对话框作为回退选项",{"2":{"66":1}}],["我的知乎",{"2":{"330":1}}],["我的简介",{"2":{"329":2}}],["我是前端码农",{"2":{"322":1}}],["我是果冻虾仁",{"2":{"319":1}}],["六级标题",{"0":{"316":1},"2":{"310":1}}],["五级标题",{"0":{"315":1},"1":{"316":1},"2":{"310":1}}],["四级标题",{"0":{"314":1},"1":{"315":1,"316":1},"2":{"310":1}}],["居中",{"0":{"369":1},"2":{"308":1,"358":2}}],["折叠",{"0":{"366":1},"1":{"367":1,"368":1},"2":{"308":1}}],["复选框列表",{"0":{"345":1},"1":{"346":1,"347":1},"2":{"308":1}}],["复杂宏",{"2":{"210":1}}],["锚点",{"0":{"331":1},"2":{"308":1}}],["粗体2",{"2":{"325":2}}],["粗体1",{"2":{"325":2}}],["粗体",{"0":{"325":1},"2":{"308":1,"325":1}}],["换行",{"0":{"324":1},"2":{"308":1}}],["换言之",{"2":{"147":1}}],["横线",{"0":{"309":1},"2":{"308":1}}],["称之为github",{"2":{"307":1}}],["部分语法为非标准语法",{"2":{"307":1}}],["插件",{"2":{"306":1}}],["插值语法和表达式",{"0":{"109":1},"2":{"113":1}}],["渲染器",{"2":{"306":1}}],["渲染引擎",{"2":{"23":1}}],["图片路径",{"2":{"326":1}}],["图片链接的时候为了清晰就是放在在表格中显示的",{"2":{"361":1}}],["图片链接",{"0":{"330":1},"2":{"308":1}}],["图片",{"0":{"326":1},"2":{"308":1,"361":1}}],["图片懒加载",{"0":{"305":1}}],["图谱示例",{"2":{"66":1}}],["启用行号",{"2":{"300":2}}],["启用了单元测试",{"2":{"240":1}}],["支持多种编程语言",{"2":{"295":1}}],["样式隔离目前是可选的",{"2":{"293":1}}],["信息",{"2":{"292":1}}],["危险",{"2":{"292":1}}],["危险区域",{"2":{"292":2}}],["点我查看代码",{"2":{"292":2}}],["点击enter之后",{"2":{"371":1}}],["点击language下拉菜单并选择",{"2":{"159":1}}],["点击twitter分享会崩溃",{"2":{"74":1}}],["点击continue",{"2":{"14":2}}],["点击",{"2":{"14":13}}],["行号已启用",{"2":{"300":2}}],["行号",{"0":{"300":1}}],["行号导入代码片段代码组包含",{"2":{"289":1}}],["行为可能带来的负面影响",{"2":{"294":2}}],["行为设计模式的类",{"2":{"155":1}}],["风格的警报",{"0":{"294":1},"2":{"294":1}}],["风格的警报代码块中的语法高亮在代码块中实现行高亮代码块中聚焦代码块中的颜色差异高亮",{"2":{"289":1}}],["风格的表格emoji",{"2":{"289":1}}],["风格的表格",{"0":{"287":1}}],["💯",{"2":{"288":1}}],["🎉目录表",{"2":{"289":1}}],["🎉",{"0":{"288":1},"2":{"288":1}}],["外部链接带有",{"2":{"285":1}}],["外部链接",{"0":{"285":1}}],["假设现在处于",{"2":{"283":1}}],["假设上面的",{"2":{"189":1}}],["└─",{"2":{"283":3}}],["│",{"2":{"283":3}}],["├─",{"2":{"283":6}}],["才能在",{"2":{"260":1}}],["才能使用图谱",{"2":{"63":1}}],["试图在",{"2":{"256":1}}],["试图调用项目所支持的最低平台版本不支持的方法将会引发编译时错误",{"2":{"208":1}}],["试图调用不存在的方法将触发未识别的选择器错误",{"2":{"141":1}}],["遵守error协议并标记",{"2":{"252":1}}],["遵循如下映射",{"2":{"223":3}}],["手动写个接口声明",{"2":{"245":1}}],["研究了一下发现可以采取如下方式解决",{"2":{"245":1}}],["保护空间",{"2":{"371":1}}],["保护伞头文件中导入的",{"2":{"244":1}}],["保护伞头文件",{"2":{"243":1,"246":1}}],["保存着",{"2":{"141":1}}],["译者注",{"2":{"243":1,"245":1}}],["往往需要在",{"2":{"242":1}}],["犹如它们标记了public修饰符一般",{"2":{"240":1}}],["私有声明不会暴露给",{"2":{"240":1}}],["私信",{"2":{"30":1}}],["确保先导入相关的",{"2":{"260":1}}],["确保build",{"2":{"260":1}}],["确保框架的build",{"2":{"260":1}}],["确保将",{"2":{"244":1,"246":1}}],["确保在build",{"2":{"239":1}}],["确定已过期的",{"0":{"13":1}}],["利用这种特性",{"2":{"235":1}}],["利用session",{"2":{"113":1}}],["优化",{"0":{"257":1},"2":{"235":1}}],["优点",{"2":{"33":1}}],["详细设计",{"2":{"346":1,"347":1}}],["详细信息",{"2":{"292":1}}],["详细列表请参阅在",{"2":{"234":1}}],["详情请参阅在",{"2":{"260":1}}],["详情请参阅为产品模块命名小节",{"2":{"260":1}}],["详情请参阅",{"2":{"159":1}}],["切记",{"2":{"234":1}}],["切换为由远程创建的分支",{"2":{"387":1}}],["切换到上一个分支",{"2":{"386":1}}],["切换到指定分支",{"2":{"386":1}}],["切换到工程目录下",{"2":{"116":1}}],["切换到设备上的",{"2":{"66":1}}],["切换淘宝镜像",{"0":{"82":1}}],["避免编译时出现符号重复的错误",{"2":{"234":1}}],["具体的操作步骤",{"2":{"231":1}}],["具有class属性特性的属性",{"2":{"136":1}}],["具有assign",{"2":{"136":1}}],["具有weak属性特性的属性",{"2":{"136":1}}],["具有readonly属性特性的属性",{"2":{"136":1}}],["具有为空性属性特性的属性",{"2":{"136":1}}],["现有的",{"2":{"229":1}}],["现代化特性应用其中",{"2":{"229":1}}],["现在这是可选的",{"2":{"304":1}}],["现在该换成anyobject了",{"2":{"187":1}}],["现在可以开始尝试在appdelegate中编写",{"2":{"159":1}}],["现在",{"2":{"63":1}}],["广泛的功能并整合到现有的",{"2":{"228":1}}],["哪些依然用",{"2":{"228":1}}],["简介",{"0":{"370":1}}],["简洁语法",{"2":{"357":1}}],["简称gfm",{"2":{"307":1}}],["简而言之",{"2":{"228":1}}],["简单宏",{"2":{"210":1}}],["逻辑以及性能",{"2":{"228":1}}],["故障排除贴士",{"0":{"234":1,"260":1},"2":{"228":1,"235":1}}],["故需要安装itunes",{"2":{"27":1}}],["准备迁移",{"0":{"231":1},"2":{"228":1}}],["缓冲区的地址会作为函数参数传入",{"2":{"226":1}}],["形式到一个缓冲区内",{"2":{"224":1}}],["≅",{"2":{"215":2}}],["√2",{"2":{"215":2}}],["组合选项值",{"2":{"219":1}}],["组织任意类型的相关常量",{"2":{"213":1}}],["组件的生命周期可分成三个状态",{"2":{"124":1}}],["组件间通讯",{"0":{"113":1}}],["组件",{"0":{"108":1,"119":1},"1":{"109":1,"110":1,"111":1,"112":1},"2":{"120":1,"125":1}}],["旧版宏的",{"2":{"213":1}}],["尽可能地避免直接使用指针",{"2":{"223":1}}],["尽可能地使用int这种原生",{"2":{"211":1}}],["尽管对于不同的项目",{"2":{"234":1}}],["尽管",{"2":{"220":1}}],["尽管在使用anyobject类型的值调用方法时不需要强制解包",{"2":{"141":1}}],["之后添加",{"2":{"300":1}}],["之后附加文本来设置自定义标题",{"2":{"292":1}}],["之后组件已经生成了对应的dom结构",{"2":{"124":1}}],["之间不能进行隐式转换",{"2":{"211":1}}],["空指针",{"2":{"210":1}}],["空格",{"2":{"8":1}}],["匿名字段由内部所嵌套的拥有命名字段的struct或union类型构成",{"2":{"222":1}}],["匿名结构体和联合体字段",{"0":{"222":1},"2":{"210":1}}],["匿名函数",{"2":{"25":1}}],["联合体所有字段共享同一块内存",{"2":{"220":1}}],["联合体的行为",{"2":{"220":1}}],["联合体导入为",{"2":{"220":2}}],["联合体",{"0":{"220":1},"2":{"210":1,"220":1}}],["变参函数",{"0":{"215":1},"2":{"210":1}}],["变量和参数",{"2":{"223":1}}],["变量存储属性会成为",{"2":{"151":1}}],["变量的默认行为",{"2":{"147":1}}],["变量",{"2":{"25":1}}],["全局函数",{"2":{"214":1}}],["全局常量",{"0":{"212":1},"1":{"213":1},"2":{"210":1,"212":1}}],["全局变量",{"2":{"151":1}}],["每一个标题都是一个锚点",{"2":{"331":1}}],["每个选项值都是结构体的一个静态变量",{"2":{"219":1}}],["每个枚举成员会被导入为属性类型是该结构体类型的全局只读计算型属性",{"2":{"218":1}}],["每个平台参数由下面列出的平台名称组成",{"2":{"208":1}}],["每次超时时间75s",{"2":{"34":1}}],["针对之前的例子",{"2":{"208":1}}],["こんにちは",{"2":{"206":1}}],["库中的",{"2":{"205":1}}],["传递给服务器",{"2":{"371":1}}],["传递给函数的指针仅保证在函数调用期间内有效",{"2":{"224":1}}],["传给服务器",{"2":{"371":1}}],["传给其他本地进程",{"2":{"205":1}}],["传入cf",{"2":{"217":1}}],["传值",{"2":{"124":2}}],["经过转换之后",{"2":{"204":1}}],["符合",{"2":{"204":1}}],["符号后提供一个自定义的区域名",{"2":{"301":1}}],["符号",{"2":{"163":1}}],["成功转换为",{"2":{"204":1}}],["反之为false",{"2":{"204":1}}],["若要将",{"2":{"243":1,"245":1}}],["若要同时遵守这两种协议",{"2":{"205":1}}],["若要使用这套方法",{"2":{"205":1}}],["若是",{"2":{"204":1}}],["若果cocoapods",{"2":{"83":1}}],["让",{"0":{"256":1},"2":{"235":1}}],["让某个对象向另一个对象发送消息",{"2":{"202":1}}],["让程序会到主界面",{"2":{"37":1}}],["宏的常量声明可在",{"2":{"213":1}}],["宏之后也会作为结构体导入到",{"2":{"213":1}}],["宏之后会以结构体形式导入到",{"2":{"213":1}}],["宏标注一套可以通过",{"2":{"213":1}}],["宏标注一套不会再扩充新值的常量声明",{"2":{"213":1}}],["宏标注",{"2":{"213":1}}],["宏定义的自定义错误类型",{"2":{"200":1}}],["宏可以防止该方法被",{"2":{"195":1}}],["异常的更多信息",{"2":{"199":1}}],["异常",{"2":{"199":1}}],["异常中恢复",{"2":{"199":1}}],["异常处理使用",{"2":{"199":1}}],["异常与错误不同",{"2":{"199":1}}],["异步下载图片",{"2":{"61":1}}],["考虑以下",{"2":{"213":1}}],["考虑",{"2":{"198":1}}],["考虑如下",{"2":{"150":1}}],["关键字将抛出表达式转换为返回可选值的表达式",{"2":{"197":1}}],["关键字",{"2":{"195":1}}],["关于本知识库",{"0":{"266":1}}],["关于指定平台可用性的更多信息",{"2":{"258":1}}],["关于访问级别修饰符的更多信息",{"2":{"240":1,"245":1,"260":1}}],["关于产品模块名的具体介绍",{"2":{"238":1,"240":1}}],["关于如何在",{"2":{"241":1,"246":1}}],["关于如何编码和解码",{"2":{"205":1}}],["关于如何编码和解码更复杂的自定义类型的相关信息",{"2":{"205":1}}],["关于如何实现对象比较逻辑的更多信息",{"2":{"149":1}}],["关于键路径的更多信息",{"2":{"201":1}}],["关于",{"2":{"153":1,"199":1,"201":1,"231":1}}],["关于锁",{"0":{"43":1}}],["关于app强制更新的itunes地址",{"2":{"9":1}}],["某些接受错误的方法",{"2":{"195":1}}],["某条信息可能很有帮助",{"2":{"190":1}}],["指向某个tag",{"2":{"387":1}}],["指向指定commit",{"2":{"386":1}}],["指的是带有框架版本号和版本字符串声明的那个头文件",{"2":{"243":1}}],["指针指向的类型不会被桥接",{"2":{"226":1}}],["指针运算",{"2":{"210":1}}],["指针",{"0":{"223":1},"1":{"224":1,"225":1,"226":1,"227":1},"2":{"210":1}}],["指针参数作为最后一个参数",{"2":{"195":1}}],["指定commit的sha码",{"2":{"390":1}}],["指定语言",{"2":{"301":1}}],["指定子系统和类别",{"2":{"190":1}}],["指定属性特性",{"0":{"171":1},"1":{"172":1,"173":1,"174":1},"2":{"162":1}}],["延迟存储属性",{"2":{"194":1}}],["¤",{"2":{"194":1}}],["惰性属性的值只会在被初次访问时才被初始化",{"2":{"194":1}}],["惰性初始化",{"0":{"194":1},"2":{"192":1}}],["使这些设计模式更加强大易用",{"2":{"192":1}}],["使用汇总",{"0":{"378":1},"1":{"379":1,"380":1,"381":1,"382":1,"383":1,"384":1,"385":1,"386":1,"387":1,"388":1,"389":1,"390":1,"391":1,"392":1}}],["使用服务器发回的凭据",{"2":{"372":1}}],["使用的协议protocol",{"2":{"372":1}}],["使用绿色表示新增",{"2":{"362":1}}],["使用普通文本的删除线",{"0":{"360":1}}],["使用url标识符能达到复用的目的",{"2":{"328":1}}],["使用uiimage",{"2":{"135":1}}],["使用uidocumentinteractioncontroller",{"2":{"79":1}}],["使用一次新的commit",{"2":{"385":1}}],["使用一对反引号",{"2":{"323":1}}],["使用一对各三个的反引号",{"2":{"322":1}}],["使用一个any类型的对象时",{"2":{"139":1}}],["使用更多的",{"2":{"306":1}}],["使用喜欢的包管理器来安装需要的依赖项",{"2":{"293":1}}],["使用自定义锚点",{"2":{"281":2}}],["使用自定义的分享按钮",{"2":{"66":1}}],["使用以下示例中展示的相应语法即可",{"2":{"258":1}}],["使用以点",{"2":{"218":1}}],["使用该宏标记的方法导入到",{"2":{"257":1}}],["使用该方法的时候",{"2":{"16":1}}],["使用字典字面量替代",{"2":{"256":1}}],["使用字符串的比较",{"2":{"53":1}}],["使用者使用其他替代方式",{"2":{"256":1}}],["使用如下命令",{"2":{"377":1}}],["使用如下语法将外部框架导入到",{"2":{"247":2}}],["使用如下语法将",{"2":{"246":1}}],["使用如下代码",{"2":{"92":1}}],["使用这些标记internal的",{"2":{"245":1}}],["使用单个",{"2":{"230":1}}],["使用函数customcopydescription作为参数copydescription的值",{"2":{"227":1}}],["使用位字段相对应的计算属性时",{"2":{"221":1}}],["使用按位与操作符",{"2":{"219":1}}],["使用原始值进行初始化时",{"2":{"218":1}}],["使用原生",{"2":{"66":1}}],["使用可扩充形式的常量声明在导入后会额外获得一个构造器",{"2":{"213":1}}],["使用可选链语法在anyobject上调用方法",{"2":{"141":1}}],["使用可选来防止这种不安全的行为",{"2":{"141":1}}],["使用conformstoprotocol",{"2":{"204":1}}],["使用int",{"2":{"215":1}}],["使用iskindofclass",{"2":{"204":1}}],["使用itunes获取ipa",{"0":{"27":1}}],["使用轻量泛型的nsdictionary对象会被桥接为",{"2":{"185":1}}],["使用轻量泛型的nsset对象会被桥接为set",{"2":{"184":1}}],["使用轻量泛型的nsarray对象被桥接时",{"2":{"183":1}}],["使用浮点数",{"2":{"182":1}}],["使用var使其可读写",{"2":{"173":1}}],["使用v4",{"2":{"103":1}}],["使用let使其只读",{"2":{"173":1}}],["使用linux",{"2":{"2":1}}],["使用那些用到",{"2":{"167":1}}],["使用选择器调用方法并非内在安全的",{"2":{"155":1}}],["使用===运算符",{"2":{"149":1}}],["使用==运算符",{"2":{"149":1}}],["使用了轻量泛型的",{"2":{"145":1}}],["使用为空性标注来指明初始化是否会失败",{"2":{"135":1}}],["使用jsx",{"2":{"118":1}}],["使用js向web传值的时候就会遇到js报错",{"2":{"8":1}}],["使用方法",{"2":{"95":1}}],["使用方式",{"2":{"52":1}}],["使用浏览器模拟客户端的文件如下",{"2":{"90":1}}],["使用pongmessage接受pong消息",{"2":{"90":1}}],["使用byte",{"2":{"90":1}}],["使用xcode",{"2":{"84":1}}],["使用open",{"2":{"79":1}}],["使用",{"0":{"85":1,"162":1,"169":1,"177":1},"1":{"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"189":1,"190":1,"191":1},"2":{"78":1,"112":2,"152":1,"153":1,"158":1,"160":1,"162":1,"166":1,"169":1,"177":1,"192":1,"208":1,"213":2,"227":2,"232":3,"258":3,"263":1,"295":1,"306":1}}],["使用respondstoselector",{"2":{"78":1,"208":1}}],["使用开放图谱标签",{"2":{"66":1}}],["使用someprotocol",{"2":{"165":1}}],["使用sdk中的分享按钮fbsdksharebutton",{"2":{"66":1}}],["使用systemversion方法获取到的值为8",{"2":{"53":1}}],["使用您在应用面板中指定的显示名称替换",{"2":{"64":1}}],["使用应用编号替换",{"2":{"64":1}}],["使用nsoperatingsystemversion",{"2":{"53":1}}],["使用手机",{"2":{"39":1}}],["使用新的源",{"2":{"20":1}}],["使用转义字符转义后的字符串就可以正常的传递",{"2":{"8":1}}],["既有的设计模式",{"2":{"192":1}}],["动作模式的示例",{"2":{"202":1}}],["动作模式基本类似",{"2":{"202":1}}],["动作是一种常见的",{"2":{"202":1}}],["动作",{"0":{"202":1},"2":{"192":1}}],["动态库",{"2":{"160":1}}],["动态分派的可用性并不妨碍",{"2":{"153":1}}],["动态方法查找",{"0":{"140":1},"2":{"132":1}}],["动态检查",{"0":{"51":1},"1":{"52":1,"53":1}}],["捕获和处理自定义错误",{"0":{"200":1},"2":{"192":1}}],["捕获和处理错误",{"0":{"196":1},"2":{"192":1}}],["处理命令行参数",{"0":{"209":1},"2":{"192":1}}],["处理异常",{"0":{"199":1},"2":{"192":1}}],["处理这些干扰事件",{"2":{"37":1}}],["抛出错误",{"0":{"198":1},"2":{"192":1}}],["同样支持以标注的方式渲染",{"2":{"294":1}}],["同样",{"2":{"195":1,"258":1}}],["同样会在dictionary类型和nsdictionary类之间桥接",{"2":{"185":1}}],["同时在ssl通讯过程中还要完成数据通讯的完整性",{"2":{"371":1}}],["同时服务器还将向客服端传送自己的证书",{"2":{"371":1}}],["同时保留代码块的颜色",{"2":{"298":1}}],["同时提供读取方法和写入方法使其可读写",{"2":{"173":1}}],["同时也可以看到是否过期",{"2":{"14":1}}],["运算符返回可选类型的值",{"2":{"204":1}}],["运算符尝试向下转换到子类型",{"2":{"204":1}}],["运算符向下转换到指定类型",{"2":{"204":1}}],["运算符",{"2":{"182":1}}],["运算符转换",{"2":{"182":1}}],["运行时系统",{"2":{"245":1}}],["运行时中的一些特定类",{"2":{"180":1}}],["运行时",{"2":{"167":1}}],["运行时行为的新方法或属性时",{"2":{"163":1}}],["运行时提供的动态方法决议",{"2":{"155":1}}],["运行时库中的",{"2":{"153":1}}],["运行时动态分派对成员的访问操作",{"2":{"153":1}}],["运行时会自动处理桥接回相应的",{"2":{"138":1}}],["运行app所需要的最低的操作系统版本",{"2":{"48":1}}],["运行",{"2":{"21":1,"84":1,"106":1}}],["算术类型之间桥接",{"2":{"182":1}}],["均有相对应的",{"2":{"181":1}}],["区间的这些依据",{"2":{"181":1}}],["码元序列的形式编码兼容",{"2":{"181":1}}],["拥有对应的桥接值类型的一些类",{"2":{"180":1}}],["丢弃了类名的ns前缀",{"2":{"180":1}}],["事实上",{"2":{"179":1}}],["事件处理",{"0":{"122":1}}],["事件监听",{"2":{"113":1}}],["事件绑定",{"2":{"110":2}}],["桥接头文件时",{"2":{"260":1}}],["桥接头文件时会自动设置该路径",{"2":{"239":1}}],["桥接头文件以及为",{"2":{"260":1}}],["桥接头文件的话",{"2":{"240":1}}],["桥接头文件的路径",{"2":{"239":1}}],["桥接头文件的文件名",{"2":{"238":1}}],["桥接头文件中导入的所有",{"2":{"239":1}}],["桥接头文件中",{"2":{"239":1}}],["桥接头文件将",{"2":{"238":1}}],["桥接头文件将这些文件暴露给",{"2":{"238":1}}],["桥接头文件",{"2":{"231":1,"238":3,"240":1,"241":1,"259":1,"260":1}}],["桥接引用类型",{"2":{"179":1}}],["桥接引用类型的地方就可以使用",{"2":{"179":1}}],["桥接值类型",{"2":{"179":1}}],["桥接为nsarray时",{"2":{"143":1}}],["持久化和网络等",{"2":{"178":1}}],["排序过滤",{"2":{"178":1}}],["日期时间",{"2":{"178":1}}],["日常使用",{"0":{"61":1}}],["除了干净之外",{"2":{"328":1}}],["除了单行之外",{"2":{"296":1}}],["除此之外",{"2":{"177":1}}],["除非配置了",{"2":{"301":1,"303":1}}],["除非它们被标记",{"2":{"240":1,"260":1}}],["除非当前的平台版本符合指定要求",{"2":{"208":1}}],["除非代码确实依赖于",{"2":{"155":1}}],["除非声明所在的上下文为其隐式添加了",{"2":{"153":1}}],["除非分享内容是开放图谱动态",{"2":{"63":1}}],["间相互转换的数据类型被称为桥接类型",{"2":{"177":1}}],["进到",{"2":{"390":1}}],["进行交互",{"2":{"177":1}}],["进入终端以后",{"2":{"27":1}}],["统一日志只在",{"2":{"190":1}}],["统一日志系统提供了一个",{"2":{"190":1}}],["统一日志",{"0":{"190":1},"2":{"177":1}}],["字母等的组合",{"2":{"328":1}}],["字典字面量创建nsdictionary对象",{"2":{"185":1}}],["字典",{"0":{"185":1},"2":{"177":1,"185":3}}],["字符索引",{"2":{"181":1}}],["字符组成",{"2":{"181":1}}],["字符串可以在string类型和nsstring类型之间桥接",{"2":{"181":1}}],["字符串表达式不会将属性或方法所属类型的类型信息传递给接受键路径的",{"2":{"156":1}}],["字符串表达式接受链式的方法或属性引用",{"2":{"156":1}}],["字符串表达式生成可被编译器检查的键和键路径",{"2":{"156":1}}],["字符串",{"0":{"181":1},"2":{"99":1,"177":1}}],["字符串比较",{"2":{"53":1}}],["字符",{"2":{"8":1}}],["思考以下",{"2":{"183":1,"184":1,"185":1}}],["思考下面这个叫做person的",{"2":{"175":1}}],["思考如下名为schroedingerscat的",{"2":{"220":1}}],["思考如下",{"2":{"133":1,"142":1,"145":2,"151":1,"214":1,"216":1,"257":1}}],["面板中编辑这些属性",{"2":{"170":1}}],["面板的",{"2":{"170":2}}],["面向对象的三个基本特征",{"2":{"340":1,"341":1}}],["面向对象",{"2":{"25":1}}],["名字",{"2":{"360":1}}],["名字不能重复",{"2":{"167":1}}],["名称",{"2":{"14":1,"33":1}}],["析构器",{"2":{"166":1}}],["跟在父类类名后面",{"2":{"165":1}}],["冒号后面跟上",{"2":{"163":1}}],["更多信息请参阅在应用程序的",{"2":{"233":1}}],["更多信息请参阅与",{"2":{"232":1}}],["更多信息请参阅使用",{"2":{"232":1}}],["更多信息请参阅",{"2":{"206":1,"207":1,"227":1}}],["更便捷的方式是直接遵守",{"2":{"205":1}}],["更为强大的现代化语言特性来改善代码",{"2":{"162":1}}],["更新远程仓库地址",{"2":{"389":1}}],["更新时同步还是异步",{"0":{"125":1}}],["更新后",{"2":{"124":1}}],["更新development",{"2":{"14":1}}],["更新provisioning",{"2":{"11":1}}],["更新",{"0":{"10":1},"1":{"11":1,"12":1,"13":1,"14":1}}],["拷贝语义",{"0":{"174":1},"2":{"162":1}}],["兼容使用",{"0":{"167":1},"2":{"162":1}}],["兼容性",{"0":{"138":1},"1":{"139":1,"140":1,"141":1},"2":{"132":1,"155":1}}],["编辑git配置文件",{"2":{"383":1}}],["编码",{"2":{"346":1,"347":1}}],["编程语言",{"2":{"337":1,"338":1}}],["编写构造器和析构器",{"0":{"166":1},"2":{"162":1}}],["编译",{"0":{"367":1},"2":{"366":1}}],["编译器错误地将一个普通的类方法识别为类工厂方法",{"2":{"254":1}}],["编译器无法识别类工厂方法",{"2":{"254":1}}],["编译器无法自动对返回的",{"2":{"189":1}}],["编译器自动将",{"2":{"253":1}}],["编译器导入为",{"2":{"212":1}}],["编译器",{"2":{"175":1}}],["编译器会报错提示符号未定义",{"2":{"245":1}}],["编译器会自动为它分配空值nil",{"2":{"169":1}}],["编译器会根据",{"2":{"163":1}}],["编译器包含一些特性",{"2":{"168":1}}],["编译器能确保构造器不会遗留任何未初始化的属性",{"2":{"166":1}}],["编译器和",{"2":{"160":1}}],["编译器选择更高效的分派方法",{"2":{"153":1}}],["编译器都会引入一种通用的桥接转换操作",{"2":{"138":1}}],["编译完成",{"2":{"95":1}}],["编译常量",{"2":{"50":1}}],["编译设置",{"0":{"48":1}}],["采用",{"0":{"192":1},"1":{"193":1,"194":1,"195":1,"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"209":1},"2":{"232":1,"263":1}}],["采用协议",{"0":{"165":1},"2":{"162":1}}],["采用的是",{"2":{"44":1}}],["继承uiview或者nsview来自定义一个视图时",{"2":{"170":1}}],["继承",{"0":{"163":1},"1":{"164":1},"2":{"162":1,"340":1,"341":1}}],["继续",{"2":{"14":1}}],["头文件导入",{"2":{"240":1}}],["头文件看作",{"2":{"240":1}}],["头文件都会暴露给",{"2":{"239":1,"244":1}}],["头文件中相应的",{"2":{"252":1}}],["头文件中生成一个ns",{"2":{"252":1}}],["头文件中的内容",{"2":{"239":1,"244":1}}],["头文件中的所有结构体声明导入为",{"2":{"216":1}}],["头文件中的所有函数声明导入为",{"2":{"214":1}}],["头文件中引用",{"0":{"249":1},"2":{"235":1}}],["头文件",{"2":{"161":1,"239":1,"240":1,"244":1,"249":1,"251":1}}],["公开它的",{"2":{"161":1}}],["概念到",{"2":{"161":1}}],["概念范畴",{"2":{"31":1}}],["核心类型到",{"2":{"161":1}}],["那些头文件被编译成",{"2":{"161":1}}],["那么客户端就要将信任的凭据发给服务端",{"2":{"372":1}}],["那么文内使用标识符",{"2":{"328":1}}],["那么该函数参数可以是任意类型的unsafemutablepointer",{"2":{"225":1}}],["那么该函数参数可以是任意类型的unsafepointer",{"2":{"224":1}}],["那么该函数参数可以是下列任意一种类型",{"2":{"224":1,"225":1,"226":1}}],["那么requestwheninuseauthorization",{"2":{"208":1}}],["那么is返回结果为true",{"2":{"204":1}}],["那么可以通过以下方式来调用该函数",{"2":{"226":1}}],["那么可以通过以下任意一种方式来调用该函数",{"2":{"224":2,"225":2}}],["那么可以通过调用闭包返回初始值的方式来初始化",{"2":{"203":1}}],["那么可以略过本节的剩余部分了",{"2":{"188":1}}],["那么此时无法保证此惰性属性只被初始化一次",{"2":{"194":1}}],["那么就可以使用惰性属性",{"2":{"194":1}}],["那么就使用",{"2":{"25":1}}],["那么调用该方法",{"2":{"193":1}}],["那么这条信息就应该记录在信息级别",{"2":{"190":1}}],["那么这个方法必须标记为",{"2":{"152":1}}],["那么它会被桥接为set",{"2":{"184":1}}],["那么它会被桥接为",{"2":{"183":1,"185":1}}],["那么也必须实现这个方法",{"2":{"164":1}}],["那么对应的",{"2":{"151":1}}],["那么相应的",{"2":{"151":1}}],["那么",{"2":{"150":1}}],["想进行其他操作时",{"2":{"204":1}}],["想要了解",{"2":{"248":1}}],["想要了解更多关于统一日志的信息",{"2":{"190":1}}],["想要了解更多信息",{"2":{"189":1}}],["想要使用跳转到facebook应用分享",{"2":{"63":1}}],["想了解更多信息",{"2":{"161":2}}],["想导入",{"2":{"161":1}}],["任意语言框架",{"2":{"247":1}}],["任意下载自己需要的app",{"2":{"27":1}}],["任何来源",{"2":{"377":1}}],["任何",{"2":{"161":1}}],["里面则是要显示的图片",{"2":{"330":1}}],["里面说明了创建的步骤",{"2":{"14":1}}],["里的标识符",{"2":{"328":1}}],["里添加自定义的视图后",{"2":{"170":1}}],["里加载的对象",{"2":{"164":1}}],["里导入任何",{"2":{"161":1}}],["标识符上下对应就行了",{"2":{"328":1}}],["标题中的英文字母都被转化为小写字母了",{"2":{"331":1}}],["标题",{"0":{"310":1},"2":{"308":1}}],["标题和内容来定义",{"2":{"290":1}}],["标题会自动应用锚点",{"2":{"280":1}}],["标题锚点自定义锚点链接内部链接页面后缀外部链接frontmattergithub",{"2":{"289":1}}],["标题锚点",{"0":{"280":1},"1":{"281":1}}],["标记来覆盖在配置中的设置",{"2":{"300":1}}],["标记internal修饰符的",{"2":{"260":1}}],["标记private或fileprivate修饰符的",{"2":{"240":1,"260":1}}],["标注",{"2":{"213":1}}],["标准库定义了一套标准化方法来编码和解码数据",{"2":{"205":1}}],["标准库类型",{"2":{"186":1}}],["标准库",{"2":{"160":1}}],["标签",{"0":{"387":1},"1":{"388":1,"389":1,"390":1},"2":{"154":1}}],["由",{"2":{"160":1}}],["由命令行构建的",{"2":{"160":1}}],["由于这个自动生成的头文件是框架公共接口的一部分",{"2":{"245":1}}],["由于无法在",{"2":{"230":1}}],["由于cake结构体的字段是匿名类型",{"2":{"222":1}}],["由于惰性属性只在被初次访问时才进行初始化",{"2":{"194":1}}],["由于",{"2":{"182":1,"192":1,"220":1,"235":1}}],["由于friends是个对多关系",{"2":{"175":1}}],["由于使用",{"2":{"163":1}}],["由于以上两点",{"2":{"157":1}}],["由于归档文件中存储了被归档对象的类名",{"2":{"152":1}}],["由于很少将可选值传递给any类型",{"2":{"143":1}}],["由于any类型可以引用任何类型",{"2":{"139":1}}],["强制推到远程",{"2":{"390":1}}],["强制要求最低部署版本为ios",{"2":{"160":1}}],["强行推送当前分支到远程仓库",{"2":{"389":1}}],["强调用户在快速浏览文档时也不应忽略的重要信息",{"2":{"294":2}}],["强引用和弱引用",{"0":{"172":1},"2":{"162":1}}],["强大的工具集成到你的",{"2":{"157":1}}],["章节获取更多信息",{"2":{"204":2}}],["章节了解更多信息",{"2":{"172":1,"173":1,"174":1}}],["章节了解关于如何实现析构器的更多信息",{"2":{"166":1}}],["章节了解关于如何实现构造器的更多信息",{"2":{"166":1}}],["章节",{"2":{"159":1,"161":2}}],["项目根目录",{"2":{"301":1,"303":1}}],["项目时",{"2":{"238":1}}],["项目后",{"2":{"161":1}}],["项目一模一样",{"2":{"159":1}}],["项目的结构几乎和",{"2":{"159":1}}],["项目",{"0":{"159":1}}],["框架的",{"2":{"205":1}}],["框架可以使用自定义错误域和枚举来组织相关的错误类别",{"2":{"200":1}}],["框架中nslog函数的替代者",{"2":{"190":1}}],["框架为应用和框架提供了基层功能",{"2":{"178":1}}],["框架在头文件中公开",{"2":{"161":1}}],["框架或",{"2":{"161":1}}],["框架",{"0":{"177":1},"1":{"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"189":1,"190":1,"191":1},"2":{"158":1,"177":2,"217":1}}],["框架后",{"2":{"132":1}}],["迁移一个类到",{"2":{"234":1}}],["迁移代码到",{"2":{"230":1}}],["迁移工作提供了一个重新审视现有的",{"2":{"228":1}}],["迁移过程是不尽相同的",{"2":{"234":1}}],["迁移过程",{"0":{"230":1},"1":{"231":1,"232":1,"233":1},"2":{"228":1}}],["迁移",{"0":{"228":1,"265":1},"1":{"229":1,"230":1,"231":1,"232":1,"233":1,"234":1},"2":{"157":1,"265":1}}],["设计模式章节",{"2":{"232":1}}],["设计模式的时候",{"2":{"232":1}}],["设计模式",{"0":{"192":1},"1":{"193":1,"194":1,"195":1,"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"209":1},"2":{"192":1,"202":1,"263":1}}],["设计模式以及各种实践经验",{"2":{"157":1}}],["设置提交代码时的用户信息",{"2":{"383":1}}],["设置为",{"2":{"305":2}}],["设置为yes",{"2":{"260":1}}],["设置代码",{"2":{"203":1}}],["设置更早的部署版本会导致编译错误",{"2":{"160":1}}],["设置请求体仅在uiwebview中好使",{"2":{"92":1}}],["能帮助开发者开发出设计巧妙",{"2":{"192":1}}],["能让",{"2":{"168":1}}],["能够帮你更好地利用这种兼容性来开发",{"2":{"157":1}}],["能从构造器自动推断出类型",{"2":{"133":1}}],["易用",{"2":{"157":1}}],["理解",{"0":{"161":1},"2":{"157":1}}],["搭建",{"0":{"158":1},"1":{"159":1,"160":1},"2":{"157":1}}],["表头2",{"2":{"357":2,"369":1}}],["表头2|",{"2":{"357":2,"369":1}}],["表头1",{"2":{"357":4,"369":2}}],["表格中嵌入图片",{"0":{"361":1}}],["表格可以指定对齐方式",{"2":{"358":1}}],["表格单元中的内容可以和其他大多数gfm语法配合使用",{"2":{"359":1}}],["表格单元",{"2":{"357":16,"369":8}}],["表格",{"0":{"357":1},"1":{"358":1,"359":1,"360":1,"361":1},"2":{"308":1}}],["表示代码块中的行号从",{"2":{"300":1}}],["表示一套可扩充新值的常量的声明在标注",{"2":{"213":1}}],["表示一组固定值的常量声明在标注",{"2":{"213":1}}],["表示一条能访问到某个对象特定属性的路径",{"2":{"156":1}}],["表示字符串长度",{"2":{"181":1}}],["表现形式下访问这些字符的支持",{"2":{"181":1}}],["表达式语法",{"2":{"156":1}}],["表达式语法类似",{"2":{"156":1}}],["表达式这种创建方式不同的是",{"2":{"156":1}}],["表达式接受属性引用以及链式属性引用",{"2":{"156":1}}],["表达式创建",{"2":{"156":1}}],["表达式创建键路径来访问属性",{"2":{"156":1}}],["表达式来访问",{"2":{"156":1}}],["键值观察是一种能让某个对象在其他对象指定属性变化时得到通知的机制",{"2":{"201":1}}],["键值观察",{"0":{"201":1},"2":{"192":1}}],["键路径通过",{"2":{"156":1}}],["键路径是一个由多个键构成的字符串",{"2":{"156":1}}],["键之间用点分隔",{"2":{"156":1}}],["键是一个表示某个对象特定属性的字符串",{"2":{"156":1}}],["键和键路径也常用于键值监听",{"2":{"156":1}}],["键和键路径经常用于键值编码",{"2":{"156":1}}],["键和键路径",{"0":{"156":1},"2":{"132":1}}],["`counting",{"2":{"391":1}}],["`auto",{"2":{"391":1}}],["`fetching",{"2":{"391":1}}],["`epoll`",{"2":{"323":1}}],["`socket`",{"2":{"323":1}}],["`网络编程`",{"2":{"323":1}}],["`linux`",{"2":{"323":1}}],["`highlighted",{"2":{"296":2}}],["```ts",{"2":{"300":2,"302":1}}],["```html",{"2":{"295":1}}],["```js",{"2":{"292":1,"295":1,"296":3,"297":1,"298":1,"299":1,"302":1}}],["```",{"2":{"276":1,"292":1,"295":2,"296":3,"297":1,"298":1,"299":1,"300":3,"302":2}}],["`default`",{"2":{"218":1}}],["`dirname",{"2":{"95":1}}],["`和`perform",{"2":{"155":1}}],["`",{"2":{"155":2,"293":1,"296":2,"303":4,"391":3}}],["绝大多数情况下",{"2":{"155":1}}],["坚决不提倡使用这些",{"2":{"155":1}}],["甚至是内嵌的",{"2":{"303":1}}],["甚至无法保证对象能否响应选择器",{"2":{"155":1}}],["甚至可以利用扩展为类添加协议一致性而无需子类化",{"2":{"146":1}}],["修改远程仓库名",{"2":{"389":1}}],["修改结构体schroedingerscat的计算属性isalive的值也会改变计算属性isdead的值",{"2":{"220":1}}],["修改结构体",{"2":{"217":1}}],["修改符和",{"2":{"201":1}}],["修改conf",{"2":{"2":1}}],["修饰符的更多信息",{"2":{"201":1}}],["修饰符",{"2":{"163":1}}],["修饰符标记的声明还必须显式标记",{"2":{"153":1}}],["修饰符来要求通过",{"2":{"153":1}}],["дерево",{"2":{"152":2}}],["вдереве",{"2":{"152":1}}],["количество",{"2":{"152":1}}],["красный",{"2":{"152":2}}],["прячьорехи",{"2":{"152":1}}],["имя",{"2":{"152":1}}],["белка",{"2":{"152":1}}],["черный",{"2":{"152":1}}],["цвет",{"2":{"152":3}}],["别名",{"2":{"152":1,"334":1,"335":1}}],["枚举值",{"2":{"253":1}}],["枚举值的命名",{"2":{"253":1}}],["枚举声明",{"2":{"252":1}}],["枚举会在",{"2":{"252":1}}],["枚举时",{"2":{"219":1}}],["枚举的特性",{"2":{"218":1}}],["枚举的声明如下",{"2":{"218":1}}],["枚举",{"0":{"218":1,"255":1},"2":{"210":1,"218":2,"235":1}}],["枚举以及常量",{"2":{"180":1}}],["枚举类型以及枚举用例暴露给",{"2":{"152":1}}],["枚举添加存储型属性",{"2":{"146":1}}],["暴露给",{"2":{"152":1,"238":1}}],["读取并保留缓冲区中的值",{"2":{"226":1}}],["读取性能越高",{"2":{"44":1}}],["读写和只读",{"0":{"173":1},"2":{"162":1}}],["读写属性",{"2":{"151":1}}],["柯里化函数",{"2":{"151":1}}],["嵌套类型",{"2":{"151":1}}],["顶级函数",{"2":{"151":1}}],["独有特性",{"2":{"151":1}}],["子目录中包含的每个",{"2":{"283":1}}],["子句来匹配特定的错误代码以便区分可能的失败情况",{"2":{"196":1}}],["子类中标记internal修饰符的方法和属性",{"2":{"245":1}}],["子类中重写此方法时",{"2":{"198":1}}],["子类可以从",{"2":{"163":1}}],["子类",{"0":{"175":1},"2":{"162":1,"163":1,"234":1}}],["子类及其成员",{"2":{"151":1}}],["子传父",{"2":{"124":1}}],["操作符将其转换为更具体的类型",{"2":{"150":1}}],["判断常量或者变量是否引用同一对象",{"2":{"149":1}}],["比较两个对象内容是否相同",{"2":{"149":1}}],["比较两个对象可以使用两种方式",{"2":{"149":1}}],["比如如下内容将会把一个表格在页面中居中展示",{"2":{"369":1}}],["比如javascipt",{"2":{"355":1}}],["比如我们",{"2":{"331":1}}],["比如你在多个地方想使用同一个链接",{"2":{"328":1}}],["比如它的类型",{"2":{"234":1}}],["比如一个播放音效的音频通道或发起",{"2":{"203":1}}],["比如8",{"2":{"53":1}}],["比如latest",{"2":{"48":1}}],["比如",{"2":{"37":1,"67":1,"95":2,"161":1,"379":1}}],["比如使用protocol",{"2":{"33":1}}],["块引用有多级结构",{"0":{"351":1},"1":{"352":1,"353":1}}],["块引用",{"0":{"348":1},"1":{"349":1,"350":1,"351":1,"352":1,"353":1},"2":{"308":1}}],["块内的代码只会执行一次",{"2":{"203":1}}],["块类似",{"2":{"148":1}}],["块会保持对被捕获对象的强引用",{"2":{"148":1}}],["块兼容",{"2":{"147":1}}],["泛型来提供强类型的方法签名",{"2":{"177":1}}],["泛型",{"2":{"151":1}}],["泛型参数化带有类限定",{"2":{"145":1}}],["泛型类型参数导入到",{"2":{"145":1}}],["举个例子",{"2":{"142":1}}],["批量标注可以使用ns",{"2":{"142":1}}],["包含",{"0":{"303":1}}],["包含不可变和可变子类的类簇被统一桥接为单个值类型",{"2":{"179":1}}],["包含了推送与非推送版本",{"2":{"14":1}}],["包括子目录",{"2":{"384":1}}],["包括各种被隐式标记的情况",{"2":{"260":1}}],["包括一些只在内部使用而没有在头文件中暴露出来的值",{"2":{"218":1}}],["包括字符串常量",{"2":{"213":1}}],["包括你自己实例化的",{"2":{"186":1}}],["包括数据存储",{"2":{"178":1}}],["包括self",{"2":{"148":2}}],["包括类型属性和静态属性",{"2":{"146":1}}],["包括",{"2":{"142":1,"177":1,"182":1}}],["包括结构体与对象的引用",{"2":{"142":1}}],["其他任意需要居中展示的语法",{"2":{"369":1}}],["其语法与代码高亮类似",{"2":{"363":1}}],["其实前面介绍图片显示",{"2":{"361":1}}],["其实对于哪种字节排序的选择都是任意的",{"2":{"350":1}}],["其实呢",{"2":{"331":1}}],["其操作数首先被拷贝到一个无主临时缓冲区",{"2":{"226":1}}],["其生命周期会延续到本次调用结束",{"2":{"225":1}}],["其元素类型也会被桥接过去",{"2":{"183":1}}],["其默认实现是抛出nsinvalidargumentexception异常",{"2":{"155":1}}],["其值为",{"2":{"141":2}}],["其中host和hostname填写git服务器的域名",{"2":{"380":1}}],["其中http",{"2":{"372":1}}],["其中",{"2":{"372":1}}],["其中交战的两个派别无法就应该从哪一端打开一个半熟的鸡蛋达成一致",{"2":{"350":1}}],["其中包含了属性所在类型的类型信息",{"2":{"156":1}}],["其中包含分享链接的预览",{"2":{"63":1}}],["其中常用名称可以采用公司名称+app名称+环境名",{"2":{"14":1}}],["崩溃",{"2":{"141":1}}],["因此他的父亲",{"2":{"350":1}}],["因此只有标记public或open修饰符的",{"2":{"245":1}}],["因此只有在每个成员都需要使用",{"2":{"163":1}}],["因此大多数情况下你不需要专门去设置它",{"2":{"239":1}}],["因此最好选择一个没有子类的类开始",{"2":{"230":1}}],["因此使用",{"2":{"222":1}}],["因此构造器的第一个参数没有标签",{"2":{"222":1}}],["因此联合体作为结构体导入到",{"2":{"220":1}}],["因此能确信代码可以在应用所支持的任何平台上如期工作",{"2":{"208":1}}],["因此编译器会报告错误",{"2":{"208":1}}],["因此在初始化表达式中可以使用self",{"2":{"194":1}}],["因此在将可选值传递给类方法logsomevalue",{"2":{"143":1}}],["因此该后缀是多余的",{"2":{"187":1}}],["因此它们不再需要两个类了",{"2":{"179":1}}],["因此发布时需要同时包含",{"2":{"160":1}}],["因此应该使用",{"2":{"152":1}}],["因此",{"2":{"152":1,"155":1,"165":1,"167":2,"175":1,"211":1,"234":1,"303":1,"350":1}}],["因此甚至可以直接传递一个",{"2":{"147":1}}],["因此可以把一个",{"2":{"147":1}}],["因此将其作为隐式解包可选类型导入",{"2":{"142":1}}],["因此无法保证向下转换到具体类型一定成功",{"2":{"139":1}}],["因为图片本身和链接本身都支持url标识符的形式",{"2":{"330":1}}],["因为可能存在风险",{"2":{"294":2}}],["因为私有声明不会暴露给",{"2":{"260":1}}],["因为cake结构体第一个字段是匿名的",{"2":{"222":1}}],["因为count属性和character",{"2":{"141":1}}],["因为它们使用了",{"2":{"161":1}}],["因为",{"2":{"155":1,"182":1,"219":1}}],["因为该选择器存在于",{"2":{"155":1}}],["因为编译器无法保证结果",{"2":{"155":1}}],["因为扩展不能为类",{"2":{"146":1}}],["因为valuefromswift参数的类型是id",{"2":{"143":1}}],["因为anyobject类型的值在运行时才能确定其真实类型",{"2":{"141":1}}],["还有代表着服务器ssl传输状态的sectrustref类型的属性servertrust",{"2":{"372":1}}],["还有一些时候则最好创建",{"2":{"207":1}}],["还需要建立一个随机数然后对其进行数据签名",{"2":{"371":1}}],["还会缩短",{"2":{"253":1}}],["还会提供一个无参数的默认构造器",{"2":{"216":1}}],["还是基于混合语言的",{"2":{"247":1}}],["还是",{"2":{"236":1,"259":1}}],["还提供了一些相关的存取方法",{"2":{"175":1}}],["还提供了在对多关系中添加和移除对象的实例方法实现",{"2":{"175":1}}],["还提供了",{"2":{"152":1}}],["还可以通过在",{"2":{"300":1}}],["还可以指定多个单行",{"2":{"296":1}}],["还可以直接往现有项目中添加另一种语言的源文件",{"2":{"236":1}}],["还可以直接利用",{"2":{"183":1,"184":1,"185":1}}],["还可以将",{"2":{"170":1}}],["还可以利用",{"2":{"162":1}}],["还可以利用扩展来增加属性",{"2":{"146":1}}],["还可以使用cf",{"2":{"188":1}}],["还可以使用",{"2":{"162":1}}],["还可以用",{"2":{"156":1}}],["还可以为结构或是枚举添加协议一致性",{"2":{"146":1}}],["还可以为系统框架中的类型或者自定义类型定义扩展",{"2":{"146":1}}],["还引入了anyobject类型来表示一种对象类型",{"2":{"140":1}}],["还要高",{"2":{"43":1}}],["仍须在方法名后面跟上一对圆括号",{"2":{"137":1}}],["然而",{"2":{"136":1,"139":2,"146":1,"199":1,"209":1,"211":1,"259":1}}],["然后传递给服务端",{"2":{"372":1}}],["然后传入",{"2":{"205":1}}],["然后执行一系列步骤来产生主通讯密码",{"2":{"371":1}}],["然后将加密后的",{"2":{"371":1}}],["然后用服务器的公钥",{"2":{"371":1}}],["然后再将",{"2":{"260":1}}],["然后再启动",{"2":{"23":1}}],["然后在",{"2":{"257":1}}],["然后使用类扩展来采用",{"2":{"251":1}}],["然后重新赋值给操作数",{"2":{"226":1}}],["然后检查返回值是否为",{"2":{"197":1}}],["然后选择一个模板",{"2":{"159":1}}],["然后分享照片",{"2":{"67":1}}],["然后系统将切换回您的应用",{"2":{"63":1}}],["然后按住command+r进入进入到恢复工具界面",{"2":{"27":1}}],["然后点击",{"2":{"27":1}}],["然后导出为",{"2":{"14":1}}],["忽略凭据参数",{"2":{"372":1}}],["忽略",{"2":{"136":1}}],["作为产品模块名时",{"2":{"259":2}}],["作为错误参数",{"2":{"197":1}}],["作为抛出方法导入",{"2":{"195":1}}],["作为",{"2":{"161":2,"238":1,"306":1}}],["作为一个简洁",{"2":{"157":1}}],["作为替代",{"2":{"142":1}}],["作为类型属性导入",{"2":{"136":1}}],["作为标记weak关键字",{"2":{"136":1}}],["作为只读计算型属性",{"2":{"136":1}}],["作为可选类型或者非可选类型的属性导入",{"2":{"136":1}}],["加密算法的种类",{"2":{"371":2}}],["加载图片成功",{"2":{"135":1}}],["加上前缀",{"2":{"64":1}}],["小端",{"2":{"350":1}}],["小节查看在",{"2":{"202":1}}],["小节获取更多信息",{"2":{"148":1,"155":2,"203":1}}],["小节获取更多关于可选类型的信息",{"2":{"142":1}}],["小节",{"2":{"135":1,"136":2,"189":1,"194":1}}],["小于号",{"2":{"8":1}}],["请勿继续",{"2":{"292":2}}],["请向标题添加后缀",{"2":{"281":1}}],["请确保",{"2":{"229":1}}],["请使用",{"2":{"213":1}}],["请考虑如下整形常量类型",{"2":{"213":1}}],["请考虑如下来自于",{"2":{"195":1}}],["请在该类的声明中使用",{"2":{"163":1}}],["请参阅在",{"2":{"241":1,"246":1}}],["请参阅在应用程序的",{"2":{"231":1}}],["请参阅为产品模块命名小节",{"2":{"238":1,"240":1}}],["请参阅采用",{"2":{"232":1}}],["请参阅swift",{"2":{"231":1,"248":1}}],["请参阅键和键路径小节",{"2":{"201":1}}],["请参阅强制动态派发小节",{"2":{"201":1}}],["请参阅",{"2":{"135":1,"136":1,"142":1,"148":1,"149":1,"153":1,"155":2,"156":1,"161":2,"166":2,"172":1,"173":1,"174":1,"189":1,"190":1,"194":1,"199":1,"202":1,"203":1,"204":2,"205":2,"229":1,"232":1,"240":1,"245":1,"258":1,"260":1}}],["请求的网络管理者",{"2":{"203":1}}],["请求的url及参数如上图所示",{"2":{"67":1}}],["请求体的内容并没携带一起发送给服务器",{"2":{"92":1}}],["请求",{"2":{"66":1}}],["请求传送的参数包含中文字符",{"0":{"3":1}}],["许多系统框架中的",{"2":{"135":1}}],["被标记宏的下标方法会在方法名前加双下划线",{"2":{"257":1}}],["被迁移的类不能有任何",{"2":{"234":1}}],["被重命名的类型",{"0":{"180":1},"2":{"177":1}}],["被桥接的类型",{"0":{"179":1},"2":{"177":1}}],["被捕获的变量可以直接修改",{"2":{"147":1}}],["被导入到",{"2":{"145":1,"218":1}}],["被称为可失败初始化",{"2":{"135":1}}],["被关闭连接",{"2":{"90":1}}],["应询问代理能否响应消息",{"2":{"193":1}}],["应该使用takeunretainedvalue",{"2":{"189":1}}],["应该将类型声明为隐式解包可选类型",{"2":{"169":1}}],["应该这样写",{"2":{"134":1}}],["应用可能需要使用更复杂的本地化形式",{"2":{"206":1}}],["应用中的部分内容成为了可能",{"2":{"157":1}}],["应用开发流程中",{"2":{"157":1}}],["应用的target就是一个模块",{"2":{"167":1}}],["应用的方法",{"2":{"132":1}}],["应用的名称",{"2":{"9":1}}],["应用面板找到应用编号",{"2":{"64":1}}],["应用编号",{"2":{"64":1}}],["应用提供",{"2":{"63":1}}],["应用",{"0":{"375":1},"2":{"63":5,"66":2,"130":1,"157":1,"167":1}}],["应用程序中",{"2":{"228":1}}],["应用程序的机会",{"2":{"228":1}}],["应用程序的生命周期事件",{"2":{"37":1}}],["应用程序进入前台",{"2":{"37":1}}],["应用程序进入后台",{"2":{"37":1}}],["应用程序启动完毕",{"2":{"37":1}}],["应用程序本身的各种事件",{"2":{"37":1}}],["应用场景",{"0":{"30":1}}],["应用名称",{"2":{"9":1}}],["像这样调用一个工厂方法",{"2":{"134":1}}],["从process",{"2":{"209":1}}],["从没有内存管理标注的",{"2":{"189":1}}],["从类型名字的末端移除",{"2":{"187":1}}],["从现有的",{"2":{"157":1}}],["从而指引",{"2":{"256":1}}],["从而让",{"2":{"250":1}}],["从而将其从",{"2":{"233":1}}],["从而保证在应用程序的生命周期内",{"2":{"203":1}}],["从而提供一个统一的资源或服务的访问入口",{"2":{"203":1}}],["从而根据日志事件的重要性来控制日志信息如何被处理",{"2":{"190":1}}],["从而能够将其正确导入",{"2":{"254":2}}],["从而能够根据命名推导出内存管理策略",{"2":{"188":1}}],["从而能使用同样简洁的构造器语法",{"2":{"134":1}}],["从而帮助编译器自动插入内存管理函数调用",{"2":{"188":1}}],["从而可以在",{"2":{"179":1}}],["从而在",{"2":{"177":1}}],["从而增加代码的安全性和可预测性",{"2":{"166":1}}],["从而消除编译警告",{"2":{"143":1}}],["从而判断初始化是否成功",{"2":{"135":1}}],["从证书颁发机构请求证书",{"2":{"14":1}}],["你还能用",{"2":{"239":1,"244":1}}],["你还可以指定一个日志系统中定义的日志级别",{"2":{"190":1}}],["你还可以通过显式提供类型标注",{"2":{"182":1}}],["你还可以在anyobject类型的值上调用任意",{"2":{"140":1}}],["你还可以再用其他类型的对象为其赋值",{"2":{"140":1}}],["你需要知道",{"2":{"232":1}}],["你也不用创建头文件",{"2":{"230":1}}],["你也可以通过提供类型标注的方式利用字符串字面量创建nsstring对象",{"2":{"181":1}}],["你也可以使用if",{"2":{"141":1}}],["你无法使用cf",{"2":{"217":1}}],["你可能会遇到使用",{"2":{"213":1}}],["你可以像这样传递它的选项",{"2":{"293":1}}],["你可以导入位于其他",{"2":{"247":1}}],["你可以编辑这个",{"2":{"238":1}}],["你可以从",{"2":{"205":1}}],["你可以从使用",{"2":{"199":1}}],["你可以让自定义类型遵守",{"2":{"205":1}}],["你可以传递",{"2":{"197":1}}],["你可以创建一个新的oslog对象",{"2":{"190":1}}],["你可以通过",{"2":{"205":1}}],["你可以通过使用nsstring或printf格式化字符串连同单个或多个尾参数来格式化日志信息",{"2":{"190":1}}],["你可以通过顶级函数os",{"2":{"190":1}}],["你可以使用可用性条件",{"2":{"258":1}}],["你可以使用autoreleasepool",{"2":{"207":1}}],["你可以使用as运算符将string值转换为nsstring对象",{"2":{"181":1}}],["你可以使用as操作符在这些桥接类型间进行转换",{"2":{"179":1}}],["你可以使用",{"2":{"152":1,"153":1,"182":1,"196":1,"197":1,"258":1}}],["你可以将其赋值为nil",{"2":{"142":1}}],["你可以将任意类型的对象赋值给一个anyobject类型的常量或者变量",{"2":{"140":1}}],["你可以用",{"2":{"205":1,"213":1,"235":1}}],["你可以用可选绑定语法对这种构造器的可选类型的返回值进行解包",{"2":{"135":1}}],["你可以用同样的方式使用它们",{"2":{"133":1}}],["你可以在github上搜索",{"2":{"322":1}}],["你可以在项目中同时使用两种语言",{"2":{"235":1}}],["你可以在自己的代码中使用cf",{"2":{"217":1}}],["你可以在你的",{"2":{"135":1}}],["你可以在赋值时显式地声明类型",{"2":{"133":1}}],["你甚至可以使用",{"2":{"192":1}}],["你依然可以在",{"2":{"192":1}}],["你应该尽量避免在",{"2":{"179":1}}],["你应该使用",{"2":{"133":1}}],["你创建了一个基于文档的",{"2":{"167":1}}],["你会始终使用原生的",{"2":{"166":1}}],["你不需要创建自己的自动释放池块",{"2":{"207":1}}],["你不需要再调用cfretain",{"2":{"188":1}}],["你不需要调用alloc",{"2":{"133":1}}],["你不应该为",{"2":{"149":1}}],["后会做如下处理",{"2":{"257":1}}],["后的命名",{"2":{"253":1,"255":1}}],["后续小节会介绍更多细节",{"2":{"236":1}}],["后两种类型会转换成unsafepointer",{"2":{"224":1}}],["后面跟着相应的版本号",{"2":{"208":1}}],["后面的xxx替换成自己的appleid的账号",{"2":{"95":1}}],["后者使用一个尾随的",{"2":{"199":1}}],["后缀",{"2":{"195":1,"284":1}}],["后如下所示",{"2":{"151":1,"220":1}}],["后将如下所示",{"2":{"142":1,"145":1}}],["后",{"2":{"133":1,"145":3,"170":1,"218":1,"220":1,"222":1,"226":1,"248":1}}],["构建的",{"2":{"160":1}}],["构建发布到图谱",{"2":{"66":1}}],["构造过程完成后",{"2":{"169":1}}],["构造方法转换为",{"2":{"166":1}}],["构造方法时都不会出现init单词",{"2":{"133":1}}],["构造方法",{"2":{"133":1}}],["构造器后的方法名",{"2":{"254":1}}],["构造器将可选指针转化为int值",{"2":{"215":1}}],["构造器",{"2":{"166":3,"253":1}}],["构造器和实例方法会成为",{"2":{"151":1}}],["构造器初始化uiimage对象便会失败",{"2":{"135":1}}],["构造器在导入到",{"2":{"135":1}}],["构造器会作为init",{"2":{"135":2}}],["构造器会返回nil",{"2":{"135":1}}],["构造器会直接返回它们初始化的对象",{"2":{"135":1}}],["构造器语法的区别在实例化对象时将更为明显",{"2":{"133":1}}],["构造器声明",{"2":{"133":1}}],["构造器导入到",{"2":{"133":1}}],["构造器以init开头",{"2":{"133":1}}],["改名文件",{"2":{"384":1}}],["改善并提高你编写",{"2":{"132":1}}],["改为静态打包",{"2":{"26":1}}],["学会如何利用互用性来重新定义",{"2":{"132":1}}],["学习",{"2":{"23":1}}],["融入到你的开发流程中时",{"2":{"132":1}}],["互用性让你在编写",{"2":{"162":1}}],["互用性很重要的一点就是允许你在编写",{"2":{"132":1}}],["互用性是能让",{"2":{"132":1}}],["互动游戏",{"2":{"30":1}}],["哈希",{"0":{"150":1},"2":{"132":1}}],["闭包也会保持对被捕获对象的强引用",{"2":{"148":1}}],["闭包传递给一个接受块作为参数的",{"2":{"147":1}}],["闭包与块有相似的捕获语义",{"2":{"147":1}}],["闭包与函数具有相同类型",{"2":{"147":1}}],["闭包与",{"2":{"147":1}}],["闭包导入",{"2":{"147":1}}],["闭包",{"0":{"147":1},"1":{"148":1},"2":{"132":1}}],["轻量泛型",{"0":{"145":1},"2":{"132":1}}],["轻触",{"2":{"63":1}}],["访问https时",{"2":{"371":1}}],["访问选项值像枚举一样也用点",{"2":{"219":1}}],["访问",{"2":{"217":1}}],["访问属性",{"0":{"136":1},"2":{"132":1}}],["访问account的实现代码",{"2":{"74":1}}],["删除远程tag",{"2":{"387":1}}],["删除远程分支",{"2":{"386":1}}],["删除本地tag",{"2":{"387":1}}],["删除分支",{"2":{"386":1}}],["删除工作区文件",{"2":{"384":1}}],["删除文件",{"0":{"384":1}}],["删除线可混合使用",{"2":{"325":1}}],["删除线",{"0":{"325":1},"2":{"308":1,"325":1}}],["删除视图",{"2":{"130":1}}],["删除music",{"2":{"27":1}}],["跨域的问题",{"2":{"129":1}}],["条件语句中使用可用性信息",{"2":{"258":1}}],["条件编译块",{"2":{"210":1}}],["条件分支不会被执行",{"2":{"141":1}}],["条件渲染",{"0":{"126":1}}],["条件判断",{"2":{"111":1}}],["父类中继承所有的功能",{"2":{"163":1}}],["父传子",{"2":{"124":1}}],["父子组件之间的交互",{"2":{"113":1}}],["只是在三个反引号后面写diff",{"2":{"363":1}}],["只剩下选项值名称",{"2":{"219":1}}],["只能是字母",{"2":{"259":1}}],["只能提供一个新的",{"2":{"217":1}}],["只能做到web分享",{"2":{"63":1}}],["只应在必要时才使用这些类型",{"2":{"211":1}}],["只需修改build",{"2":{"259":1}}],["只需确保被导入框架的build",{"2":{"247":1}}],["只需将",{"2":{"245":1}}],["只需创建一个",{"2":{"205":1}}],["只需在属性或方法声明前标记",{"2":{"169":1}}],["只在最底部给标识符定义出实际的url链接即可",{"2":{"328":1}}],["只在实例变量为nil时才初始化实例变量",{"2":{"194":1}}],["只在客户端",{"2":{"124":1}}],["只为其提供一个读取方法使其只读",{"2":{"173":1}}],["只不过会为该类型指定一个数组",{"2":{"169":1}}],["只要选择了一种规则并且始终如一的坚持",{"2":{"350":1}}],["只要它们所属的类继承自",{"2":{"260":1}}],["只要设值或取值方法被标记ns",{"2":{"257":1}}],["只要闭包的参数列表或闭包体内没有引用泛型类型的参数",{"2":{"227":1}}],["只要",{"2":{"201":1}}],["只要简单地添加导入语句到",{"2":{"161":1}}],["只要兼容于",{"2":{"151":1}}],["只有标记public或open修饰符的声明才会出现在自动生成的头文件中",{"2":{"260":1}}],["只有继承自",{"2":{"248":1,"260":1}}],["只有使用",{"2":{"227":1}}],["只有一个重要的区别",{"2":{"159":1}}],["只有在",{"2":{"136":1}}],["只读属性",{"2":{"151":1}}],["已经连接完毕",{"2":{"169":1}}],["已移出真实",{"2":{"124":1}}],["已插入真实",{"2":{"124":1}}],["已生成",{"2":{"14":1}}],["向一个对象发送无法识别的选择器将造成接收者调用doesnotrecognizeselector",{"2":{"155":1}}],["向下转换",{"0":{"139":1},"2":{"132":1}}],["向事件传递参数",{"2":{"122":1}}],["向客户端",{"2":{"90":1}}],["声明也会出现在自动生成的头文件中",{"2":{"260":1}}],["声明不会出现在自动生成的头文件中",{"2":{"260":1}}],["声明不会出现在这个头文件中",{"2":{"240":1}}],["声明添加可用性信息",{"2":{"258":1}}],["声明如下所示",{"2":{"252":1}}],["声明时",{"2":{"245":1}}],["声明才会出现在这个自动生成的头文件中",{"2":{"245":1}}],["声明会暴露给包含这个导入语句的",{"2":{"241":1,"246":1}}],["声明了",{"2":{"240":1}}],["声明可在",{"0":{"252":1},"2":{"235":1}}],["声明可被",{"0":{"250":1},"2":{"235":1}}],["声明来指明其可用性",{"2":{"208":1}}],["声明一个计算型属性时",{"2":{"173":1}}],["声明一个存储型属性时",{"2":{"173":1}}],["声明一个",{"2":{"169":1}}],["声明符合多个协议的类型时",{"2":{"165":1}}],["声明符合单个协议的类型时",{"2":{"165":1}}],["声明和采用",{"2":{"162":1}}],["声明协议",{"0":{"176":1},"2":{"162":1}}],["声明在",{"2":{"152":1}}],["声明",{"0":{"120":1,"257":1},"2":{"142":1,"150":1,"151":1,"183":1,"184":1,"185":1,"195":1,"213":3,"235":1,"240":2,"257":1,"260":1}}],["语言枚举会自动遵守equatable协议",{"2":{"218":1}}],["语言枚举",{"2":{"218":1}}],["语言枚举导入为",{"2":{"219":1}}],["语言枚举导入为结构体",{"2":{"218":1}}],["语言枚举导入为原始值类型为int的",{"2":{"218":1}}],["语言基本数值类型",{"2":{"211":1}}],["语言设计和模式",{"2":{"210":1}}],["语言的类型和特性保持了兼容性",{"2":{"210":1}}],["语言的互用性",{"2":{"210":1}}],["语言",{"0":{"210":1},"1":{"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1},"2":{"263":1}}],["语言特性的",{"2":{"232":1}}],["语言特性",{"2":{"162":1}}],["语言类库",{"2":{"161":2}}],["语言学习",{"2":{"23":1}}],["语法2由两部分组成",{"2":{"328":1}}],["语法2",{"0":{"322":1}}],["语法1",{"0":{"321":1}}],["语法使用",{"2":{"248":1}}],["语法使用这些自定义的",{"2":{"239":1,"244":1}}],["语法来标明不可恢复的程序错误",{"2":{"199":1}}],["语法调用它的一个构造器",{"2":{"133":1}}],["语法实例化这些类并与之交互",{"2":{"132":1}}],["语法",{"0":{"118":1,"274":1,"334":1,"337":1,"340":1,"343":1,"346":1,"352":1,"355":1,"363":1},"1":{"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1},"2":{"223":6,"293":1,"323":1,"325":1,"326":1,"328":1,"329":1,"330":1,"331":1}}],["低版本的npm",{"2":{"117":1}}],["低于该版本",{"2":{"53":1}}],["增加一个新的远程仓库",{"2":{"389":1}}],["增加",{"0":{"384":1}}],["增加了访问本地目录的权限",{"2":{"116":1}}],["增加字段",{"2":{"3":1}}],["路由的作用为切换视图",{"2":{"130":1}}],["路由的作用",{"2":{"130":1}}],["路由",{"0":{"114":1}}],["路由参数来进行通讯",{"2":{"113":1}}],["移动端组件库",{"2":{"113":1}}],["移除系统",{"2":{"20":1}}],["回退到n次提交之前",{"2":{"390":1}}],["回退到前3次提交之前",{"2":{"390":1}}],["回退到上个版本",{"2":{"390":1}}],["回滚",{"0":{"390":1}}],["回到顶部",{"2":{"331":2}}],["回到创建证书的页面",{"2":{"14":1}}],["回调函数",{"2":{"113":1}}],["生成一个github用的ssh",{"2":{"380":1}}],["生成一个公司用的ssh",{"2":{"380":1}}],["生成的页面和内部链接带有",{"2":{"284":1}}],["生命周期的方法有",{"2":{"124":1}}],["生命周期函数",{"0":{"124":1},"2":{"113":1}}],["生产系统",{"2":{"88":1}}],["初始化也不会失败",{"2":{"218":1}}],["初始化失败时",{"2":{"135":1}}],["初始化",{"0":{"133":1},"1":{"134":1,"135":1},"2":{"132":1}}],["初始化方法中申明",{"2":{"113":1}}],["初始化项目",{"0":{"21":1,"84":1,"103":1,"106":1,"117":1},"1":{"107":1}}],["引入服务",{"2":{"113":1}}],["引用类型",{"2":{"99":1,"179":2}}],["非托管对象的知识",{"2":{"188":1}}],["非托管对象",{"0":{"189":1},"2":{"155":1,"177":1}}],["非可选类型会被标注",{"2":{"151":1}}],["非父子组件之间的交互",{"2":{"113":1}}],["非完美越狱",{"2":{"39":1}}],["写在类里面",{"2":{"113":1}}],["安全性与隐私中设置",{"2":{"377":1}}],["安全取值",{"2":{"112":1}}],["安装插件",{"0":{"107":1}}],["安装ionic",{"2":{"102":1,"105":1}}],["安装定时器",{"2":{"85":1}}],["安装太慢",{"2":{"83":1}}],["安装步骤",{"0":{"71":1}}],["安装下载好的itunes",{"2":{"27":1}}],["安装连接",{"2":{"27":1}}],["安装指定版本的",{"2":{"82":1}}],["安装指定版本",{"2":{"20":1}}],["安装最新版本",{"2":{"20":1}}],["安装到钥匙串中",{"2":{"14":1}}],["安装",{"0":{"368":1},"2":{"4":1,"20":1,"39":1,"130":1,"366":1}}],["管道",{"2":{"112":1}}],["循环数据",{"2":{"111":1}}],["用ssh命令分别测试",{"2":{"380":1}}],["用如下语法导入",{"2":{"241":1}}],["用contains",{"2":{"219":1}}],["用remove",{"2":{"219":1}}],["用来处理未来可能的平台",{"2":{"208":1}}],["用于自己进行一些开发活动",{"2":{"379":1}}],["用于公司内部的工作开发",{"2":{"379":1}}],["用于将一个非托管对象转换为一个可接受内存管理的对象",{"2":{"189":1}}],["用于操作对象的原始指针的值可能会是null",{"2":{"142":1}}],["用于表单元素",{"2":{"110":1}}],["用户不光要给服务器",{"2":{"371":1}}],["用户使用字典字面量作为替代",{"2":{"256":1}}],["用户测试",{"2":{"88":1}}],["用户轻触",{"2":{"63":1}}],["用户",{"2":{"2":1}}],["属性默认都是强引用",{"2":{"172":1}}],["属性通常会有一系列用于指定该属性的一些附加信息的属性特性",{"2":{"171":1}}],["属性以及常量",{"2":{"161":1}}],["属性声明",{"2":{"145":1}}],["属性声明中并无相应体现",{"2":{"136":1}}],["属性引用一个视图控制器",{"2":{"144":1}}],["属性类型或者返回值类型是否可以为null或nil值",{"2":{"142":1}}],["属性",{"0":{"121":1},"2":{"110":1,"121":1,"152":1,"156":1,"173":1,"176":1,"201":1,"250":1}}],["双向绑定",{"2":{"110":2}}],["双引号",{"2":{"8":1,"25":1}}],["值来表明方法调用失败",{"2":{"195":1}}],["值",{"2":{"195":1,"227":1}}],["值可表示的最大值是127",{"2":{"182":1}}],["值转换为",{"2":{"182":1}}],["值而不是int和nsrange值",{"2":{"181":1}}],["值为",{"2":{"138":4}}],["值或者对象作为id参数传入",{"2":{"138":1}}],["值绑定",{"2":{"110":2}}],["值类型介绍",{"2":{"99":1}}],["值类型",{"2":{"99":1,"179":1}}],["绑定",{"0":{"110":1}}],["绑定数据",{"2":{"109":1}}],["命令全体臣民吃鸡蛋时打破较小的一端",{"2":{"350":1}}],["命令行工具",{"2":{"102":1,"105":1}}],["命名",{"0":{"253":1},"1":{"254":1,"255":1},"2":{"232":1,"235":1}}],["命名可选参数",{"2":{"25":1}}],["未定义",{"2":{"99":1}}],["布尔",{"2":{"99":1}}],["数学方程",{"0":{"304":1}}],["数组字面量创建nsset对象",{"2":{"184":1}}],["数组字面量创建nsarray对象",{"2":{"183":1}}],["数组",{"0":{"183":1},"2":{"177":1,"183":2}}],["数值时必须使用",{"2":{"182":1}}],["数值来创建",{"2":{"182":1}}],["数值",{"0":{"182":1},"2":{"177":1}}],["数字在显示的时候变成了英文字母",{"2":{"343":1,"344":1}}],["数字1还是1",{"2":{"343":1,"344":1}}],["数字",{"2":{"99":1,"259":1}}],["数据结构",{"2":{"352":1,"353":1}}],["数据形式创建",{"2":{"205":1}}],["数据",{"2":{"205":2}}],["数据都保存成了文件",{"2":{"44":1}}],["数据则根据大小不同选择",{"2":{"44":1}}],["数据越小",{"2":{"44":1}}],["数据统计速度快",{"2":{"44":1}}],["数据统计缓慢",{"2":{"44":1}}],["数据库的",{"2":{"44":1}}],["数据类型大小计算",{"2":{"210":1}}],["数据类型",{"0":{"99":1},"2":{"42":2}}],["数据存储方式对比",{"0":{"42":1}}],["数据传输格式",{"0":{"32":1}}],["警告",{"0":{"299":1},"2":{"98":1,"289":1,"292":1}}],["错误类型",{"0":{"252":1},"2":{"235":1}}],["错误模式传递的错误中恢复",{"2":{"199":1}}],["错误模式截然不同",{"2":{"199":1}}],["错误处理是可选的",{"2":{"196":1}}],["错误处理",{"0":{"195":1},"1":{"196":1,"197":1,"198":1,"199":1,"200":1},"2":{"192":1}}],["错误",{"0":{"299":1},"2":{"98":1,"289":1}}],["输出",{"2":{"287":1,"288":1,"289":1,"291":1,"292":1,"295":1,"296":3,"297":1,"298":1,"299":1,"300":1,"301":2,"302":2,"304":1}}],["输出语句",{"0":{"98":1}}],["输入框的下拉列表中选择current",{"2":{"175":1}}],["输入框中输入类名",{"2":{"175":1}}],["输入框中进行设置",{"2":{"170":1}}],["输入",{"2":{"98":1,"287":1,"288":1,"289":1,"291":1,"292":1,"295":1,"296":3,"297":1,"298":1,"299":1,"300":1,"301":2,"302":2,"303":2,"304":1}}],["输入命令",{"2":{"27":1}}],["输入环境后保存",{"2":{"23":1}}],["输入电脑登录用户的密码",{"2":{"14":1}}],["输入导出的密码",{"2":{"14":1}}],["输入存储名称",{"2":{"14":1}}],["输入名称名称",{"2":{"14":1}}],["输入邮箱地址",{"2":{"14":1}}],["验证并上传到app",{"2":{"95":1}}],["验证是否安装成功",{"2":{"20":1}}],["清理完成",{"2":{"95":1}}],["正在被重新渲染",{"2":{"124":1}}],["正在编译工程",{"2":{"95":1}}],["正在清理工程",{"2":{"95":1}}],["正在玩游戏",{"2":{"37":1}}],["工程名",{"2":{"95":1}}],["工程绝对路径",{"2":{"95":1}}],["工具",{"0":{"39":1},"2":{"39":2}}],["企业证书打包",{"2":{"94":1}}],["浏览器通知服务器已经准备就绪",{"2":{"371":1}}],["浏览器",{"2":{"371":1}}],["浏览器随机产生一个用于后面通讯的",{"2":{"371":1}}],["浏览器利用服务器传递过来的信息验证服务器的合法性",{"2":{"371":1}}],["浏览器验证证书信息",{"2":{"371":1}}],["浏览器首先向服务器发送一个访问的请求",{"2":{"371":1}}],["浏览器会帮我们做很多影藏的工作",{"2":{"371":1}}],["浏览器发送的信息",{"2":{"90":1}}],["浏览器提供",{"2":{"63":1}}],["服务器发过来的质询",{"2":{"372":1}}],["服务器通知浏览器已经准备就绪",{"2":{"371":1}}],["服务器和客服端用相同的主通讯密码即",{"2":{"371":1}}],["服务器将自己的私钥解开加密的",{"2":{"371":1}}],["服务器各自生成通话密码",{"2":{"371":1}}],["服务器身份验证",{"2":{"371":1}}],["服务器的公钥从步骤2中的服务器的证书中获得",{"2":{"371":1}}],["服务器的合法性包括",{"2":{"371":1}}],["服务器证书上的域名是否和服务器的实际域名相匹配",{"2":{"371":1}}],["服务器向客户端传送ssl协议的版本号",{"2":{"371":1}}],["服务器端返回证书",{"2":{"371":1}}],["服务器与客户端之间通讯所需要的各种信息",{"2":{"371":1}}],["服务器接收到一些表示食品杂货店商品的",{"2":{"205":1}}],["服务器返回证书时",{"2":{"372":1}}],["服务器返回的信息",{"2":{"90":1}}],["服务器返回收到消息",{"2":{"90":1}}],["服务端要求的认证方法几乎总是servertrust方式",{"2":{"372":1}}],["服务端要求客户端对其验证的方法authenticationmethod等重要的信息",{"2":{"372":1}}],["服务端错误",{"2":{"90":1}}],["服务端示例",{"2":{"90":1}}],["本文url标识符都放置于文末",{"2":{"330":1}}],["本文介绍markdown语法",{"2":{"307":1}}],["本例中zhihu",{"2":{"328":1}}],["本例使用tomcat7作为服务器容器",{"2":{"90":1}}],["本地化字符串最常见的形式可能仅仅需要一个本地化键和一句注释",{"2":{"206":1}}],["本地化",{"0":{"206":1},"2":{"192":1}}],["本地图片数据",{"2":{"109":1}}],["本地名为",{"2":{"83":1}}],["断开连接时销毁心跳",{"2":{"90":1}}],["网络协议",{"0":{"374":1}}],["网络",{"0":{"373":1},"1":{"374":1,"375":1}}],["网络编程",{"2":{"323":1}}],["网络连接中断被调用",{"2":{"90":1}}],["网络状态检测",{"0":{"54":1}}],["失败了就去重连",{"2":{"90":1}}],["失败后重试10次",{"2":{"34":1}}],["压力测试",{"2":{"88":1}}],["负载测试",{"2":{"88":1}}],["质量保证体系",{"2":{"88":1}}],["qq",{"2":{"380":1}}],["q",{"2":{"90":2,"392":1}}],["qas",{"2":{"88":1}}],["qualifiedset",{"2":{"150":2}}],["qualifieddictionary",{"2":{"150":2}}],["quality",{"2":{"88":1,"254":2}}],["quit",{"2":{"392":1}}],["quiet",{"2":{"95":3}}],["quicktime",{"2":{"44":1}}],["questions",{"2":{"59":1,"395":1,"396":1}}],["queue",{"2":{"16":1,"61":13,"67":4,"79":3,"90":5}}],["quotient",{"2":{"214":2}}],["quote",{"2":{"66":4}}],["quot",{"0":{"60":2,"68":2,"86":2,"91":2},"1":{"92":2},"2":{"3":8,"4":2,"8":4,"9":2,"14":18,"17":2,"21":2,"26":2,"27":2,"34":2,"36":2,"37":2,"40":2,"44":2,"53":2,"54":2,"57":2,"58":2,"59":2,"61":2,"67":2,"78":2,"86":4,"88":2,"90":2,"95":2,"100":2,"233":2,"238":2,"240":2,"241":4,"246":2,"285":4,"292":2,"326":2,"328":2,"330":2,"372":2,"377":2,"390":2,"395":2,"397":6}}],["与指定的远程分支建立追踪关系",{"2":{"386":1}}],["与此相似",{"2":{"205":1}}],["与此相反",{"2":{"155":1}}],["与使用",{"2":{"156":1}}],["与之类似",{"2":{"145":1,"150":1,"179":1}}],["与",{"0":{"132":1,"168":1,"210":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"169":1,"170":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1},"2":{"161":1,"162":1,"166":1,"192":1,"235":1,"263":2}}],["与url相关的处理",{"2":{"86":1}}],["与客户端没有关系",{"2":{"31":1}}],["镜像使用帮助",{"0":{"83":1}}],["官方提供了一键生成项目初始结构的脚手架react",{"2":{"82":1}}],["官方文档",{"2":{"62":1}}],["模拟https证书认证",{"0":{"372":1}}],["模拟器打包path",{"2":{"26":1}}],["模型实体使用",{"2":{"175":1}}],["模块还会生成",{"2":{"161":1}}],["模块到",{"2":{"161":1}}],["模块",{"2":{"161":2}}],["模块的下载",{"2":{"82":1}}],["模板变量",{"2":{"113":1}}],["提交所有tag",{"2":{"387":1}}],["提交指定tag",{"2":{"387":1}}],["提交时显示所有diff信息",{"2":{"385":1}}],["提交工作区自上次commit之后的变化",{"2":{"385":1}}],["提交暂存区的指定文件到仓库区",{"2":{"385":1}}],["提交暂存区到仓库区",{"2":{"385":1}}],["提示",{"2":{"292":1}}],["提示用户允许访问账号信息",{"2":{"74":1}}],["提示用户添加账号信息",{"2":{"74":1}}],["提供",{"2":{"175":1}}],["提供了一些与",{"2":{"211":1}}],["提供了一些方式来使用常见的",{"2":{"210":1}}],["提供了如下桥接值类型用于替代如下",{"2":{"179":1}}],["提供了高效便捷的方式来使用",{"2":{"177":1}}],["提供了底层存储以及nsmanagedobject子类的属性实现",{"2":{"175":1}}],["提供了下面这个fix",{"2":{"164":1}}],["提供的替代",{"2":{"82":1}}],["方式二",{"2":{"392":1}}],["方式一",{"2":{"392":1}}],["方法可以优化为一个返回元组值的",{"2":{"257":1}}],["方法可用",{"2":{"208":1}}],["方法将导致编译错误",{"2":{"256":1}}],["方法将不可用",{"2":{"208":1}}],["方法移除选项值",{"2":{"219":1}}],["方法添加选项值",{"2":{"219":1}}],["方法不可用",{"2":{"208":1}}],["方法不存在于nsdate对象中",{"2":{"141":1}}],["方法检查选项值",{"2":{"219":1}}],["方法检查一个类或者实例的方法是否可用",{"2":{"208":1}}],["方法检查某个对象是否符合特定协议",{"2":{"204":1}}],["方法检查某个对象是否是特定类型的实例",{"2":{"204":1}}],["方法检测是否有某个方法",{"2":{"78":1}}],["方法中发生错误",{"2":{"198":2}}],["方法声明上使用",{"2":{"195":1}}],["方法被",{"2":{"195":1}}],["方法和takeretainedvalue",{"2":{"189":1}}],["方法返回一个nil",{"2":{"195":1}}],["方法返回一个用来表示方法调用成功或失败的",{"2":{"195":1}}],["方法返回",{"2":{"188":1}}],["方法返回非可选值",{"2":{"151":1}}],["方法以及声明的类型如何在",{"2":{"161":1}}],["方法以及它的变体在兼容",{"2":{"155":1}}],["方法以及访问属性",{"2":{"140":1}}],["方法引用还可以加上圆括号",{"2":{"154":1}}],["方法在运行时可用时才去调用",{"2":{"208":1}}],["方法在",{"2":{"152":1}}],["方法会返回可选值",{"2":{"151":1}}],["方法会拥有",{"2":{"151":1}}],["方法会在指定类上执行一个操作",{"2":{"144":1}}],["方法没有指定返回类型",{"2":{"151":1}}],["方法没有参数",{"2":{"151":1}}],["方法名来自动推断被重写的父类方法",{"2":{"163":1}}],["方法名的类型",{"2":{"154":1}}],["方法名的其余部分则会被分配为相应的命名参数",{"2":{"133":1}}],["方法名上",{"2":{"151":1}}],["方法提供的基本实现仅仅是比较两个指针是否相同",{"2":{"149":1}}],["方法调用在行为上类似于隐式解包可选",{"2":{"141":1}}],["方法时",{"2":{"141":1}}],["方法时能保持无类型的灵活性",{"2":{"140":1}}],["方法导入到",{"2":{"137":1}}],["方法的声明",{"2":{"257":1}}],["方法的错误指针参数",{"2":{"198":1}}],["方法的错误参数也是它的第一个参数",{"2":{"195":1}}],["方法的最后一个非块类型的参数是",{"2":{"195":1}}],["方法的导入和调用请参阅",{"2":{"136":1}}],["方法的不安全调用",{"0":{"155":1},"2":{"132":1}}],["方法",{"0":{"137":1},"2":{"132":1,"136":1,"147":1,"149":2,"151":2,"152":1,"155":1,"156":2,"161":1,"177":1,"181":1,"189":2,"193":1,"195":1,"198":2,"201":1,"250":1,"253":1,"257":1}}],["方便接入",{"2":{"33":1}}],["方便以管理",{"2":{"14":1}}],["限制下拉没有回弹效果",{"2":{"77":1}}],["显示某个远程仓库的信息",{"2":{"389":1}}],["显示所有远程仓库",{"2":{"389":1}}],["显示当前分支的版本历史",{"2":{"388":1}}],["显示当前的git配置",{"2":{"383":1}}],["显示有变更的文件",{"2":{"388":1}}],["显示",{"2":{"377":1}}],["显示任何来源",{"0":{"377":1}}],["显示twitter分享功能",{"2":{"74":1}}],["显示的时候没有分享计数器",{"2":{"63":1}}],["申请访问account权限",{"2":{"74":1}}],["申请权限需要注意的事项",{"2":{"66":1}}],["暂时的解决方式",{"2":{"74":1}}],["暂停程序的操作",{"2":{"37":1}}],["问题",{"0":{"74":1}}],["拖拽到工程文件",{"2":{"71":1}}],["截图如下",{"2":{"67":1}}],["最终",{"2":{"215":1}}],["最完善的开源库",{"2":{"113":1}}],["最后一行再加上三个反引号```",{"2":{"355":1}}],["最后一个参数是一个星号",{"2":{"208":1}}],["最后使用一个闭包字面量作为参数equal的值",{"2":{"227":1}}],["最后进入自己的工程",{"2":{"83":1}}],["最后获取最新发布的信息",{"2":{"67":1}}],["最新的安装版本为12",{"2":{"27":1}}],["结合",{"0":{"168":1},"1":{"169":1,"170":1},"2":{"162":1}}],["结构提供了两个方法",{"2":{"189":1}}],["结构中",{"2":{"189":1}}],["结构体cfarraycallbacks的构造器使用nil作为参数retain和release的值",{"2":{"227":1}}],["结构体cake中",{"2":{"222":1}}],["结构体后仍将保持类似",{"2":{"220":1}}],["结构体如下所示",{"2":{"216":1}}],["结构体声明",{"2":{"216":1}}],["结构体",{"0":{"191":1,"216":1},"1":{"217":1},"2":{"146":1,"151":1,"177":1,"210":1,"216":1,"220":1}}],["结构和枚举扩充功能",{"2":{"146":1}}],["结论",{"2":{"67":1}}],["结果为nsorderedascending",{"2":{"53":1}}],["授权",{"2":{"67":1}}],["根据所需平台和版本有条件地执行代码",{"2":{"258":1}}],["根据官方文档的介绍",{"2":{"67":1}}],["根据app",{"0":{"14":1},"2":{"11":1}}],["且看下面的介绍",{"2":{"67":1}}],["没能继续测试是否能拿到用户发布的内容",{"2":{"67":1}}],["没有可靠的方法可以从",{"2":{"199":1}}],["没有",{"2":{"195":1}}],["没有readwrite和readonly特性",{"2":{"173":1}}],["没有头文件",{"2":{"159":1}}],["没有为空性标注的类型",{"2":{"142":1}}],["没有开发者平台",{"2":{"79":1}}],["没有元数据",{"2":{"44":1}}],["没有的函数的重载",{"2":{"25":1}}],["获取access",{"2":{"67":1}}],["获取较高权限",{"2":{"67":1}}],["获取图片大小",{"2":{"61":1}}],["登陆权限有如下几种",{"2":{"67":1}}],["登录即可启用分享",{"2":{"66":1}}],["登录功能添加至您的应用",{"2":{"66":1}}],["账号和密码",{"2":{"67":1}}],["返回布尔值",{"2":{"227":1}}],["返回一个",{"2":{"227":1}}],["返回一个cvalistpointer类型的值",{"2":{"215":1}}],["返回一个布尔值",{"2":{"124":1}}],["返回的是非保留对象还是被保留对象来选择对应的方法",{"2":{"189":1}}],["返回的",{"2":{"188":1}}],["返回的结果如下图所示",{"2":{"67":1}}],["返回值类型为",{"2":{"195":1}}],["返回值",{"2":{"67":1}}],["返回应用",{"2":{"64":1}}],["无序列表",{"0":{"333":1},"1":{"334":1,"335":1},"2":{"308":1}}],["无缝交互",{"2":{"229":1}}],["无论它是基于",{"2":{"247":1}}],["无论这个项目原本是基于",{"2":{"236":1}}],["无论是",{"2":{"259":1}}],["无论是系统框架还是自己代码中的枚举",{"2":{"218":1}}],["无论是否提供了内存管理标注",{"2":{"186":1}}],["无论在编译期还是运行期",{"2":{"138":1}}],["无法转化",{"2":{"260":1}}],["无法转换为",{"2":{"204":1}}],["无法改变框架的产品模块名",{"2":{"259":1}}],["无法映射回",{"2":{"161":1}}],["无法响应该选择器",{"2":{"155":1}}],["无法响应该方法",{"2":{"141":1}}],["无法再以",{"2":{"152":1}}],["无法在",{"2":{"151":1,"234":1}}],["无法通过扩展覆盖类型中既有的方法与属性",{"2":{"146":1}}],["无法加载图片",{"2":{"135":1}}],["无法识别的选择器和可选链语法",{"0":{"141":1},"2":{"132":1}}],["无回调",{"2":{"67":1}}],["无需再进行重写",{"2":{"149":1}}],["无需获取权限",{"2":{"67":1}}],["无需添加",{"2":{"66":1}}],["调用一个以函数指针为参数的函数时",{"2":{"227":1}}],["调用一个会抛出错误的方法时必须明确进行错误处理",{"2":{"196":1}}],["调用这种函数需使用",{"2":{"215":1}}],["调用方法可能会抛出nsinvalidargumentexception类型的unrecognized",{"2":{"208":1}}],["调用完子类的析构器后",{"2":{"166":1}}],["调用任何",{"2":{"133":1}}],["调用赋值",{"2":{"120":1}}],["调用该方法",{"2":{"37":1}}],["调整",{"2":{"66":1}}],["权限",{"2":{"66":1}}],["多级有序列表",{"0":{"342":1},"1":{"343":1,"344":1}}],["多级无序列表",{"0":{"336":1},"1":{"337":1,"338":1}}],["多态",{"2":{"340":1,"341":1}}],["多个单行",{"2":{"296":1}}],["多行文本",{"2":{"308":1}}],["多行与单行",{"2":{"296":1}}],["多行",{"2":{"296":2}}],["多媒体",{"2":{"66":1}}],["多用于推送",{"2":{"33":1}}],["视频",{"2":{"66":1}}],["视频会议",{"2":{"30":1}}],["照片",{"2":{"66":1}}],["特性以及文档注释等",{"2":{"234":1}}],["特性为",{"2":{"232":1}}],["特性的",{"2":{"227":1}}],["特性会增加应用程序编译后的体积并对性能产生不利影响",{"2":{"163":1}}],["特性会隐式地将",{"2":{"163":1}}],["特性添加到类中所有兼容",{"2":{"163":1}}],["特性编写",{"0":{"162":1},"1":{"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1},"2":{"232":1,"263":1}}],["特性取代你的",{"2":{"157":1}}],["特性何时会被隐式添加的相关信息",{"2":{"153":1}}],["特性",{"2":{"153":2,"163":2,"231":1,"232":1,"248":1}}],["特性和",{"2":{"153":1}}],["特性来控制一个声明是否可用",{"2":{"258":1}}],["特性来表示",{"2":{"227":1}}],["特性来明确指定相对应的",{"2":{"163":1}}],["特性来指定被归档的",{"2":{"152":1}}],["特性来改变类",{"2":{"152":1}}],["特性时才应在类声明中使用",{"2":{"163":1}}],["特性时",{"2":{"152":1}}],["特性表示",{"2":{"147":1}}],["特定元标签标记您的页面",{"2":{"66":1}}],["特点",{"2":{"20":1,"81":1,"105":1}}],["您可以使用这个功能来标注某个项目各项任务的完成情况",{"2":{"347":1}}],["您可以通过",{"2":{"64":1}}],["您需要",{"2":{"66":1}}],["您应使用",{"2":{"66":1}}],["要启用它",{"2":{"304":1}}],["要为标题指定自定义锚点而不是使用自动生成的锚点",{"2":{"281":1}}],["要实现该需求",{"2":{"217":1}}],["要处理",{"2":{"199":1}}],["要求在创建好包含验证信息的凭据之后必须调用",{"2":{"372":1}}],["要求",{"0":{"160":1},"2":{"160":1}}],["要在",{"2":{"133":1}}],["要添加到info",{"2":{"74":1}}],["要使用专属分享界面",{"2":{"66":1}}],["要提供最相关的信息",{"2":{"66":1}}],["要想成为uiapplication的代理对象",{"2":{"37":1}}],["大端",{"2":{"350":1}}],["大家好",{"2":{"319":1}}],["大家在使用过程中注意验证",{"2":{"307":1}}],["大多数",{"2":{"142":1}}],["大概流程如下",{"2":{"67":1}}],["大部分内容为引用",{"2":{"66":1}}],["大于号",{"2":{"8":1}}],["链接本仓库里的url",{"0":{"329":1},"2":{"308":1}}],["链接外部url",{"0":{"328":1},"2":{"308":1}}],["链接",{"0":{"282":1,"327":1,"361":1},"1":{"283":1,"284":1,"285":1,"328":1,"329":1,"330":1,"331":1},"2":{"66":1,"308":1}}],["所选行范围的格式可以是",{"2":{"303":1}}],["所有计算属性也会共享同一块内存",{"2":{"220":1}}],["所有被间接返回的",{"2":{"189":1}}],["所有的",{"2":{"187":1,"208":1}}],["所有的值",{"2":{"142":1}}],["所有协议都写在一个用逗号分隔的列表中",{"2":{"165":1}}],["所有",{"2":{"145":1}}],["所有平台",{"2":{"65":1}}],["所以中文标题不能正确识别为锚点",{"2":{"331":1}}],["所以图片链接也可以很简洁",{"2":{"330":1}}],["所以需要用户立即关注的关键内容",{"2":{"294":2}}],["所以只能访问和调用uitableviewdatasource协议定义的属性和方法",{"2":{"204":1}}],["所以有可能在不经意间写出不安全代码",{"2":{"141":1}}],["所以在viewdidload方法中调用执行js的方法",{"2":{"92":1}}],["所以它不适用于较长时间的任务",{"2":{"43":1}}],["所以",{"2":{"36":1}}],["仅支持ios9以上系统",{"2":{"65":1}}],["第五步",{"2":{"391":1}}],["第四步",{"2":{"391":1}}],["第二部分标记实际url",{"2":{"328":1}}],["第二种",{"2":{"149":1}}],["第二步",{"0":{"65":1},"2":{"67":1,"391":1}}],["第一部分使用两个中括号",{"2":{"328":1}}],["第一个数字也会被下划线替换",{"2":{"259":1}}],["第一个参数将直接在圆括号中出现",{"2":{"137":1}}],["第一种",{"2":{"149":1}}],["第一和第二行代码不会被执行",{"2":{"141":1}}],["第一步",{"0":{"64":1},"2":{"67":1,"391":1}}],["第三步",{"0":{"66":1},"2":{"391":1}}],["例如使用http",{"2":{"372":1}}],["例如myapp",{"2":{"260":1}}],["例如点号",{"2":{"259":1}}],["例如某个不完备的结构体类型",{"2":{"223":1}}],["例如vasprintf函数",{"2":{"215":1}}],["例如char",{"2":{"211":1}}],["例如通过循环创建大量临时的自动释放对象时",{"2":{"207":1}}],["例如通过一个拷贝语义的块属性",{"2":{"148":1}}],["例如生成次级线程时",{"2":{"207":1}}],["例如委托方法",{"2":{"195":1}}],["例如int",{"2":{"211":1}}],["例如info",{"2":{"190":1}}],["例如if",{"2":{"208":1}}],["例如id映射为any",{"2":{"161":1}}],["例如nsattributedstring",{"2":{"180":1}}],["例如nsstring",{"2":{"180":1}}],["例如nsstring映射为string",{"2":{"161":1}}],["例如nsbackgroundactivity",{"2":{"180":1}}],["例如nsobject",{"2":{"180":1}}],["例如来自系统框架的",{"2":{"161":1}}],["例如指针映射为可选类型",{"2":{"161":1}}],["例如`perform",{"2":{"155":1}}],["例如将参数变为了",{"2":{"152":1}}],["例如访问属性或者调用各自类中的方法",{"2":{"133":1}}],["例如",{"2":{"64":1,"133":1,"134":1,"135":1,"136":1,"137":1,"140":1,"141":2,"143":1,"144":2,"145":2,"146":1,"147":1,"150":1,"151":1,"152":1,"154":3,"155":1,"156":3,"161":1,"167":2,"169":1,"175":1,"177":2,"180":1,"182":2,"183":1,"184":1,"185":1,"189":2,"190":1,"195":1,"197":1,"198":1,"205":2,"206":1,"208":2,"213":2,"214":1,"215":1,"216":1,"217":2,"218":2,"219":1,"220":1,"221":1,"222":1,"226":1,"227":2,"232":1,"239":1,"244":1,"252":1,"254":2,"255":1,"256":1,"257":1,"283":1,"296":3,"300":1,"303":1}}],["配置",{"0":{"152":1,"383":1},"2":{"129":1,"132":1}}],["配置在开发环境",{"2":{"107":1}}],["配置在生产环境",{"2":{"107":1}}],["配置shell脚本",{"0":{"95":1}}],["配置导出plist文件",{"0":{"94":1}}],["配置环境",{"0":{"81":1},"1":{"82":1,"83":1}}],["配置环境变量",{"2":{"23":1}}],["配置说明",{"2":{"64":1}}],["白名单",{"2":{"64":3,"79":1}}],["\\tfinally",{"2":{"392":1}}],["\\tfragment",{"2":{"86":1}}],["\\t5",{"2":{"392":1}}],["\\tthen",{"2":{"392":1}}],["\\t4",{"2":{"392":1}}],["\\t3",{"2":{"392":1}}],["\\tnow",{"2":{"392":1}}],["\\t2",{"2":{"392":1}}],["\\t1",{"2":{"392":1}}],["\\tuitableviewcellstyledefault",{"2":{"218":1}}],["\\tuser",{"2":{"86":1}}],["\\tconstructor",{"2":{"113":1}}],["\\timport",{"2":{"113":2}}],["\\tpress",{"2":{"392":2}}],["\\tproviders",{"2":{"113":1}}],["\\tprivate",{"2":{"90":2}}],["\\tpublic",{"2":{"90":7}}],["\\tpath",{"2":{"86":1}}],["\\tpassword",{"2":{"86":1}}],["\\tquery",{"2":{"86":1}}],["\\thost",{"2":{"86":1}}],["\\t",{"2":{"64":2,"79":2,"90":21,"94":18,"113":2,"205":3,"232":2}}],["\\t\\tcharsetdecoder",{"2":{"90":1}}],["\\t\\tcharset",{"2":{"90":1}}],["\\t\\tclientset",{"2":{"90":1}}],["\\t\\tclient",{"2":{"90":1}}],["\\t\\tbytebuffer",{"2":{"90":1}}],["\\t\\ttry",{"2":{"90":3}}],["\\t\\tfor",{"2":{"90":2}}],["\\t\\tsystem",{"2":{"90":6}}],["\\t\\tstring",{"2":{"90":2}}],["\\t\\t",{"2":{"16":4,"64":8,"79":1,"88":1,"90":14,"94":4,"176":2,"232":1}}],["\\t\\t\\ttry",{"2":{"90":1}}],["\\t\\t\\tsystem",{"2":{"90":1}}],["\\t\\t\\tstring",{"2":{"90":1}}],["\\t\\t\\tcharbuffer",{"2":{"90":1}}],["\\t\\t\\te",{"2":{"90":3}}],["\\t\\t\\t\\ttry",{"2":{"90":1}}],["\\t\\t\\t\\tsystem",{"2":{"90":1}}],["\\t\\t\\t\\tsynchronized",{"2":{"90":1}}],["\\t\\t\\t\\t",{"2":{"90":4}}],["\\t\\t\\t\\t\\te1",{"2":{"90":1}}],["\\t\\t\\t\\t\\t",{"2":{"90":3}}],["\\t\\t\\t\\t\\tclient",{"2":{"90":2}}],["\\t\\t\\t\\tcontinue",{"2":{"90":1}}],["\\t\\t\\t\\tclientset",{"2":{"90":2}}],["\\t\\t\\t\\tbroadcast",{"2":{"90":2}}],["\\t\\t\\t\\tbreak",{"2":{"90":1}}],["\\t\\t\\tif",{"2":{"90":4}}],["\\t\\t\\tdispatch",{"2":{"16":1}}],["\\t\\t\\t",{"2":{"16":3,"90":11}}],["元组",{"2":{"151":1}}],["元素前",{"2":{"64":1}}],["元数据保存在",{"2":{"44":1}}],["否则可能会按照错误处理",{"2":{"372":1}}],["否则会导致类名不匹配",{"2":{"245":1}}],["否则会crash",{"2":{"90":1}}],["否则将退出作用域",{"2":{"208":1}}],["否则将由",{"2":{"63":1}}],["否则方法产生的错误会被忽略",{"2":{"196":1}}],["否则",{"2":{"143":1,"151":1,"188":1,"195":1,"208":1}}],["否则开始重连",{"2":{"90":1}}],["否则只能使用web显示分享",{"2":{"63":1}}],["否则用户会看到",{"2":{"63":1}}],["并与本地分支合并",{"2":{"389":1}}],["并命名",{"2":{"389":1}}],["并更新工作区",{"2":{"386":1}}],["并切换到该分支",{"2":{"386":1}}],["并包括指定文件的新变化",{"2":{"385":1}}],["并从",{"2":{"300":2}}],["并带有相应的",{"2":{"283":1}}],["并会为错误域生成相应的nsstring字符串常量",{"2":{"252":1}}],["并用产品模块名拼接上",{"2":{"238":1}}],["并无缝并入现有的",{"2":{"235":1}}],["并将",{"2":{"229":1}}],["并将其作为参数传入os",{"2":{"190":1}}],["并非在所有平台的所有版本中都可用",{"2":{"208":1}}],["并没有为每个本地化宏单独定义函数",{"2":{"206":1}}],["并能从这类数据形式转换回对象",{"2":{"205":1}}],["并绑定到",{"2":{"204":1}}],["并使用if",{"2":{"193":1}}],["并使用as运算符来消除重载方法之间的歧义",{"2":{"154":1}}],["并为其赋值字典字面量时",{"2":{"185":1}}],["并为其赋值数组字面量时",{"2":{"184":1}}],["并提供了在各种",{"2":{"181":1}}],["并提供了==运算符和===运算符的默认实现",{"2":{"149":1}}],["并在函数实现中调用相关函数",{"2":{"217":1}}],["并在",{"2":{"175":1}}],["并在发布帖子后将控制权交还您的应用",{"2":{"63":1}}],["并且将这个改名放入暂存区",{"2":{"384":1}}],["并且将这次删除放入暂存区",{"2":{"384":1}}],["并且其内容中",{"2":{"363":1}}],["并且有一个参数对应各个存储属性的构造器",{"2":{"216":1}}],["并且自动传播给调用者",{"2":{"198":1}}],["并且还有一个",{"2":{"195":1}}],["并且它们能跟彼此进行通信",{"2":{"157":1}}],["并且没有参数名",{"2":{"137":1}}],["并利用熟悉的",{"2":{"157":1}}],["并可以为其传递一些命令行参数",{"2":{"209":1}}],["并可以使用as",{"2":{"150":1}}],["并可将之用于",{"2":{"156":1}}],["并记得在选择器参数片段后添加冒号",{"2":{"152":1}}],["并被赋值为nil",{"2":{"141":1}}],["并不是专门为im设计的协议",{"2":{"33":1}}],["版本控制的系统中都少不了diff的功能",{"2":{"362":1}}],["版本",{"2":{"103":1}}],["版的",{"2":{"63":1}}],["版",{"2":{"63":4}}],["版权符",{"2":{"8":1}}],["窗口将显示帖子编辑器",{"2":{"63":1}}],["分支",{"0":{"386":1}}],["分支名",{"2":{"326":1}}],["分别用产品名和产品模块名替换",{"2":{"246":1}}],["分别用func和class",{"2":{"232":1}}],["分类相似",{"2":{"146":1}}],["分步指南",{"0":{"63":1},"1":{"64":1,"65":1,"66":1}}],["分享照片与视频",{"2":{"79":1}}],["分享文字",{"2":{"79":1}}],["分享文档",{"0":{"73":1},"2":{"67":1}}],["分享通过系统自带的",{"2":{"79":1}}],["分享参考",{"2":{"73":1}}],["分享出去后停留在instagram",{"2":{"67":1}}],["分享表",{"2":{"63":1}}],["分享对话框将由",{"2":{"63":1}}],["分享对话框",{"2":{"63":1,"66":1}}],["分享",{"0":{"62":1,"67":1,"69":1,"79":1},"1":{"63":1,"64":1,"65":1,"66":1,"70":1,"71":1,"72":1,"73":1,"74":1},"2":{"63":3,"67":2}}],["分三步去更新",{"0":{"11":1}}],["|",{"2":{"61":1,"112":1,"219":1,"287":20,"304":15,"357":18,"358":20,"369":11,"391":2}}],["||",{"2":{"36":1,"95":3}}],["扩展来提供一个优化后的接口",{"2":{"257":1}}],["扩展来扩充新值的常量声明",{"2":{"213":1}}],["扩展性强的应用程序",{"2":{"192":1}}],["扩展可以为既有类",{"2":{"146":1}}],["扩展和",{"2":{"146":1}}],["扩展",{"0":{"146":1,"279":1},"1":{"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1},"2":{"132":1,"279":1}}],["扩展一个方法",{"2":{"59":1}}],["扩展方便",{"2":{"44":1}}],["参数来标明你在开发过程中设计的可恢复错误",{"2":{"199":1}}],["参数",{"2":{"195":1,"224":1,"225":1,"226":1}}],["参数的块作为参数的方法",{"2":{"195":1}}],["参数的",{"2":{"151":1}}],["参数可以没有",{"2":{"9":1}}],["参考文档",{"2":{"69":1}}],["参考",{"2":{"59":1,"372":1,"395":1,"396":1}}],["免费的ssl证书",{"0":{"57":1}}],["免费的二级域名申请",{"0":{"56":1}}],["境外",{"2":{"56":1}}],["境内",{"2":{"56":1}}],["花生壳",{"2":{"56":1}}],["状态改变时进行相关操作",{"2":{"54":1}}],["高级配置",{"0":{"306":1}}],["高亮",{"0":{"299":1}}],["高飞",{"2":{"66":1,"74":1,"79":1,"392":1}}],["高于该版本",{"2":{"53":1}}],["高效",{"2":{"33":1}}],["存取方法的选择器时",{"2":{"154":1}}],["存取器属性特性",{"2":{"136":1}}],["存在的问题",{"2":{"53":1}}],["存储名称建议使用公司名称+app名称+环境+apns的形式",{"2":{"14":1}}],["存储",{"2":{"14":2}}],["转换到",{"2":{"151":1,"226":1,"232":1}}],["转换为基本数据类型比较",{"2":{"53":1}}],["转义字符",{"0":{"8":1},"2":{"8":1}}],["综合而论",{"2":{"52":1}}],["定义要聚焦的行数",{"2":{"297":1}}],["定义类",{"2":{"163":1,"165":1}}],["定义的宏如下",{"2":{"52":1}}],["定义字符串",{"2":{"25":1}}],["99",{"2":{"391":1}}],["98",{"2":{"155":1,"391":2}}],["9e",{"2":{"155":1}}],["9d",{"2":{"155":1}}],["9c",{"2":{"86":1}}],["9a",{"2":{"86":1}}],["95",{"2":{"66":1}}],["9",{"2":{"50":1,"52":7,"66":1,"74":1,"160":1,"296":1}}],["静态检查",{"0":{"50":1}}],["静态库",{"2":{"26":1}}],["这次质询被拒绝",{"2":{"372":1}}],["这里最关键的就是证书信息",{"2":{"371":1}}],["这里可以找到所有支持的",{"2":{"288":1}}],["这在记录组件库时特别有用",{"2":{"293":1}}],["这会很有帮助",{"2":{"292":1}}],["这允许将标题链接为",{"2":{"281":1}}],["这对下标方法就会变为",{"2":{"257":1}}],["这有个简短的实践列表",{"2":{"229":1}}],["这有个不带内存管理标注的",{"2":{"189":1}}],["这等同于访问processinfo",{"2":{"209":1}}],["这套宏包括nslocalizedstring",{"2":{"206":1}}],["这与司空见惯的",{"2":{"199":1}}],["这意味着它们不会出现在",{"2":{"245":1}}],["这意味着你可能需要整理现有项目",{"2":{"229":1}}],["这意味着除非提供了一个错误指针",{"2":{"196":1}}],["这意味着不但可以基于",{"2":{"162":1}}],["这将不会产生错误",{"2":{"303":1}}],["这将会很有帮助",{"2":{"301":1}}],["这将借助类型推断来为结构体的每个匿名字段设置初始值",{"2":{"222":1}}],["这将导致修改任意计算属性的值都会改变其他计算属性的值",{"2":{"220":1}}],["这将使计算初始值的表达式只在属性被初次访问时才进行求值",{"2":{"194":1}}],["这将返回目标类型的可选值",{"2":{"139":1}}],["这两个方法均会返回解包后的原始对象",{"2":{"189":1}}],["这同样遵循上面提到的桥接规则",{"2":{"183":1,"184":1,"185":1}}],["这包括了所有",{"2":{"161":1}}],["这使得调用者可以在扩充新值时省略参数标签",{"2":{"213":1}}],["这使运用最新的",{"2":{"157":1}}],["这使你能以更加类型安全的方式去操作各种值",{"2":{"142":1}}],["这使你能够在一种语言编写的文件中使用另一种语言",{"2":{"132":1}}],["这使你在访问返回值为id类型的",{"2":{"140":1}}],["这篇指南包括了三个有关兼容性的重要方面",{"2":{"157":1}}],["这是三级的有序列表",{"2":{"343":1,"344":1}}],["这是二级的有序列表",{"2":{"343":1,"344":1}}],["这是一级的有序列表",{"2":{"343":1,"344":1}}],["这是一个",{"2":{"325":2}}],["这是一个特殊的容器",{"2":{"293":1}}],["这是一段普通的文本",{"2":{"318":1}}],["这是一种能让某个对象在另一个对象的特定属性改变时获得通知的机制",{"2":{"156":1}}],["这是一种通过字符串来访问某个对象的属性的机制",{"2":{"156":1}}],["这是为了兼容",{"2":{"218":1}}],["这是因为通过执行选择器返回的值的类型和所有权无法在编译期决定",{"2":{"155":1}}],["这类数据形式可以写入文件",{"2":{"205":1}}],["这类需要在运行时动态替换方法实现的函数时",{"2":{"153":1}}],["这类",{"2":{"153":1}}],["这样才会将验证的信息发送给服务端",{"2":{"372":1}}],["这样看起来比较干净",{"2":{"328":1}}],["这样下一行的文本就换行了",{"2":{"324":1}}],["这样",{"2":{"213":1}}],["这样就确保了只有唯一的实例会被创建",{"2":{"203":1}}],["这样的",{"2":{"156":1}}],["这样归档文件才能通过新的",{"2":{"152":1}}],["这样写",{"2":{"133":1,"137":1}}],["这种自然的工作流程使得创建基于混合语言的应用程序或框架变得和单独使用一种语言一样简单",{"2":{"236":1}}],["这种方式简化了处理不同平台功能时的逻辑",{"2":{"208":1}}],["这种类型的属性必须符合nscopying协议",{"2":{"174":1}}],["这种形式",{"2":{"165":2}}],["这种兼容性能让",{"2":{"157":1}}],["这种对象具有能够动态查找",{"2":{"140":1}}],["这种模式被内置到语言特性中",{"2":{"135":1}}],["这些信息被保存在客户端称作",{"2":{"371":1}}],["这些特殊字符会被下划线",{"2":{"259":1}}],["这些宏用于组织字符串常量",{"2":{"213":1}}],["这些类型和",{"2":{"211":1}}],["这些模式很多都依赖于在",{"2":{"192":1}}],["这些方法使用string",{"2":{"181":1}}],["这些值类型的功能与其对应的引用类型相同",{"2":{"179":1}}],["这些头文件公开了那些可以映射回",{"2":{"161":1}}],["这些属性必须是计算型属性",{"2":{"146":1}}],["这些",{"2":{"135":1}}],["这个请求中包含浏览器ssl协议的版本号",{"2":{"371":1}}],["这个头文件会由",{"2":{"240":1}}],["这个头文件包含所有标记public或open修饰符的",{"2":{"240":1}}],["这个自动生成的头文件是一个",{"2":{"240":1}}],["这个cfarraycallbacks结构体使用一些函数指针进行初始化",{"2":{"227":1}}],["这个过程将影响它们的参数和返回值的类型",{"2":{"161":1}}],["这个特性在迁徙被归档的",{"2":{"152":1}}],["这个方法在初始化render时不会被调用",{"2":{"124":1}}],["这个模板是从这里ironsummitmedia",{"2":{"1":1}}],["这时候应该使用另外一个条件编译来避免出现问题",{"2":{"46":1}}],["zebra",{"2":{"287":2,"358":2}}],["zero",{"2":{"133":2,"304":2}}],["zulu",{"2":{"155":1}}],["zorro",{"2":{"113":1}}],["zhihu",{"2":{"330":3}}],["zhangsan",{"2":{"92":1}}],["zh",{"2":{"56":1}}],["zip",{"2":{"44":2}}],["zshrc",{"2":{"23":3}}],["则用来改写上一次commit的提交信息",{"2":{"385":1}}],["则只将",{"2":{"371":1}}],["则需编写",{"2":{"199":1}}],["则需要按以下的步骤进行",{"2":{"27":1}}],["则错误会填充错误指针参数",{"2":{"198":1}}],["则错误会传播到它的调用域",{"2":{"198":1}}],["则错误会被抛出",{"2":{"198":1}}],["则该错误会自动填充到桥接的",{"2":{"198":1}}],["则该方法保持不变",{"2":{"195":1}}],["则使用错误对象来填充该方法的错误指针参数",{"2":{"198":1}}],["则不会对方法名进行简化",{"2":{"195":1}}],["则可以假定这些",{"2":{"169":1}}],["则必须提供该构造器的完整实现",{"2":{"164":1}}],["则必须使用动态分派",{"2":{"153":1}}],["则应该这样写",{"2":{"133":1,"137":1}}],["则会产生错误",{"2":{"197":1}}],["则会作为init",{"2":{"135":1}}],["则会以initwith开头",{"2":{"133":1}}],["则会收到回调",{"2":{"90":1}}],["则先使用pod",{"2":{"84":1}}],["则把所有",{"2":{"44":1}}],["源码编译",{"2":{"44":1}}],["直接到仓库区",{"2":{"385":1}}],["直接进行第6步",{"2":{"371":1}}],["直接混合两种语法当然可以",{"2":{"330":1}}],["直接回车不能换行",{"2":{"324":1}}],["直接使用相对路径就可了",{"2":{"326":1}}],["直接使用协议名作为其类型",{"2":{"165":1}}],["直接使用属性名即可",{"2":{"136":1}}],["直接采用nscoding协议的类必须实现这个方法",{"2":{"164":1}}],["直接编译工程",{"2":{"84":1}}],["直接找到",{"2":{"84":1}}],["直接上传同时包含照片和视频的内容",{"2":{"66":1}}],["直接上传由用户拍摄的视频",{"2":{"66":1}}],["直接上传一张或多张由用户拍摄的照片",{"2":{"66":1}}],["直接从官网下载最新的",{"2":{"44":1}}],["直接写为文件速度会更快一些",{"2":{"44":1}}],["单行文本",{"0":{"319":1},"2":{"308":1}}],["单击一个符号来查看它的详细信息",{"2":{"234":1}}],["单击一个",{"2":{"234":1}}],["单例模式提供了一个可全局访问的共享对象",{"2":{"203":1}}],["单例",{"0":{"203":1},"2":{"192":1}}],["单个属性声明可以使用nullable",{"2":{"142":1}}],["单个类型声明可以使用",{"2":{"142":1}}],["单页面",{"2":{"130":1}}],["单条数据大于",{"2":{"44":1}}],["单引号",{"2":{"8":1,"25":1}}],["yaml",{"2":{"286":2}}],["yarn",{"2":{"82":1,"103":1,"117":1}}],["yarn是",{"2":{"82":1}}],["yellow",{"2":{"205":2,"213":2}}],["yes",{"2":{"61":1,"65":1,"67":7,"73":1,"79":4,"90":1,"197":1,"222":1}}],["yuanyuan",{"2":{"156":6}}],["y",{"2":{"77":2,"133":1,"146":5,"154":1,"214":2,"217":3,"224":2,"225":2}}],["yydiskcache",{"2":{"44":1}}],["yourself",{"2":{"73":1}}],["your",{"2":{"64":6,"103":4,"190":3,"392":1,"395":2,"397":5}}],["you",{"2":{"2":3,"86":3,"95":2,"392":4,"397":8}}],["热数据的文件不要超过物理内存大小",{"2":{"44":1}}],["难以实现较好的淘汰算法",{"2":{"44":1}}],["他们的实现都比较简单",{"2":{"44":1}}],["等价代码",{"2":{"303":2}}],["等待这些任务都执行完成之后",{"2":{"61":1}}],["等缓存",{"2":{"44":1}}],["等等",{"2":{"37":1}}],["磁盘缓存最好是把",{"2":{"44":1}}],["磁盘缓存",{"0":{"44":1}}],["性能测试",{"2":{"88":1}}],["性能要高很多",{"2":{"44":1}}],["性能非常高",{"2":{"44":1}}],["性能也都相近",{"2":{"44":1}}],["性能就会下降许多",{"2":{"43":1}}],["性能最高的锁",{"2":{"43":1}}],["但依然停留在当前分支",{"2":{"386":1}}],["但该文件会保留在工作区",{"2":{"384":1}}],["但仍有一些通用的办法能解决代码迁移时遇到的问题",{"2":{"234":1}}],["但",{"2":{"220":1}}],["但有如下例外情况",{"2":{"180":1}}],["但有个关键的不同",{"2":{"147":1}}],["但这不包括一些",{"2":{"151":1}}],["但建议使用强制解包的方式来防止一些意想不到的行为",{"2":{"141":1}}],["但是有一些html语法在写readme的时候是很少的补充",{"2":{"365":1}}],["但是有的情况下则必须创建",{"2":{"207":1}}],["但是现在已经没问题啦",{"2":{"331":1}}],["但是十分啰嗦",{"2":{"330":1}}],["但是可以跳转进去查看",{"2":{"240":1}}],["但是该信息并不是排查错误所必需的",{"2":{"190":1}}],["但是这种做法并不推荐",{"2":{"189":1}}],["但是未来会有的一些类",{"2":{"180":1}}],["但是",{"2":{"153":1}}],["但是会在运行时触发一个错误",{"2":{"141":1}}],["但是必须保证scoketopen",{"2":{"90":1}}],["但是理论上是可以的",{"2":{"67":1}}],["但是不能直接发给别人使用",{"2":{"14":1}}],["但ios9以后不推荐使用",{"2":{"65":1}}],["但一旦有等待情况出现时",{"2":{"43":1}}],["但当信号总量设为",{"2":{"43":1}}],["它将",{"2":{"253":1}}],["它还能达到复用的目的",{"2":{"328":1}}],["它还支持选择行范围",{"2":{"303":1}}],["它还支持可选值链式引用",{"2":{"156":1}}],["它还会包含标记internal修饰符的",{"2":{"240":1}}],["它被导入到",{"2":{"220":1}}],["它被导入为如下形式",{"2":{"218":2,"219":1}}],["它拥有isalive和isdead两个字段",{"2":{"220":1}}],["它能保证延迟初始化只执行一次",{"2":{"203":1}}],["它是",{"2":{"190":1}}],["它有个叫做name的string类型的属性",{"2":{"175":1}}],["它们和自定义容器的渲染方式相同",{"2":{"294":1}}],["它们只会暴露给",{"2":{"245":1}}],["它们的前缀名均会被移除",{"2":{"218":1}}],["它们表示交通信号灯的颜色组合",{"2":{"213":1}}],["它们没有返回值",{"2":{"155":1}}],["它们会被导入为",{"2":{"136":1}}],["它在底层使用",{"2":{"293":1}}],["它在",{"2":{"147":1}}],["它会被这样导入",{"2":{"195":1}}],["它会带有一个类型约束来要求该类必须符合指定协议",{"2":{"145":1}}],["它会带有一个类型约束来要求该类必须是指定类的子类",{"2":{"145":1}}],["它会作为any类型导入到",{"2":{"143":1}}],["它比较合适",{"2":{"43":1}}],["它的值对应于源代码根目录",{"2":{"303":1}}],["它的优势在于等待时不会消耗",{"2":{"43":1}}],["它的性能比",{"2":{"43":1}}],["它的缺点是当等待时会消耗大量",{"2":{"43":1}}],["它非常合适",{"2":{"43":1}}],["资源",{"2":{"43":2}}],["忙等",{"2":{"43":1}}],["原始的方法是打破鸡蛋较大的一端",{"2":{"350":1}}],["原始值类型不是int类型的枚举",{"2":{"151":1}}],["原生错误处理机制抛出错误的方法",{"2":{"195":1}}],["原先的引用类型依然可以通过加上ns前缀来访问",{"2":{"179":1}}],["原子属性特性",{"2":{"136":1}}],["原文档说明如下",{"2":{"67":1}}],["原理很简单",{"2":{"43":1}}],["原图",{"2":{"36":1}}],["琐碎的记录",{"0":{"41":1,"55":1},"1":{"42":1,"43":1,"44":1,"56":1,"57":1}}],["know",{"2":{"397":1}}],["kib",{"2":{"391":2}}],["kits",{"2":{"69":2}}],["k",{"2":{"217":3}}],["kvc",{"2":{"156":2}}],["kvo",{"2":{"153":1,"156":2}}],["kadress",{"2":{"90":2}}],["kport",{"2":{"90":2}}],["khost",{"2":{"90":2}}],["kctcellulardatanotrestricted",{"2":{"54":1}}],["kctcellulardatarestrictedstateunknown",{"2":{"54":1}}],["kctcellulardatarestricted",{"2":{"54":1}}],["kcfcorefoundationversionnumber",{"2":{"52":14}}],["keychainmanager",{"2":{"391":1}}],["keygen",{"2":{"380":2}}],["key的配置中",{"2":{"380":1}}],["key=",{"2":{"295":2}}],["keys",{"2":{"256":1}}],["keyedobjects",{"2":{"185":2}}],["keypath",{"2":{"156":13}}],["keydown",{"2":{"110":1}}],["key>teamid",{"2":{"94":1}}],["key>stripswiftsymbols",{"2":{"94":1}}],["key>signingstyle",{"2":{"94":1}}],["key>signingcertificate",{"2":{"94":1}}],["key>provisioningprofiles",{"2":{"94":1}}],["key>method",{"2":{"94":1}}],["key>destination",{"2":{"94":1}}],["key>com",{"2":{"94":1}}],["key>compilebitcode",{"2":{"94":1}}],["key>cfbundleurlschemes",{"2":{"64":1}}],["key>cfbundleurltypes",{"2":{"64":1}}],["key>nsphotolibraryusagedescription",{"2":{"64":1}}],["key>lsapplicationqueriesschemes",{"2":{"64":1,"79":1}}],["key>facebookdisplayname",{"2":{"64":1}}],["key>facebookappid",{"2":{"64":1}}],["key>",{"2":{"64":6,"79":1,"94":9}}],["keywindow",{"2":{"59":1,"396":2}}],["key",{"0":{"127":1,"379":1},"1":{"380":1},"2":{"44":1,"71":1,"92":4,"156":5,"185":1,"380":2}}],["keepalive机制",{"2":{"34":1}}],["kubadownload",{"2":{"39":1}}],["越狱操作",{"2":{"39":1}}],["越狱为",{"2":{"39":1}}],["来源于网络的图片",{"2":{"308":1}}],["来只包含代码文件的相应部分",{"2":{"301":1}}],["来自定义起始行号",{"2":{"300":1}}],["来自vmware",{"2":{"113":1}}],["来命名",{"2":{"240":1,"260":1}}],["来让",{"2":{"232":1}}],["来进一步简化方法名",{"2":{"195":1}}],["来进行访问",{"2":{"124":1}}],["来使用统一日志系统",{"2":{"190":1}}],["来捕获系统各个层级传递的消息",{"2":{"190":1}}],["来替代常规的js语法",{"2":{"118":1}}],["来说",{"2":{"43":1}}],["来越狱",{"2":{"39":1}}],["来决定的",{"2":{"31":1}}],["程序启动后",{"2":{"37":1}}],["程序启动过程",{"0":{"37":1}}],["或许会出现以下问题",{"0":{"392":1}}],["或两者均指定",{"2":{"296":1}}],["或属性列表数据解码并初始化实例",{"2":{"205":1}}],["或属性列表数据",{"2":{"205":1}}],["或属性列表",{"2":{"205":1}}],["或更高版本",{"2":{"160":1}}],["或",{"2":{"159":2,"195":1,"205":1,"213":1,"215":1,"298":1,"299":1}}],["或setter",{"2":{"154":1}}],["或者就是在两行文本直接加一个空行",{"2":{"324":1}}],["或者也可以从相对路径导入",{"2":{"301":1}}],["或者可以添加",{"2":{"283":1}}],["或者可以选择file",{"2":{"159":1}}],["或者选项集的值",{"2":{"253":1}}],["或者反过来",{"2":{"237":1,"238":1,"242":1}}],["或者其他方式",{"2":{"232":1}}],["或者nil",{"2":{"227":1}}],["或者subtract",{"2":{"219":1}}],["或者formunion",{"2":{"219":1}}],["或者属性列表来实例化对象",{"2":{"205":1}}],["或者属性的初始值无法在实例的构造过程完成前确定时",{"2":{"194":1}}],["或者如果适当的",{"2":{"197":1}}],["或者接受一个带有",{"2":{"195":1}}],["或者cfautorelease函数",{"2":{"188":1}}],["或者用nsuserdefaults或nskeyedarchiver归档到硬盘的对象",{"2":{"164":1}}],["或者",{"2":{"161":2,"206":1,"208":1,"209":1,"238":1,"380":1}}],["或者延迟执行",{"2":{"155":1}}],["或者将一个元素为可选类型的数组",{"2":{"143":1}}],["或者叫响应式扩展编程",{"2":{"113":1}}],["或者一个电话打过来了",{"2":{"37":1}}],["或bytebuffer",{"2":{"90":1}}],["或文件存储",{"2":{"44":1}}],["或其他淘汰算法",{"2":{"44":1}}],["或压缩json格式",{"2":{"33":1}}],["按钮即表示用户确认分享",{"2":{"63":1}}],["按钮将打开一个新窗口",{"2":{"63":1}}],["按钮",{"2":{"63":1}}],["按home键使程序进入后台",{"2":{"37":1}}],["按了home键",{"2":{"37":1}}],["按照同样的方式",{"2":{"14":1}}],["消失后",{"2":{"37":1}}],["代表进行https请求时",{"2":{"372":1}}],["代表框架",{"2":{"33":1}}],["代理类型proxytype",{"2":{"372":1}}],["代理通常表现为一个定义交互方法的协议和符合协议的代理属性",{"2":{"193":1}}],["代理",{"0":{"193":1},"2":{"192":1}}],["代理中的若干方法介绍",{"2":{"37":1}}],["代码提交",{"0":{"385":1}}],["代码高亮",{"0":{"354":1},"1":{"355":1,"356":1},"2":{"308":1}}],["代码组",{"0":{"302":1}}],["代码块中的颜色差异",{"0":{"298":1}}],["代码块中的语法高亮",{"0":{"295":1}}],["代码块中聚焦",{"0":{"297":1}}],["代码块中使用彩色文本实现语法高亮",{"2":{"295":1}}],["代码自动生成的头文件导入",{"2":{"260":1}}],["代码自动生成的头文件导入到要使用",{"2":{"245":1}}],["代码自动生成的头文件",{"2":{"259":1,"260":1}}],["代码作为常规",{"2":{"253":1}}],["代码部分",{"2":{"245":2}}],["代码的头文件中",{"2":{"245":1}}],["代码的",{"2":{"245":1}}],["代码的保护伞头文件",{"2":{"240":1}}],["代码的声明",{"2":{"152":1}}],["代码使用时",{"2":{"238":1}}],["代码使用var和let来控制可变性",{"2":{"179":1}}],["代码需要遵循现代编码实践",{"2":{"229":1}}],["代码间有着最佳兼容性",{"2":{"229":1}}],["代码来改善程序的架构",{"2":{"228":1}}],["代码替换",{"2":{"228":1}}],["代码做好迁移准备",{"0":{"229":1},"2":{"228":1}}],["代码到",{"0":{"228":1},"1":{"229":1,"230":1,"231":1,"232":1,"233":1,"234":1},"2":{"265":1}}],["代码可以使用",{"2":{"208":1}}],["代码之前捕获异常",{"2":{"199":1}}],["代码调用会抛出错误的",{"2":{"198":1}}],["代码导入到",{"0":{"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1},"1":{"239":1,"241":1,"244":1,"246":1},"2":{"235":4,"240":1,"246":1,"248":1,"249":1,"260":1}}],["代码导入",{"2":{"179":2,"234":1,"253":1}}],["代码声明了一个拥有",{"2":{"169":1}}],["代码中也许会存在无法自动处理的特殊情况",{"2":{"253":1}}],["代码中的",{"2":{"245":1}}],["代码中的函数",{"2":{"161":1}}],["代码中访问",{"2":{"242":1}}],["代码中",{"2":{"235":1,"243":1,"245":1}}],["代码中通过commond",{"2":{"234":1}}],["代码中对应的导入语句更改为",{"2":{"233":1}}],["代码中进行扩充以添加新值",{"2":{"213":1}}],["代码中使用标记internal修饰符的",{"2":{"260":1}}],["代码中使用了自定义的",{"2":{"260":1}}],["代码中使用",{"2":{"179":1,"237":1,"240":1}}],["代码中使用时",{"2":{"167":1}}],["代码中以更加自然的方式使用这些原有的功能",{"2":{"179":1}}],["代码时",{"2":{"162":1,"234":1,"260":1}}],["代码时可以融合",{"2":{"162":1}}],["代码时使用",{"2":{"132":1}}],["代码无法直接导入",{"2":{"161":1}}],["代码",{"2":{"159":1,"162":1,"199":1,"213":1,"231":1,"237":1,"239":1,"241":3,"242":1,"244":1,"246":2}}],["代码迁移到",{"2":{"157":1}}],["代码片段插入文件正文",{"2":{"64":1}}],["都可以放在其中",{"2":{"369":1}}],["都可以找到app的下载地址",{"2":{"9":1}}],["都可省略",{"2":{"326":1}}],["都提供了可用性信息",{"2":{"208":1}}],["都会要求确认",{"2":{"384":1}}],["都会自动转换为",{"2":{"283":1}}],["都会自动管理",{"2":{"186":1}}],["都会根据产品模块名来命名",{"2":{"259":1}}],["都会带有类型约束来要求该类型必须是一个类类型",{"2":{"145":1}}],["都改善了它们的",{"2":{"177":1}}],["都将作为一个module直接导入到",{"2":{"161":1}}],["都已经提供了为空性标注",{"2":{"142":1}}],["都能确保是非空值",{"2":{"142":1}}],["都是基于",{"2":{"44":1}}],["都是基于文件系统的",{"2":{"44":1}}],["都是应用程序自身的一些事件",{"2":{"37":1}}],["监听",{"2":{"37":1}}],["总结",{"2":{"37":1}}],["内部是链接要显示的文本",{"2":{"330":1}}],["内部链接将转换为单页导航的路由链接",{"2":{"283":1}}],["内部链接",{"0":{"283":1}}],["内部和外部链接都会被特殊处理",{"2":{"282":1}}],["内省",{"0":{"204":1},"2":{"192":1}}],["内存管理命名规定的",{"2":{"188":1}}],["内存受管理的对象",{"0":{"188":1},"2":{"177":1}}],["内存警告",{"2":{"37":2}}],["内置属性型指令用法",{"0":{"112":1}}],["内置结构型指令用法",{"0":{"111":1}}],["内容",{"2":{"98":3}}],["内相同的环境",{"2":{"23":1}}],["系统设计",{"2":{"346":1,"347":1}}],["系统框架有个大致了解",{"2":{"157":1}}],["系统框架",{"2":{"142":1,"161":1}}],["系统集成",{"2":{"88":1}}],["系统版本低于ios9",{"2":{"52":1}}],["系统版本在ios9",{"2":{"50":1}}],["系统最高版本",{"2":{"50":1}}],["系统最低版本",{"2":{"50":1}}],["系统自带的",{"2":{"44":1}}],["系统事件",{"2":{"37":1}}],["系统中",{"2":{"36":1}}],["++",{"2":{"298":2}}],["+client",{"2":{"90":1}}],["+pon",{"2":{"90":1}}],["+pong",{"2":{"90":1}}],["+msg",{"2":{"90":2}}],["+session",{"2":{"90":4}}],["+",{"2":{"36":1,"43":1,"59":3,"90":6,"97":2,"118":1,"143":1,"146":3,"232":1,"234":2,"304":6,"363":1}}],["会进入到代理方法",{"2":{"372":1}}],["会根据产品模块名",{"2":{"260":1}}],["会根据这个名称来命名桥接头文件和自动生成的头文件",{"2":{"259":1}}],["会根据可选值是否有值来决定是否将其桥接为",{"2":{"143":1}}],["会随着源文件的创建生成",{"2":{"238":1}}],["会以",{"2":{"227":1}}],["会以如下形式导入它们",{"2":{"150":1,"213":2,"214":1}}],["会是autoreleasingunsafemutablepointer",{"2":{"226":1}}],["会处理好这些值和其兼容的",{"2":{"221":1}}],["会使用空选项集表示这种选项",{"2":{"219":1}}],["会忽略值为0的枚举成员",{"2":{"219":1}}],["会返回指定搜索路径和域中的",{"2":{"197":1}}],["会把返回值转换为非可选类型",{"2":{"195":1}}],["会把返回值转换为",{"2":{"195":1}}],["会尝试删除选择器的第一部分中的",{"2":{"195":1}}],["会产生错误的方法将",{"2":{"195":1}}],["会在你需要引用头文件的时候自动生成头文件",{"2":{"230":1}}],["会在array类型和nsarray类之间桥接",{"2":{"183":1}}],["会在",{"2":{"182":1}}],["会在运行时提供其实现和存储",{"2":{"175":1}}],["会连接各个",{"2":{"169":1}}],["会自动创建",{"2":{"238":1}}],["会自动将",{"2":{"195":1}}],["会自动将一些",{"2":{"177":1}}],["会自动对其进行内存管理",{"2":{"188":1}}],["会自动调用父类的析构器",{"2":{"166":1}}],["会自动调用析构器",{"2":{"166":1}}],["会自动为",{"2":{"149":1}}],["会非常简单",{"2":{"157":1}}],["会将枚举值的名称前缀截断",{"2":{"255":1}}],["会将之导入为opaquepointer",{"2":{"223":1}}],["会将之替换为",{"2":{"195":1}}],["会将结构体中的位字段导入为结构体的计算型属性",{"2":{"221":1}}],["会将使用ns",{"2":{"219":1}}],["会将未使用ns",{"2":{"218":1}}],["会将用ns",{"2":{"218":1}}],["会将用户切换到默认浏览器并打开动态发布对话框",{"2":{"63":1}}],["会将这些类型的名字重映射",{"2":{"187":1}}],["会将它们移到相关类型的内部作为嵌套类型",{"2":{"180":1}}],["会将",{"2":{"166":1}}],["会将其导入为结构体的成员函数",{"2":{"217":1}}],["会将其导入为元素类型为anyhashable的set",{"2":{"150":1}}],["会将其导入为键类型为anyhashable的dictionary",{"2":{"150":1}}],["会将根据泛型类的类型约束来推断泛型参数化",{"2":{"145":1}}],["会将可选值桥接为它所包装的值",{"2":{"143":1}}],["会将nil值桥接为nsnull实例",{"2":{"143":1}}],["会作为隐式解包可选类型导入到",{"2":{"142":1}}],["会作为可选类型导入到",{"2":{"142":1}}],["会作为非可选类型导入到",{"2":{"142":1}}],["会被桥接为",{"2":{"182":1}}],["会被拼接在方法名上",{"2":{"151":1}}],["会被拼接到",{"2":{"151":1}}],["会被",{"2":{"136":1}}],["会为你处理",{"2":{"133":1}}],["会引起视图的重绘",{"2":{"125":1}}],["会切换到原生",{"2":{"63":1}}],["会打开网页分享对话框",{"2":{"63":1}}],["会比",{"2":{"44":1}}],["会导致内存交换严重降低性能",{"2":{"44":1}}],["会出现逆时针90",{"2":{"36":1}}],["会提示找不到location目录",{"2":{"16":1}}],["旋转图片",{"2":{"36":1}}],["通话密码",{"2":{"371":1}}],["通讯将断开",{"2":{"371":1}}],["通常会提供一些函数用于创建",{"2":{"217":1}}],["通常通过点击",{"2":{"209":1}}],["通常",{"2":{"207":1}}],["通常用nslocalizedstring系列宏来本地化字符串",{"2":{"206":1}}],["通常这种对象会是",{"2":{"205":1}}],["通常可设置3",{"2":{"34":1}}],["通过在配置文件中将",{"2":{"305":1}}],["通过该接口去调用方法的原始实现",{"2":{"257":1}}],["通过之前学习的工具",{"2":{"228":1}}],["通过用",{"2":{"228":1}}],["通过序列化",{"2":{"205":1}}],["通过这些工具",{"2":{"228":1}}],["通过这种方式",{"2":{"169":1,"189":1}}],["通过这个导入语句",{"2":{"161":1}}],["通过导入相应的模块",{"2":{"146":1}}],["通过props",{"2":{"121":1}}],["通过npm搭建开发环境",{"0":{"102":1,"116":1}}],["通过uidocumentinteractioncontroller",{"2":{"67":1}}],["通过",{"2":{"67":1,"147":1}}],["通过授权",{"2":{"67":1}}],["通过custom",{"2":{"67":1}}],["通过文件读写来缓存数据",{"2":{"44":1}}],["通过微信的测试结果",{"2":{"9":1}}],["发行者的数字签名",{"2":{"371":1}}],["发行者证书的公钥能否正确解开服务器证书的",{"2":{"371":1}}],["发行服务器的证书的ca是否可靠",{"2":{"371":1}}],["发起请求",{"2":{"371":1}}],["发生一个错误",{"2":{"198":2}}],["发布订阅",{"2":{"113":1}}],["发布证书",{"0":{"10":1},"1":{"11":1,"12":1,"13":1,"14":1}}],["发送post请求",{"0":{"92":1}}],["发送消息错误",{"2":{"90":1}}],["发送二进制数据",{"2":{"90":1}}],["发送文本数据",{"2":{"90":1}}],["发送相应的keepalive探针",{"2":{"34":1}}],["检查选项值",{"2":{"219":1}}],["检查协议符合性的示例",{"2":{"204":1}}],["检查协议符合性以及转换到符合协议类型的语法和上述类型检查和转换的语法是完全一样的",{"2":{"204":1}}],["检查mydelegate是否实现了window",{"2":{"193":1}}],["检查mydelegate不为nil",{"2":{"193":1}}],["检查运行的ios系统版本",{"0":{"53":1}}],["检查基本的配置",{"2":{"26":1}}],["检测是否有某个属性",{"2":{"78":1}}],["检测某个api是否可用",{"0":{"78":1}}],["检测通信双方的存活状态",{"2":{"34":1}}],["检测连接的状态",{"2":{"34":1}}],["心跳机制",{"2":{"34":1}}],["重做上一次commit",{"2":{"385":1}}],["重写整个应用程序",{"2":{"228":1}}],["重名了一些类",{"2":{"180":1}}],["重映射类型",{"0":{"187":1},"2":{"177":1}}],["重映射",{"2":{"161":3}}],["重要注解",{"0":{"72":1}}],["重连机制",{"0":{"34":1},"2":{"90":1}}],["重启电脑",{"2":{"27":2}}],["流量耗费大",{"2":{"33":1}}],["流量少",{"2":{"33":1}}],["额外信息多",{"2":{"33":1}}],["可是当今的皇帝的祖父小时候吃鸡蛋",{"2":{"350":1}}],["可为所有图片启用懒加载",{"2":{"305":1}}],["可能还想查看",{"2":{"293":1}}],["可能需要在",{"2":{"237":1}}],["可直接导入到",{"2":{"240":1}}],["可变函数调用约定和指针类型一样",{"2":{"215":1}}],["可变指针",{"0":{"225":1},"2":{"210":1}}],["可变参数",{"2":{"151":1}}],["可结合if",{"2":{"204":1}}],["可用性检查可以作为控制流语句的一个条件",{"2":{"208":1}}],["可用性在运行时作为判断条件",{"2":{"208":1}}],["可用性",{"0":{"208":1},"2":{"192":1}}],["可选的协议要求必须标记",{"2":{"250":1}}],["可选指针不能传递给withvalist",{"2":{"215":1}}],["可选协议要求必须标记",{"2":{"176":1}}],["可选类型会被标注",{"2":{"151":1}}],["可选类型",{"2":{"142":1}}],["可执行文件则自带静态链接的运行时库",{"2":{"160":1}}],["可执行文件必须能在它的",{"2":{"160":1}}],["可无缝兼容",{"2":{"157":1}}],["可在",{"2":{"153":1}}],["可失败初始化",{"0":{"135":1},"2":{"132":1}}],["可扩展性强",{"2":{"33":1}}],["可以实现分次提交",{"2":{"384":1}}],["可以实现一个析构器来代替dealloc方法",{"2":{"166":1}}],["可以显示横线效果",{"2":{"309":1}}],["可以为通过",{"2":{"305":1}}],["可以这样用相对路径包含",{"2":{"303":1}}],["可以找到合法的编程语言列表",{"2":{"295":1}}],["可以添加",{"2":{"283":1}}],["可以省略扩展名",{"2":{"283":1}}],["可以建议",{"2":{"256":1}}],["可以选择file",{"2":{"238":1}}],["可以option",{"2":{"234":1}}],["可以填写一个",{"2":{"231":1}}],["可以一步步探索",{"2":{"228":1}}],["可以传递一个顶级的",{"2":{"227":1}}],["可以像这样在一个",{"2":{"303":1}}],["可以像这样对多个代码块进行分组",{"2":{"302":1}}],["可以像下面这样将enabled属性的取值方法在",{"2":{"232":1}}],["可以像如下这样创建和使用它",{"2":{"222":1}}],["可以像调用协议中的可选方法那样",{"2":{"141":1}}],["可以调用",{"2":{"215":1}}],["可以看到",{"2":{"213":1}}],["可以看出某些系统版本的值是一样的",{"2":{"52":1}}],["可以访问类型属性commandline",{"2":{"209":1}}],["可以简单地使用静态类型属性来实现单例",{"2":{"203":1}}],["可以自己创建在应用程序内共享的单例对象",{"2":{"203":1}}],["可以根据",{"2":{"189":1}}],["可以根据需要在子类中重写isequal",{"2":{"149":1}}],["可以包含多种不同类型",{"2":{"182":1}}],["可以连接源代码和",{"2":{"169":1}}],["可以定义一个继承自",{"2":{"163":1}}],["可以创建结合了",{"2":{"157":1}}],["可以将这个",{"2":{"240":1}}],["可以将每一对可以桥接的",{"2":{"186":1}}],["可以将一个string类型的值传递给一个接收nsstring对象的",{"2":{"177":1}}],["可以将",{"2":{"157":1}}],["可以将可能会值缺失的值包装为该类型的可选类型",{"2":{"142":1}}],["可以用来防止与",{"2":{"293":1}}],["可以用insert",{"2":{"219":1}}],["可以用dispatch",{"2":{"203":1}}],["可以用",{"2":{"156":2,"208":1,"363":1}}],["可以利用它来解决桥接方法循环",{"2":{"152":1}}],["可以让一个",{"2":{"152":1}}],["可以扩展uibezierpath类",{"2":{"146":1}}],["可以在上一行文本后面补两个空格",{"2":{"324":1}}],["可以在文件目录后面的",{"2":{"301":1}}],["可以在代码块中添加",{"2":{"300":1}}],["可以在guard语句中检查可用性",{"2":{"208":1}}],["可以在if语句中检查可用性",{"2":{"208":1}}],["可以在应用程序中编码和解码对象",{"2":{"205":1}}],["可以在特定事件发生时",{"2":{"202":1}}],["可以在类声明前标记",{"2":{"170":1}}],["可以在",{"2":{"161":1,"170":1,"177":1,"234":1}}],["可以在闭包的捕获列表中指定self为unowned",{"2":{"148":1}}],["可以在你确认不需要更新组件时使用",{"2":{"124":1}}],["可以在这个方法中调用settimeout",{"2":{"124":1}}],["可以通过下面的语法来从现有文件中导入代码片段",{"2":{"301":1}}],["可以通过以下配置为每个代码块启用行号",{"2":{"300":1}}],["可以通过在站点配置中添加以下内容来全局设置自定义标题",{"2":{"292":1}}],["可以通过在容器的",{"2":{"292":1}}],["可以通过",{"2":{"257":1}}],["可以通过继承",{"2":{"232":1}}],["可以通过该构造器将结构体的字段初始化为自定义的值",{"2":{"222":1}}],["可以通过返回属性初始值的自求值闭包给属性赋值",{"2":{"194":1}}],["可以通过让块捕获self的弱引用来避免此问题",{"2":{"148":1}}],["可以通过this",{"2":{"124":1}}],["可以通过id+证书名称确定",{"2":{"14":1}}],["可以更换如下",{"2":{"116":1}}],["可以尝试切换到清华站点",{"2":{"83":1}}],["可以加速",{"2":{"82":1}}],["可以设置使用国内淘宝提供的镜像",{"2":{"82":1}}],["可以设置为xcode默认的设置",{"2":{"48":1}}],["可以先请求用户授权",{"2":{"67":1}}],["可以获取用户的公开内容",{"2":{"67":1}}],["可以使用ns",{"2":{"253":1,"254":2,"255":1,"256":1,"257":1}}],["可以使用相同或者不同的类名",{"2":{"231":1}}],["可以使用一个空数组字面量",{"2":{"219":1}}],["可以使用一个数组字面量创建一个选项集",{"2":{"219":1}}],["可以使用常量值或者表达式创建一个选项集",{"2":{"219":1}}],["可以使用按位或操作符",{"2":{"219":1}}],["可以使用is运算符检查一个实例是否是指定类或其子类的实例",{"2":{"204":1}}],["可以使用is运算符来检查类型",{"2":{"204":1}}],["可以使用as",{"2":{"204":1}}],["可以使用selector类型引用",{"2":{"202":1}}],["可以使用lazy修饰符声明一个存储属性",{"2":{"194":1}}],["可以使用可选链语法在一个可能为nil的对象上调用可选的代理方法",{"2":{"193":1}}],["可以使用weak关键字指明某个属性持有其所指向对象的弱引用",{"2":{"172":1}}],["可以使用perform",{"2":{"155":1}}],["可以使用",{"2":{"154":1,"157":1,"163":1,"170":1,"175":1,"179":1,"205":1,"231":1,"280":1,"289":1,"297":1,"306":1}}],["可以使用为空性标注来指明一个参数类型",{"2":{"142":1}}],["可以使用强制下转操作符",{"2":{"139":1}}],["可以使用条件转换操作符",{"2":{"139":1}}],["可以使用原生的",{"2":{"132":1}}],["可以使用自定义按钮和调用图谱",{"2":{"66":1}}],["可以使用分为",{"2":{"66":1}}],["可以使用动态库",{"2":{"26":1}}],["可以存储的数据类型",{"2":{"42":1}}],["可以是数字",{"2":{"328":1}}],["可以是",{"2":{"25":1}}],["可以没有",{"2":{"9":1}}],["订阅+推送模式",{"2":{"33":1}}],["节约流量",{"2":{"33":1}}],["缺点",{"2":{"33":1,"44":2}}],["jelly",{"2":{"334":1,"335":1}}],["jekyll",{"2":{"1":2}}],["j",{"2":{"304":2}}],["jim",{"2":{"156":4}}],["jigsaw",{"2":{"113":1}}],["justgreen",{"2":{"213":1}}],["justyellow",{"2":{"213":1}}],["justred",{"2":{"213":1}}],["jukebox",{"2":{"151":2}}],["jumplocation",{"2":{"86":2}}],["jhipster",{"2":{"113":1}}],["jssnippet",{"2":{"302":1}}],["jsconfig",{"2":{"302":1}}],["jsconsole",{"2":{"292":1}}],["jsfunction",{"2":{"301":1}}],["jsimport",{"2":{"293":1,"306":1}}],["jsexport",{"2":{"276":1,"295":1,"296":3,"297":1,"298":1,"299":1,"300":1,"301":2,"302":1,"305":1}}],["jsx",{"0":{"118":1},"1":{"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1}}],["js中没有方法重载",{"2":{"100":1}}],["js的组成",{"0":{"97":1}}],["js的宏定义如下",{"2":{"92":1}}],["js",{"0":{"96":1},"1":{"97":1,"98":1,"99":1,"100":1},"2":{"92":4,"301":4,"302":4,"306":1}}],["jspostcssisolatestyles",{"2":{"293":1}}],["jsp",{"2":{"90":1}}],["json`",{"2":{"303":4}}],["jsondecoder",{"2":{"205":3}}],["jsonencoder",{"2":{"205":1}}],["jsonobject",{"2":{"198":1}}],["jsonserialization",{"2":{"198":1}}],["json",{"2":{"32":1,"198":2,"205":11}}],["ja",{"2":{"206":1}}],["jacuzzi",{"2":{"184":1}}],["javascipt",{"2":{"356":1}}],["javascriptdocument",{"2":{"356":1}}],["javascript",{"2":{"118":1}}],["javascript操作浏览器部分功能的api",{"2":{"97":1}}],["javascript操作网页上元素的api",{"2":{"97":1}}],["javascript的语法规范",{"2":{"97":1}}],["javascripterror=",{"2":{"92":1}}],["javapublic",{"2":{"356":1}}],["javax",{"2":{"90":7}}],["java",{"2":{"90":12,"356":1}}],["jailbreak",{"0":{"38":1,"39":1},"1":{"39":1,"40":1},"2":{"39":2}}],["jpgpath",{"2":{"67":2}}],["jpg",{"2":{"44":1,"66":2,"70":1,"86":2}}],["jpeg",{"2":{"44":1}}],["文字超链接",{"2":{"308":1}}],["文字高亮功能能使行内部分文字高亮",{"2":{"323":1}}],["文字高亮",{"0":{"323":1},"1":{"324":1,"325":1},"2":{"308":1}}],["文本摘自",{"0":{"350":1}}],["文本块",{"0":{"320":1},"1":{"321":1,"322":1}}],["文本",{"0":{"317":1},"1":{"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"325":1},"2":{"308":1}}],["文本处理",{"2":{"178":1}}],["文本消息",{"2":{"90":1}}],["文本协议",{"2":{"32":1}}],["文件内容如下",{"2":{"380":1}}],["文件内存映射",{"2":{"44":1}}],["文件名默认用作标题",{"2":{"302":1}}],["文件并将以下内容添加到其中",{"2":{"293":1}}],["文件数学方程图片懒加载高级配置",{"2":{"289":1}}],["文件中包含另一个",{"2":{"303":1}}],["文件中",{"2":{"283":1}}],["文件中使用同一",{"2":{"231":1}}],["文件看作同一代码集",{"2":{"260":1}}],["文件导入到",{"2":{"243":2,"245":1}}],["文件暴露给",{"2":{"240":1}}],["文件都可以使用这些",{"2":{"239":1,"244":1}}],["文件到现有的",{"2":{"238":1}}],["文件供",{"2":{"238":1}}],["文件可以在项目中并存",{"2":{"236":1}}],["文件现在可以访问所有",{"2":{"161":1}}],["文件的顶部",{"2":{"161":1}}],["文件的混合语言应用",{"2":{"157":1}}],["文件的内容如下",{"2":{"94":1,"95":1}}],["文件的实现",{"2":{"65":1}}],["文件夹",{"2":{"84":1}}],["文件配置",{"0":{"64":1}}],["文件头",{"2":{"44":18}}],["文件",{"0":{"303":1},"2":{"2":1,"90":3,"94":1,"95":1,"159":1,"230":1,"247":1,"303":2}}],["开箱即用",{"2":{"286":1}}],["开头表示删除",{"2":{"363":1}}],["开头表示新增",{"2":{"363":1}}],["开头",{"2":{"219":1}}],["开头的枚举变量名",{"2":{"218":1}}],["开始进行第4步",{"2":{"372":1}}],["开始进行数据通讯",{"2":{"371":1}}],["开始数据通信",{"2":{"371":1}}],["开始",{"0":{"262":1},"2":{"300":3}}],["开始迁移",{"0":{"232":1},"2":{"228":1}}],["开始才是启动时指定的命令行参数",{"2":{"209":1}}],["开始发布ipa包",{"2":{"95":1}}],["开始ipa打包",{"2":{"95":1}}],["开源",{"2":{"33":1}}],["开源协议",{"2":{"32":1}}],["开发基于混合语言的应用程序",{"2":{"235":1}}],["开发",{"2":{"88":1}}],["开发版本对比",{"0":{"88":1}}],["开发者账号申请注意事项",{"0":{"70":1}}],["开发者账号中可以查看到该应用的地址",{"2":{"9":1}}],["开发人员根据新的证书重新打包ipa",{"2":{"14":1}}],["开发调试的使用",{"2":{"14":1}}],["开发中",{"2":{"8":1}}],["开发过程",{"2":{"2":1}}],["自动生成的",{"2":{"251":1}}],["自动生成的头文件将这些",{"2":{"240":1}}],["自动生成",{"2":{"239":1,"240":1}}],["自动释放指针",{"0":{"226":1},"2":{"210":1}}],["自动释放池块使用",{"2":{"207":1}}],["自动释放池块可以让对象放弃所有权而又不会被立即释放",{"2":{"207":1}}],["自动释放池",{"0":{"207":1},"2":{"192":1}}],["自动打包脚本",{"0":{"93":1},"1":{"94":1,"95":1}}],["自定义标题",{"0":{"292":1}}],["自定义容器可以通过它们的类型",{"2":{"290":1}}],["自定义容器",{"0":{"290":1},"1":{"291":1,"292":1,"293":1}}],["自定义容器默认标题自定义标题rawgithub",{"2":{"289":1}}],["自定义锚点",{"0":{"281":1}}],["自定义分享界面",{"2":{"66":1}}],["自定义分享内容",{"2":{"66":1}}],["自定义二进制",{"2":{"32":1}}],["自旋锁",{"2":{"43":1}}],["自己保留",{"2":{"14":1}}],["连接失败",{"2":{"90":1}}],["连接成功了开始发送心跳",{"2":{"90":1}}],["连接成功",{"2":{"90":1}}],["连接的长短是通过协议来规定和实现的",{"2":{"31":1}}],["连接是否为长连接",{"2":{"31":1}}],["实际上术语",{"2":{"350":1}}],["实体",{"2":{"175":1}}],["实体模型文件中相对应的属性或者方法声明标记",{"2":{"175":1}}],["实时渲染",{"0":{"170":1},"2":{"162":1}}],["实例方法对应的cf",{"2":{"217":1}}],["实例方法",{"2":{"151":1}}],["实例如何根据它是否有值来桥接到",{"2":{"143":1}}],["实例",{"0":{"143":1},"2":{"132":1,"205":2,"306":1}}],["实现和接口将直接放进这个",{"2":{"230":1}}],["实现时",{"2":{"228":1}}],["实现所有协议要求即可",{"2":{"176":1}}],["实现",{"0":{"175":1},"2":{"162":1,"228":1}}],["实现一个类似nsresponder这种在接口中使用了目标",{"2":{"155":1}}],["实现分享功能",{"0":{"66":1}}],["实现高性能缓存",{"2":{"43":1}}],["实现方式",{"2":{"31":1}}],["实用工具",{"2":{"27":1}}],["是怎样转化某些",{"2":{"232":1}}],["是",{"2":{"204":1}}],["是一个nsurlprotectionspace类型的对象",{"2":{"372":1}}],["是一个包含授权请求的对象",{"2":{"372":1}}],["是一个包含三个键值对的",{"2":{"185":1}}],["是一个包含三个元素的",{"2":{"183":1,"184":1}}],["是一个接受内存管理的",{"2":{"189":1}}],["是信号量",{"2":{"43":1}}],["是服务器通过编程的方式手动挂起请求来实现的",{"2":{"31":1}}],["是根据服务端的处理方式来决定的",{"2":{"31":1}}],["是通过设置",{"2":{"31":1}}],["而无需修改issue原文",{"2":{"347":1}}],["而无需将其转换为具体类型",{"2":{"140":1}}],["而非链接本身的title了",{"2":{"330":1}}],["而图片链接",{"2":{"330":1}}],["而应该使用前向声明来引用一个",{"2":{"249":1}}],["而该类型的各种常量会变成相应的类型成员",{"2":{"213":1}}],["而是为nslocalizedstring",{"2":{"206":1}}],["而不必立刻使用",{"2":{"228":1}}],["而不用再进行可用性检查",{"2":{"208":1}}],["而不是默认的",{"2":{"281":1}}],["而不是autoreleasingunsafemutablepointer",{"2":{"226":1}}],["而不是作为结构体本身的属性",{"2":{"218":1}}],["而不是直接返回它",{"2":{"215":1}}],["而不是发生什么特定错误时",{"2":{"197":1}}],["而不是",{"2":{"183":1,"184":1,"185":1,"260":1}}],["而不是比较指针",{"2":{"149":1}}],["而不是一份值拷贝",{"2":{"147":1}}],["而不会切换到原生",{"2":{"63":1}}],["而在",{"2":{"142":1,"206":1}}],["而如果初始化会失败",{"2":{"135":1}}],["而当webview已经创建的时候",{"2":{"92":1}}],["而请求的任务包含多个",{"2":{"61":1}}],["而且使用的",{"2":{"160":1}}],["而且因为",{"2":{"147":1}}],["而且没有对ios",{"2":{"52":1}}],["而且是需要两边都设置才有效",{"2":{"31":1}}],["而",{"2":{"44":1,"167":1}}],["而轮询的长短",{"2":{"31":1}}],["而一种轮询方式是否为长轮询",{"2":{"31":1}}],["协议标记",{"2":{"250":1}}],["协议并绑定到",{"2":{"204":1}}],["协议一样采用",{"2":{"176":1}}],["协议会被导入为",{"2":{"165":1}}],["协议",{"0":{"164":1,"250":1,"251":1},"2":{"161":1,"162":2,"165":1,"176":1,"180":1,"204":2,"205":2,"232":1,"235":2,"251":1}}],["协议限定类",{"0":{"144":1},"2":{"132":1}}],["协议简单",{"2":{"33":1}}],["协议举例",{"2":{"33":1}}],["协商方式",{"2":{"31":1}}],["协同编辑",{"2":{"30":1}}],["长短连接是传输层概念",{"2":{"31":1}}],["长短轮询是应用层概念",{"2":{"31":1}}],["长连接",{"2":{"31":1}}],["长轮询",{"2":{"31":1}}],["轮询",{"2":{"31":1}}],["基本操作流程",{"0":{"391":1}}],["基本语法",{"2":{"357":1}}],["基本格式",{"2":{"326":1}}],["基本数值类型",{"2":{"211":1}}],["基本类型",{"0":{"211":1},"2":{"210":1}}],["基本设置",{"0":{"157":1},"1":{"158":1,"159":1,"160":1,"161":1},"2":{"262":1}}],["基本的发展阶段",{"0":{"31":1}}],["基于混合语言编写应用程序或框架的过程还是有些区别的",{"2":{"236":1}}],["基于这个原因",{"2":{"179":1}}],["基于对象内容进行比较",{"2":{"149":1}}],["基于三角形的边长与起点来创建一个简单的三角形路径",{"2":{"146":1}}],["基于springmvc",{"2":{"113":1}}],["基于scoket",{"2":{"33":1}}],["基于数据库的缓存可以很好的支持元数据",{"2":{"44":1}}],["基于数据库",{"2":{"44":1}}],["基于",{"2":{"44":1}}],["基于文件读写",{"2":{"44":1}}],["基于xmpp",{"2":{"33":1}}],["基于mqtt",{"2":{"33":1}}],["基于webscoket",{"2":{"33":1}}],["基于位置的应用",{"2":{"30":1}}],["智能家居",{"2":{"30":1}}],["滴滴司机位置",{"2":{"30":1}}],["体育实况更新",{"2":{"30":1}}],["股票基金实时报价",{"2":{"30":1}}],["抽奖",{"2":{"30":1}}],["弹窗显示内容",{"2":{"98":1}}],["弹幕",{"2":{"30":1}}],["弹出保存框",{"2":{"14":1}}],["聊天",{"2":{"30":1}}],["即展示一个文件内容的增加与删除",{"2":{"362":1}}],["即",{"2":{"326":1}}],["即一次迁移一个类",{"2":{"230":1}}],["即一个",{"2":{"44":1}}],["即混搭和互用来对应用程序进行增量迁移",{"2":{"228":1}}],["即枚举可以存储任何值",{"2":{"218":1}}],["即takeunretainedvalue",{"2":{"189":1}}],["即应用名或者框架名加上子类名",{"2":{"167":1}}],["即属性",{"2":{"151":1}}],["即使有冲突",{"2":{"389":1}}],["即使原始值不匹配任何枚举值",{"2":{"218":1}}],["即使在多个线程同时访问的情况下",{"2":{"203":1}}],["即使是使用来自",{"2":{"167":1}}],["即使是使用",{"2":{"166":1}}],["即使它们是在",{"2":{"146":2}}],["即使用js发送post请求",{"2":{"92":1}}],["即可执行js",{"2":{"92":1}}],["即8",{"2":{"53":1}}],["即实时性要求高的场景",{"2":{"30":1}}],["即时通信的常用应用场景",{"2":{"30":1}}],["即时通讯技术",{"0":{"29":1},"1":{"30":1,"31":1,"32":1,"33":1,"34":1}}],["即mt=7等等",{"2":{"9":1}}],["目录下新建一个config文件",{"2":{"380":1}}],["目录下的所有所有文件",{"2":{"27":1}}],["目录会生成gitlab",{"2":{"380":1}}],["目录表",{"0":{"289":1}}],["目录",{"0":{"261":1,"308":1},"1":{"262":1,"263":1,"264":1,"265":1,"309":1}}],["目标",{"0":{"202":1},"2":{"192":1,"202":1}}],["目前尚无对应的桥接值类型",{"2":{"180":1}}],["目前只申请下来basic权限",{"2":{"67":1}}],["目前还没申请下来该权限",{"2":{"63":1}}],["目前下载的最新sdk版本为4",{"2":{"63":1}}],["目前大多数app都支持到该版本",{"2":{"48":1}}],["目前使用itunes",{"2":{"27":1}}],["看到提示成功以后就解除权限控制了",{"2":{"27":1}}],["终端",{"2":{"27":1}}],["终端启动时",{"2":{"23":1}}],["7l",{"2":{"392":1}}],["78",{"2":{"391":1}}],["71",{"2":{"391":10}}],["7或macos",{"2":{"160":1}}],["7b5c727466",{"2":{"44":1}}],["7",{"2":{"27":1,"36":1,"296":2,"372":1}}],["7以上的版本已经无法下载ipa包",{"2":{"27":1}}],["卸载原有的itunes",{"2":{"27":1}}],["步骤",{"2":{"27":1}}],["不知道是否准确",{"2":{"328":1}}],["不但如此",{"2":{"239":1,"244":1}}],["不需要导入任何东西到保护伞头文件",{"2":{"245":1}}],["不需要导入语句",{"2":{"241":2,"246":2}}],["不需要任何导入语句",{"2":{"239":1,"244":1}}],["不需要附加圆括号",{"2":{"136":1}}],["不要将",{"2":{"249":1}}],["不要立刻删除",{"2":{"233":1}}],["不要试图保留指针并在函数返回之后继续使用",{"2":{"224":1}}],["不支持联合体",{"2":{"220":1}}],["不支持macos",{"2":{"27":1}}],["不符合",{"2":{"204":1}}],["不是",{"2":{"204":1}}],["不存在且不能创建",{"2":{"197":1}}],["不会被",{"2":{"195":1}}],["不提供单独的内存分配方法",{"2":{"166":1}}],["不同",{"2":{"166":1}}],["不仅可以继承",{"2":{"162":1}}],["不过可能为空",{"2":{"372":1}}],["不过当且仅当authenticationmethod为nsurlauthenticationmethodservertrust这个属性值才不为nil",{"2":{"372":1}}],["不过看起来起来可能不够明显",{"2":{"340":1}}],["不过要注意",{"2":{"331":1}}],["不过这个行间距有点大",{"2":{"324":1}}],["不过依然可以在框架内部的",{"2":{"260":1}}],["不过",{"2":{"136":1,"153":1,"223":1}}],["不失为一个好主意",{"2":{"132":1}}],["不推荐使用",{"2":{"52":1}}],["不然",{"2":{"44":1}}],["不方便扩展",{"2":{"44":1}}],["不能转化某些",{"2":{"234":1}}],["不能识别uiimageorientationright时的方向值",{"2":{"36":1}}],["不能访问库文件中bundle的资源文件",{"2":{"26":1}}],["69",{"2":{"391":1}}],["66",{"2":{"391":1}}],["60",{"2":{"82":1,"90":1}}],["6d6f6f76",{"2":{"44":1}}],["68746d6c3e",{"2":{"44":1}}],["6",{"2":{"27":3,"36":1,"66":1,"117":1,"296":1,"301":2}}],["6以下的版本",{"2":{"27":1}}],["导出",{"2":{"95":1}}],["导出兼容版本path",{"2":{"26":1}}],["导入代码片段",{"0":{"301":1}}],["导入枚举时",{"2":{"255":1}}],["导入流程都是一样的",{"2":{"247":1}}],["导入希望暴露给",{"2":{"239":1}}],["导入外部框架",{"0":{"247":1},"2":{"235":1}}],["导入相关的系统框架",{"2":{"231":1}}],["导入后的结构体会用存储属性表示结构体中的字段",{"2":{"216":1}}],["导入后会具有相应的内存管理策略",{"2":{"136":1}}],["导入函数作为类型成员",{"0":{"217":1},"2":{"210":1}}],["导入的常量枚举和结构体",{"0":{"213":1},"2":{"210":1}}],["导入时",{"2":{"195":1}}],["导入为抛出方法",{"2":{"195":1}}],["导入这些类型时",{"2":{"180":1}}],["导入器也会将值类型替换为相对应的引用类型",{"2":{"179":1}}],["导入器会将引用类型替换为相对应的值类型",{"2":{"179":1}}],["导入过程会做以下处理",{"2":{"161":1}}],["导入过程决定了",{"2":{"161":1}}],["导入过程非常简单",{"2":{"161":1}}],["导入过程",{"0":{"161":1},"2":{"157":1}}],["导入它们时则会使用相应的类型作为键或元素的类型",{"2":{"150":1}}],["导入到",{"2":{"142":1,"145":3,"218":1,"222":1,"241":2,"246":2,"247":2}}],["导入一个",{"2":{"132":1}}],["导入",{"0":{"128":1},"2":{"135":3,"136":1,"161":1,"187":1}}],["导入定时器",{"2":{"85":1}}],["导入coretelephony",{"2":{"54":1}}],["导入工程中",{"2":{"26":1}}],["真机打包path",{"2":{"26":1}}],["对其加密",{"2":{"371":1}}],["对称密码",{"2":{"371":1}}],["对齐",{"0":{"358":1}}],["对用户达成目标至关重要的信息",{"2":{"294":2}}],["对一些",{"2":{"210":1}}],["对一个实例使用键路径所得到的结果就如同直接访问该实例的对应属性一样",{"2":{"156":1}}],["对类使用",{"2":{"163":1}}],["对象来判断",{"2":{"197":1}}],["对象填充",{"2":{"195":1}}],["对象也都是非托管对象",{"2":{"189":1}}],["对象包装在一个unmanaged",{"2":{"189":1}}],["对象进行内存管理",{"2":{"189":1}}],["对象的",{"2":{"188":1}}],["对象的内存",{"2":{"186":1}}],["对象的类名",{"2":{"152":1}}],["对象",{"2":{"169":1,"179":1,"182":2,"183":1,"184":1,"185":1,"186":1,"188":2,"198":1}}],["对象比较",{"0":{"149":1},"1":{"150":1},"2":{"132":1}}],["对",{"2":{"152":1}}],["对话框时",{"2":{"66":1}}],["对话框会执行快速应用切换操作",{"2":{"66":1}}],["对自定义的分享按钮的样式的说明",{"2":{"66":1}}],["对磁盘缓存来说",{"2":{"43":1}}],["对设计者要求高",{"2":{"33":1}}],["对于同一个文件的多处变化",{"2":{"384":1}}],["对于completionhandler参数是一个最终处理凭据的回调",{"2":{"372":1}}],["对于框架的",{"2":{"260":1}}],["对于应用程序的",{"2":{"260":1}}],["对于其他方法",{"2":{"257":1}}],["对于对象下标方法",{"2":{"257":1}}],["对于初始化方法",{"2":{"257":1}}],["对于",{"2":{"253":1}}],["对于继承自",{"2":{"245":1}}],["对于如何将属性从",{"2":{"232":1}}],["对于如下",{"2":{"217":1}}],["对于指向原始内存的无类型指针",{"2":{"223":1}}],["对于类类型",{"2":{"223":1}}],["对于类型来说",{"2":{"161":1}}],["对于返回类型",{"2":{"223":1}}],["对于导入到",{"2":{"218":1}}],["对于那些没有内存管理标注的",{"2":{"189":1}}],["对于那些从",{"2":{"164":1}}],["对于从带内存管理标注的",{"2":{"188":1}}],["对于采用nscoding协议的类的子类",{"2":{"164":1}}],["对于函数和方法",{"2":{"161":1}}],["对于二进制数据",{"2":{"90":1}}],["对于分享的内容content",{"2":{"66":1}}],["对于内存缓存的存取来说",{"2":{"43":1}}],["对于打包到bundle中的文件",{"2":{"26":1}}],["对于ios8以上的系统",{"2":{"26":1}}],["对应的类型",{"2":{"211":1}}],["对应一个文件",{"2":{"44":1}}],["对应",{"2":{"14":2}}],["打印",{"2":{"181":1,"206":2,"209":3,"215":1,"220":2,"222":2}}],["打印输出",{"2":{"155":1}}],["打包ipa完成",{"2":{"95":1}}],["打包模式",{"2":{"95":1}}],["打包framework",{"2":{"26":1}}],["打开一下连接",{"2":{"39":1}}],["打开终端",{"2":{"27":2}}],["打开",{"2":{"14":1}}],["类提供了一个接收一些键值对作为可变参数的便利构造器",{"2":{"256":1}}],["类才能在",{"2":{"248":1}}],["类一样",{"2":{"239":1,"244":1}}],["类似",{"2":{"331":1}}],["类似编程语言中的变量",{"2":{"328":1}}],["类似info",{"2":{"239":1}}],["类似于",{"2":{"165":2}}],["类工厂方法导入为",{"2":{"253":1}}],["类工厂方法",{"0":{"254":1},"2":{"235":1}}],["类工厂方法和便利构造器",{"0":{"134":1},"2":{"132":1}}],["类遵守的",{"0":{"250":1},"2":{"235":1}}],["类起了一个新的类名",{"2":{"233":1}}],["类集成",{"2":{"232":1}}],["类指定在",{"2":{"231":1}}],["类必须是一个",{"2":{"234":1}}],["类必须继承自",{"2":{"231":1}}],["类必须实现协议中声明的所有构造器",{"2":{"176":1,"250":1}}],["类能在",{"2":{"231":1}}],["类前缀在",{"2":{"231":1}}],["类将某个实例转化为",{"2":{"205":1}}],["类从",{"2":{"205":2}}],["类或者协议",{"2":{"249":1}}],["类或者继承自",{"2":{"166":1}}],["类或协议",{"0":{"249":1},"2":{"235":1}}],["类或",{"2":{"205":1}}],["类继承自",{"2":{"201":1}}],["类都是引用类型",{"2":{"187":1}}],["类可以在实现文件",{"2":{"251":1}}],["类可以遵守该协议",{"2":{"250":1}}],["类可以像采用",{"2":{"176":1}}],["类可以基于其所在模块来消除歧义",{"2":{"167":1}}],["类采用的协议",{"2":{"176":1}}],["类和",{"2":{"182":1}}],["类和结构",{"2":{"172":1,"174":1}}],["类和协议的前向声明只能用于声明方法和属性",{"2":{"249":1}}],["类和协议的命名空间是统一的",{"2":{"165":1}}],["类和协议章节",{"2":{"232":1}}],["类和协议",{"0":{"162":1},"1":{"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1},"2":{"263":1}}],["类名",{"2":{"233":1}}],["类名代替原来的",{"2":{"233":1}}],["类名字符串的",{"2":{"167":1}}],["类名的方式来查看",{"2":{"234":1}}],["类名的",{"0":{"167":1},"2":{"162":1}}],["类会将其全限定名暴露给",{"2":{"167":1}}],["类会作为泛型类导入到",{"2":{"145":1}}],["类在",{"2":{"167":1,"231":1}}],["类引入了许多需要",{"2":{"163":1}}],["类的子类",{"2":{"234":1}}],["类的全限定名是mygreatapp",{"2":{"167":1}}],["类的命名空间基于其所在的模块",{"2":{"167":1}}],["类的类名即可",{"2":{"163":1}}],["类的类名包含",{"2":{"152":1}}],["类的",{"2":{"163":1,"166":1,"245":1,"248":1,"260":1}}],["类解档",{"2":{"152":1}}],["类到",{"2":{"152":1}}],["类使用",{"2":{"152":1,"168":1}}],["类方法后的方法名",{"2":{"254":1}}],["类方法",{"2":{"151":1}}],["类时",{"2":{"151":1,"166":1,"180":1}}],["类声明和分类声明",{"2":{"145":1}}],["类类型或值类型的工作",{"2":{"138":1}}],["类中的",{"2":{"156":1}}],["类中",{"2":{"135":1}}],["类型对应的",{"2":{"240":1}}],["类型之间的转换工作",{"2":{"221":1}}],["类型以及相应的",{"2":{"205":1}}],["类型转换",{"2":{"204":1}}],["类型转换为",{"2":{"177":2}}],["类型属性",{"2":{"203":1}}],["类型属性会成为",{"2":{"151":1}}],["类型时",{"2":{"187":1}}],["类型桥接为",{"2":{"186":1}}],["类型互换使用",{"2":{"186":1}}],["类型会被导入为",{"2":{"186":1}}],["类型到",{"2":{"161":1}}],["类型的头文件",{"2":{"260":1}}],["类型的",{"2":{"183":1,"184":2,"185":2}}],["类型的返回值",{"2":{"151":1}}],["类型的值",{"2":{"141":1,"224":2,"225":2,"226":1}}],["类型方法会成为",{"2":{"151":1}}],["类型别名",{"2":{"151":1}}],["类型重写这两个运算符",{"2":{"149":1}}],["类型为",{"2":{"139":1,"141":3}}],["类型兼容性小节",{"2":{"231":1,"248":1}}],["类型兼容性",{"0":{"151":1},"1":{"152":1,"153":1},"2":{"132":1}}],["类型",{"2":{"90":1,"177":2,"182":1,"186":1,"195":1,"198":1,"204":2,"205":2,"211":3,"240":1,"260":1}}],["类",{"0":{"163":1},"1":{"164":1},"2":{"25":1,"133":1,"151":1,"157":2,"161":1,"162":2,"166":1,"167":1,"186":1,"201":1,"230":1,"231":2,"232":1,"234":1,"248":1,"260":2}}],["级联运算符",{"2":{"25":1}}],["相对应的",{"2":{"216":1}}],["相对应的nsmanagedobject子类person中的代码如下",{"2":{"175":1}}],["相对于普通http网络请求",{"2":{"371":1}}],["相对于8",{"2":{"53":1}}],["相对于",{"2":{"43":1}}],["相接合",{"2":{"157":1}}],["相接合的特性",{"2":{"132":1}}],["相反",{"2":{"152":1,"215":1}}],["相当于三目运算符的简写",{"2":{"25":1}}],["相应文件配置文件>",{"2":{"23":1}}],["前端",{"0":{"267":1}}],["前端工程化",{"0":{"5":1}}],["前身为欧洲计算机制造商协会",{"2":{"97":1}}],["前面的数据",{"2":{"25":1}}],["前面的数据有值",{"2":{"25":1}}],["就下了一道敕令",{"2":{"350":1}}],["就是在数字后面加一个点",{"2":{"340":1}}],["就是一直",{"2":{"43":1}}],["就需要检查这些",{"2":{"208":1}}],["就需要给没个block任务添加入组与出组的操作",{"2":{"61":1}}],["就像使用系统的",{"2":{"239":1,"244":1}}],["就像下面这样",{"2":{"222":1}}],["就像在",{"2":{"193":1}}],["就像第三行所做的一样",{"2":{"141":1}}],["就不需要在构造器中为其分配初始值了",{"2":{"169":1}}],["就不需要提供该构造器的完整实现",{"2":{"164":1}}],["就不执行",{"2":{"25":1}}],["就可用标准",{"2":{"248":1}}],["就可以为你对其进行内存管理",{"2":{"189":1}}],["就可以为其提供一个在",{"2":{"152":1}}],["就可以进一步桥接为",{"2":{"186":1}}],["就可以在单元测试的",{"2":{"240":1}}],["就可以在",{"2":{"170":1,"201":1}}],["就可在",{"2":{"151":1}}],["就将导致强引用循环",{"2":{"148":1}}],["就无法辨别它是可选类型还是非可选类型",{"2":{"142":1}}],["就很困难了",{"2":{"53":1}}],["就会将该类型导入为枚举或结构体",{"2":{"213":1}}],["就会将之导入为anyhashable类型",{"2":{"150":1}}],["就会抛出一个",{"2":{"198":1}}],["就会导致数据错误",{"2":{"44":1}}],["就会立即清除",{"2":{"16":1}}],["就开始调用这个方法",{"2":{"37":1}}],["就要用到appdelegate代理对象了",{"2":{"37":1}}],["当有多个git账号时",{"2":{"379":1}}],["当收到质询之后就要开始进行客服端验证了",{"2":{"372":1}}],["当走到步骤2时",{"2":{"372":1}}],["当我们进行访问一个https网站时",{"2":{"372":1}}],["当我们使用其他的三方库做网络请求或则图片下载时",{"2":{"61":1}}],["当时的皇帝",{"2":{"350":1}}],["当存在",{"2":{"260":1}}],["当requestwheninuseauthorization",{"2":{"208":1}}],["当产生错误时",{"2":{"195":1}}],["当然",{"2":{"164":1,"189":1}}],["当一个可选值传给一个接受非空id类型参数的",{"2":{"143":1}}],["当你只关心是否有错误",{"2":{"197":1}}],["当你需要表示值缺失的情况时",{"2":{"142":1}}],["当你准备开始把",{"2":{"132":1}}],["当用anyobject类型的值调用一个",{"2":{"141":1}}],["当用户使用分享对话框分享内容时",{"2":{"66":1}}],["当id类型作为any类型导入到",{"2":{"138":1}}],["当",{"2":{"137":1,"138":1,"163":1,"166":1}}],["当指定路径的图片文件不存在时",{"2":{"135":1}}],["当前手机系统允许使用的sdk的最高版本",{"2":{"50":1}}],["当前编译所使用的sdk版本",{"2":{"48":1}}],["当前程序都会进入后台",{"2":{"37":1}}],["当使用了pch文件时",{"2":{"46":1}}],["当单条数据小于",{"2":{"44":1}}],["当发生内存警告时触发该事件",{"2":{"37":1}}],["当程序再次进入前台的时候调用",{"2":{"37":1}}],["当程序进入后台时",{"2":{"37":1}}],["当程序启动后会显示一张启动图片",{"2":{"37":1}}],["当这个图片显示完毕",{"2":{"37":1}}],["当原来的变量有值时",{"2":{"25":1}}],["当客户端使用的utf",{"2":{"3":1}}],["赋值运算符",{"2":{"25":1}}],["箭头函数",{"2":{"25":1}}],["有遇到过一些网络代理工具使用http",{"2":{"372":1}}],["有几个重要的属性",{"2":{"372":1}}],["有序列表也有多级结构",{"2":{"342":1}}],["有序列表",{"2":{"308":1}}],["有助于用户更顺利达成目标的建议性信息",{"2":{"294":2}}],["有如下",{"2":{"252":1}}],["有如下要求",{"2":{"160":1}}],["有默认值",{"2":{"25":1}}],["有的服务器只识别pem格式的文件",{"2":{"14":1}}],["函数同样不具有捕获周围作用域上下文的能力",{"2":{"227":1}}],["函数才可以作为函数指针参数",{"2":{"227":1}}],["函数接受一个cfarraycallbacks结构体作为参数",{"2":{"227":1}}],["函数接受一个cvarargtype类型的数组",{"2":{"215":1}}],["函数作为其参数",{"2":{"227":1}}],["函数调用结束时",{"2":{"226":1}}],["函数导入为相应结构体的成员函数",{"2":{"217":1}}],["函数则会在闭包体中通过闭包参数来提供该值",{"2":{"215":1}}],["函数指针调用约定的",{"2":{"227":1}}],["函数指针导入为沿用其调用约定的闭包",{"2":{"227":1}}],["函数指针",{"0":{"227":1},"2":{"210":1,"227":2}}],["函数在自动释放池块中执行一个闭包",{"2":{"207":1}}],["函数就可以实现nslocalizedstring系列宏的这些功能",{"2":{"206":1}}],["函数不会保留cfstring对象",{"2":{"189":1}}],["函数声明",{"2":{"188":1,"214":1,"217":1}}],["函数或",{"2":{"188":1}}],["函数用于从一个字符串表示的类名获取该类的引用",{"2":{"167":1}}],["函数提供",{"2":{"152":1}}],["函数组件",{"2":{"120":1}}],["函数也是一种类型",{"2":{"100":1}}],["函数",{"0":{"100":1,"214":1},"1":{"215":1},"2":{"189":2,"210":1,"215":2,"217":1}}],["函数体只有1行",{"2":{"25":1}}],["函数a可以作为另外一个b的参数",{"2":{"25":1}}],["函数是一等公民",{"2":{"25":1}}],["函数只有可选参数",{"2":{"25":1}}],["函数的va",{"2":{"215":1}}],["函数的tablename",{"2":{"206":1}}],["函数的函数名",{"2":{"147":1}}],["函数的可选参数",{"2":{"25":1}}],["函数的返回值",{"2":{"25":1}}],["位字段",{"0":{"221":1},"2":{"210":1}}],["位平台字节序值的nsstring方法",{"2":{"181":1}}],["位于最后的",{"2":{"64":1}}],["位于图图1",{"2":{"13":1}}],["位置可选参数",{"2":{"25":1}}],["接收一个或者多个指针参数的",{"2":{"257":1}}],["接收到非托管对象后",{"2":{"189":1}}],["接口导入到",{"2":{"256":1}}],["接口可能不适合或者没必要暴露给",{"2":{"256":1}}],["接口使用了自定义的",{"2":{"240":1}}],["接口",{"2":{"240":1,"257":1}}],["接口在",{"0":{"256":1},"2":{"235":1}}],["接口提供",{"0":{"253":1},"1":{"254":1,"255":1},"2":{"235":1}}],["接口与抽象类",{"2":{"25":1}}],["接着被导入到",{"2":{"161":1}}],["接下来说明一下导出p12文件给服务器使用",{"2":{"14":1}}],["集合和",{"2":{"169":1}}],["集合同样是用",{"2":{"169":1}}],["集合",{"0":{"184":1},"2":{"25":1,"177":1,"184":3}}],["三级标题",{"0":{"313":1},"1":{"314":1,"315":1,"316":1},"2":{"310":1}}],["三引号",{"2":{"25":1}}],["三重缓存",{"2":{"23":1}}],["添加每个变化前",{"2":{"384":1}}],["添加当前目录的所有文件到暂存区",{"2":{"384":1}}],["添加指定目录到暂存区",{"2":{"384":1}}],["添加指定文件到暂存区",{"2":{"384":1}}],["添加config配置文件",{"2":{"380":1}}],["添加如下内容",{"2":{"380":1}}],["添加的每张图片启用懒加载",{"2":{"305":1}}],["添加的仓库包括",{"2":{"24":1,"40":1}}],["添加",{"2":{"121":1,"238":1}}],["添加url",{"2":{"79":1}}],["添加仓库源",{"0":{"40":1}}],["添加角色",{"2":{"2":1}}],["解决方法",{"0":{"380":1}}],["解决闭包引起的循环强引用",{"2":{"148":1}}],["解决在window",{"2":{"36":1}}],["解决办法就是修改",{"2":{"23":1}}],["解压",{"2":{"4":1,"71":1}}],["~~",{"2":{"325":2}}],["~~斜粗体删除线1~~",{"2":{"325":1}}],["~~删除线~~",{"2":{"325":1}}],["~",{"2":{"23":6,"380":7,"392":16}}],["执行以下指令",{"2":{"23":1}}],["一",{"0":{"392":1}}],["一次按古法打鸡蛋时碰巧将一个手指弄破了",{"2":{"350":1}}],["一次性初始化",{"2":{"210":1}}],["一书",{"2":{"350":1}}],["一级有序列表",{"0":{"339":1},"1":{"340":1,"341":1}}],["一级标题",{"0":{"311":1},"1":{"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"319":1,"320":1,"321":1,"322":1,"323":1,"324":1,"325":1,"326":1,"327":1,"328":1,"329":1,"330":1,"331":1,"332":1,"333":1,"334":1,"335":1,"336":1,"337":1,"338":1,"339":1,"340":1,"341":1,"342":1,"343":1,"344":1,"345":1,"346":1,"347":1,"348":1,"349":1,"350":1,"351":1,"352":1,"353":1,"354":1,"355":1,"356":1,"357":1,"358":1,"359":1,"360":1,"361":1,"362":1,"363":1,"364":1,"365":1,"366":1,"367":1,"368":1,"369":1},"2":{"310":1}}],["一些",{"2":{"161":1,"208":1,"256":1}}],["一旦self也持有对块的强引用",{"2":{"148":1}}],["一旦强制下转失败",{"2":{"139":1}}],["一定要慎重考虑内存管理问题",{"2":{"148":1}}],["一样",{"2":{"141":1,"168":1}}],["一种针对异步编程工具",{"2":{"113":1}}],["一般在https访问的第3步过程中",{"2":{"372":1}}],["一般把全文所有的url标识符统一放在文章末尾",{"2":{"328":1}}],["一般很少需要这种动态分派",{"2":{"153":1}}],["一般为7200s",{"2":{"34":1}}],["一般是重新电脑才会生效",{"2":{"23":1}}],["一个github",{"2":{"379":1}}],["一个gitlab",{"2":{"379":1}}],["一个对称密钥用于ssl协议的安全数据通讯的加解密通讯",{"2":{"371":1}}],["一个类型为int",{"2":{"227":1}}],["一个类中的所有信息都在一个单独的",{"2":{"159":1}}],["一个autoreleasingunsafemutablepointer",{"2":{"226":1}}],["一个inout表达式",{"2":{"226":1}}],["一个inout",{"2":{"225":1}}],["一个unsafemutablepointer",{"2":{"225":1}}],["一个左操作数为type类型的inout表达式",{"2":{"224":1,"225":1}}],["一个string类型的值",{"2":{"224":1}}],["一个空的选项集使用常数0表示",{"2":{"219":1}}],["一个选项集是一些整数值的位掩码",{"2":{"219":1}}],["一个应用从",{"2":{"205":1}}],["一个属性可能会覆写其自动合成的读取方法",{"2":{"194":1}}],["一个声明的底层存储和实现部分将在运行时由",{"2":{"175":1}}],["一个叫做observer的",{"2":{"167":1}}],["一个有返回值的无参数方法可以像属性那样使用点语法调用",{"2":{"136":1}}],["一个电话打过来了",{"2":{"37":1}}],["一个",{"2":{"31":1,"167":1,"218":1,"219":1,"224":1,"256":1}}],["一栏",{"2":{"27":1}}],["一共产生了5个文件",{"2":{"14":1}}],["国内用户需要设置",{"2":{"23":1}}],["创建与到与本地分支对应的远程分支上",{"2":{"389":1}}],["创建空选项集时",{"2":{"219":1}}],["创建自动释放对象的相关代码",{"2":{"207":1}}],["创建应用需要使用",{"2":{"160":1}}],["创建",{"2":{"154":1,"293":1}}],["创建名为myapp的工程",{"2":{"103":1}}],["创建message类来接受客户端发来的websocket请求",{"2":{"90":1}}],["创建方式",{"2":{"66":1}}],["创建如下",{"2":{"66":1}}],["创建components目录并创建home组件",{"2":{"21":1,"106":1}}],["创建组件",{"2":{"21":1,"106":1}}],["再加一个空格",{"2":{"340":1}}],["再使用可选链语法调用方法会更为安全和方便",{"2":{"155":1}}],["再返回结果",{"2":{"61":1}}],["再次重启电脑",{"2":{"27":1}}],["再次回到apple",{"2":{"14":1}}],["再安装",{"2":{"21":1,"106":1}}],["先创建",{"2":{"21":1,"106":1}}],["到远程仓库",{"2":{"389":1}}],["到文件的",{"2":{"44":1}}],["到后",{"2":{"34":1}}],["到需要创建项目的目录下",{"2":{"21":1,"84":1,"106":1,"107":1}}],["到此新的provisioning",{"2":{"14":1}}],["vendors",{"2":{"391":3}}],["vec",{"2":{"304":22}}],["versions",{"2":{"95":1}}],["version=",{"2":{"94":2}}],["version",{"0":{"87":1},"1":{"88":1},"2":{"50":4,"53":7,"227":1,"391":2,"397":2}}],["vp",{"2":{"293":3}}],["vuejs",{"2":{"285":1}}],["vue",{"0":{"267":1},"2":{"268":1,"306":3}}],["vs",{"2":{"113":1,"301":1}}],["v4",{"2":{"103":1}}],["vc",{"2":{"59":13}}],["vasprintf",{"2":{"215":1}}],["valeriangalliat",{"2":{"306":1}}],["validatingutf8",{"2":{"215":1}}],["validate",{"2":{"95":1}}],["valid",{"2":{"86":1}}],["values",{"2":{"256":1,"397":1}}],["value2",{"2":{"218":1}}],["value1",{"2":{"218":1}}],["value参数提供了默认值",{"2":{"206":1}}],["valuefromswift",{"2":{"143":3}}],["value=obj",{"2":{"90":1}}],["value=",{"2":{"90":1}}],["value",{"2":{"44":4,"86":1,"90":1,"92":1,"110":1,"142":6,"143":2,"156":5,"185":1,"206":2,"209":2}}],["va",{"2":{"46":1,"215":2}}],["varieties",{"2":{"205":3}}],["var",{"2":{"25":1,"90":2,"92":4,"136":1,"142":2,"145":2,"146":1,"150":3,"151":4,"152":1,"156":3,"165":1,"169":2,"170":2,"175":2,"176":1,"183":1,"184":1,"185":1,"194":3,"198":1,"201":4,"213":10,"215":1,"216":3,"217":3,"218":3,"219":6,"220":2,"225":2,"227":2,"257":5}}],["vim",{"2":{"392":1}}],["vitepress",{"2":{"268":2,"275":1,"276":1,"279":1,"285":1,"292":2,"293":2,"294":1,"295":1,"296":2,"301":1,"302":4,"303":1,"306":3}}],["visible",{"2":{"59":1}}],["viewchild",{"2":{"113":2}}],["viewcontrollers",{"2":{"59":4}}],["viewcontroller",{"0":{"58":1},"1":{"59":1},"2":{"59":2,"391":5,"395":2}}],["viewdidload",{"2":{"92":2}}],["view",{"0":{"59":1,"75":1},"1":{"76":1,"77":1,"78":1},"2":{"58":1,"59":7,"66":2,"67":3,"73":1,"76":4,"79":1,"92":2}}],["vi",{"2":{"23":1,"380":1}}],["v",{"2":{"20":1,"53":10,"295":2,"385":1,"389":1,"391":2,"395":1}}],["void",{"2":{"16":1,"37":3,"66":1,"67":4,"73":2,"77":1,"79":3,"90":31,"92":2,"142":3,"143":1,"144":1,"147":1,"154":1,"176":1,"183":1,"184":1,"185":1,"195":2,"217":2,"223":2,"227":1,"245":1,"257":1,"258":1,"356":1}}],["默认提交到与本地分支对应的远程分支上",{"2":{"389":1}}],["默认的处理方法",{"2":{"372":1}}],["默认禁用",{"2":{"305":1}}],["默认禁用行号",{"2":{"300":2}}],["默认为",{"2":{"293":1}}],["默认标题",{"0":{"291":1}}],["默认情况下是",{"2":{"301":1,"303":1}}],["默认情况下",{"2":{"240":1,"255":1,"259":1,"284":1}}],["默认已通过",{"2":{"66":1}}],["默认源",{"2":{"20":1}}],["默认采用iso8859",{"2":{"3":1}}],["$$",{"2":{"304":4}}],["$a",{"2":{"304":2}}],["$altoolpath",{"2":{"95":2}}],["$1",{"2":{"287":2,"358":2}}],["$12",{"2":{"287":2,"358":2}}],["$1600",{"2":{"287":2,"358":2}}],["$event",{"2":{"110":1}}],["$exportipapath",{"2":{"95":3}}],["$scheme",{"2":{"95":2}}],["$sudo",{"2":{"20":2}}],["$number",{"2":{"95":4}}],["$0`",{"2":{"95":1}}],["$path",{"2":{"23":1}}],["$pod",{"2":{"20":1}}],["$gem",{"2":{"20":4}}],["$",{"2":{"20":1,"21":6,"23":2,"25":1,"82":5,"83":2,"84":4,"85":1,"95":18,"102":1,"103":3,"105":1,"106":6,"107":2,"116":7,"117":5,"130":1,"209":1,"304":24,"380":3,"382":3,"383":4,"384":7,"385":6,"386":15,"387":10,"388":2,"389":14,"390":4,"391":5}}],["$maven",{"2":{"4":1}}],["入门",{"0":{"18":1,"19":1,"22":1,"38":1,"80":1,"101":1,"104":1,"115":1},"1":{"19":1,"20":2,"21":2,"23":1,"24":1,"25":1,"39":1,"40":1,"81":1,"82":1,"83":1,"84":1,"85":1,"102":1,"103":1,"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1}}],["^completionblock",{"2":{"147":1}}],["^receivemsg",{"2":{"90":1}}],["^",{"2":{"16":2,"54":1,"61":8,"66":1,"67":4,"73":1,"74":1,"79":3,"90":7,"92":1,"147":1,"148":1,"203":1}}],["记得在主队列中返回数据",{"2":{"16":1}}],["记录下来",{"2":{"13":1}}],["该语法也可以实现代码高亮",{"2":{"322":1}}],["该头文件以产品模块名拼接上",{"2":{"240":1}}],["该头文件在项目目录下不可见",{"2":{"240":1}}],["该路径相对于项目",{"2":{"239":1}}],["该缓冲区的指针会被传递给函数",{"2":{"224":1}}],["该类型可以使用任何提供了编码器和解码器的序列化格式",{"2":{"205":1}}],["该类将在",{"2":{"152":1}}],["该参数会被",{"2":{"195":1}}],["该函数声明在os模块的子模块log中",{"2":{"190":1}}],["该关键字仅能修饰可选的类类型",{"2":{"172":1}}],["该方法会以抛出错误的方式替代错误指针参数",{"2":{"198":1}}],["该方法的一些变体在指定线程执行选择器",{"2":{"155":1}}],["该方法已经在异步队列中",{"2":{"16":1}}],["该",{"2":{"151":1}}],["该属性会以如下形式导入到",{"2":{"144":1}}],["该零时文件",{"2":{"16":1}}],["时鸣春涧中",{"2":{"364":1}}],["时会非常有用",{"2":{"152":1}}],["时会附带容器中元素的类型信息",{"2":{"145":1}}],["时会被检查初始化是否会失败",{"2":{"135":1}}],["时需要将参数显式转换为any类型",{"2":{"143":1}}],["时避免强引用循环",{"0":{"148":1},"2":{"132":1}}],["时被调用",{"2":{"124":1}}],["时也可以当作锁来",{"2":{"43":1}}],["时",{"2":{"16":1,"44":2,"137":1,"138":2,"143":1,"151":1,"153":1,"167":1,"169":1,"179":2,"213":1,"234":1,"240":2,"260":1}}],["为此我们可以使用url标识符的形式",{"2":{"330":1}}],["为github对markdown的扩充语法",{"2":{"307":1}}],["为避免循环引用",{"2":{"249":1}}],["为产品模块命名",{"0":{"259":1},"2":{"235":1}}],["为它自动生成的头文件",{"2":{"234":1}}],["为键路径创建一个对应的观察者并调用",{"2":{"201":1}}],["为想要观察的属性添加",{"2":{"201":1}}],["为每一个和",{"2":{"175":1}}],["为源自nsobject的类实现了equatable协议",{"2":{"149":1}}],["为了防止",{"2":{"256":1}}],["为了遵守协议",{"2":{"250":1}}],["为了解决符号未定义的错误",{"2":{"245":1}}],["为了能在",{"2":{"234":1}}],["为了让",{"2":{"231":1}}],["为了更好地与",{"2":{"229":1}}],["为了更好地支持与",{"2":{"210":1}}],["为了确保应用程序能够适应任何功能上的差异",{"2":{"208":1}}],["为了使用单独的包来提供本地化资源",{"2":{"206":1}}],["为了将某条信息记录到指定子系统",{"2":{"190":1}}],["为了便于与",{"2":{"177":1}}],["为了符合协议",{"2":{"176":1}}],["为了在",{"2":{"175":1}}],["为了获取",{"2":{"167":1}}],["为了保持命名空间",{"2":{"167":1}}],["为了开始体验在",{"2":{"158":1}}],["为了区分",{"2":{"154":1}}],["为了避免强引用循环",{"2":{"148":1}}],["为了告知调用者",{"2":{"135":1}}],["为了统一和简洁",{"2":{"134":1}}],["为空性和可选类型",{"0":{"142":1},"1":{"143":1},"2":{"132":1,"135":1,"136":1}}],["为",{"0":{"229":1,"253":1},"1":{"254":1,"255":1},"2":{"95":1,"228":1,"235":1,"245":1,"259":1,"260":1,"304":1}}],["为结构体",{"2":{"53":1}}],["为一个零时的目录",{"2":{"16":1}}],["为apple",{"2":{"9":1}}],["上面提到的很多扩展功能都是通过自定义插件实现的",{"2":{"306":1}}],["上面的例子中",{"2":{"227":1}}],["上述列表中没有包含数组",{"2":{"226":1}}],["上述声明导入到",{"2":{"151":1}}],["上述声明将以如下形式导入到",{"2":{"145":1}}],["上的应用程序图标启动应用程序",{"2":{"209":1}}],["上测试",{"2":{"74":1}}],["上线发布app就可以了",{"2":{"14":1}}],["上传本地指定分支到远程仓库",{"2":{"389":2}}],["上传到fir",{"2":{"95":1}}],["上传视频的注意事项如图所示",{"2":{"66":1}}],["上传完成之后",{"2":{"14":1}}],["上传csr文件",{"2":{"14":1}}],["说明",{"2":{"14":1,"63":1}}],["序列化",{"0":{"205":1},"2":{"192":1}}],["序列",{"2":{"14":1}}],["刚才已过期的",{"2":{"14":1}}],["以此类推",{"2":{"390":1}}],["以此表明",{"2":{"175":1}}],["以此表明该方法是",{"2":{"133":1}}],["以前github对中文支持的不好",{"2":{"331":1}}],["以前使用cftyperef的地方",{"2":{"187":1}}],["以获得更好的隔离",{"2":{"293":1}}],["以备解决问题时使用",{"2":{"233":1}}],["以逗号分隔的参数提供平台版本要求",{"2":{"208":1}}],["以便可以在需要时重写它们",{"2":{"206":1}}],["以便在异常到达任何",{"2":{"199":1}}],["以下是jonathan",{"2":{"350":1}}],["以下示例演示了在",{"2":{"196":1}}],["以下简称id",{"2":{"13":1}}],["以表明该方法可以抛出一个错误",{"2":{"195":1}}],["以如下所示导入它们",{"2":{"183":1,"184":1,"185":1,"189":1}}],["以",{"2":{"142":2}}],["以防用户未安装原生",{"2":{"66":1}}],["以上",{"2":{"39":1}}],["以上的版本",{"2":{"27":1,"117":1}}],["以及其他",{"2":{"371":1}}],["以及其所要求的方法encode",{"2":{"164":1}}],["以及所有自定义和主题组件",{"2":{"286":1}}],["以及标记了",{"2":{"260":1}}],["以及在",{"2":{"248":1}}],["以及nslocalizedstringwithdefaultvalue",{"2":{"206":1}}],["以及通过网络进行传递",{"2":{"205":1}}],["以及更高的系统平台上可用",{"2":{"190":1}}],["以及方法",{"2":{"176":1}}],["以及一个叫做friends的对多关系",{"2":{"175":1}}],["以及实时渲染",{"2":{"168":1}}],["以及系统支持的",{"2":{"161":1}}],["以及使用",{"2":{"153":1}}],["以及重载由",{"2":{"152":1}}],["以及",{"2":{"14":1,"156":1,"177":1}}],["especially",{"2":{"392":1}}],["es",{"2":{"391":1}}],["empty",{"2":{"392":1}}],["email",{"2":{"383":2}}],["emoji",{"0":{"288":1},"2":{"288":1}}],["epoll",{"2":{"323":1}}],["eraser",{"2":{"183":1}}],["errordomain",{"2":{"198":2}}],["errorwithdomain",{"2":{"198":1}}],["errorptr",{"2":{"198":2}}],["error",{"2":{"61":4,"66":1,"74":1,"79":1,"90":4,"92":2,"95":1,"98":1,"139":1,"151":4,"190":1,"194":1,"195":3,"196":10,"197":1,"198":1,"200":13,"208":1,"252":1,"299":4,"395":1}}],["e8",{"2":{"155":1}}],["e9",{"2":{"155":1}}],["ecuador",{"2":{"205":3}}],["ecmascript",{"2":{"97":2}}],["echo",{"2":{"95":33}}],["evaluatejavascript",{"2":{"92":1}}],["evaluation",{"2":{"88":1}}],["equation",{"2":{"304":2}}],["equations",{"2":{"304":2}}],["equatable",{"2":{"213":2,"218":1}}],["equals",{"2":{"90":2}}],["equal",{"2":{"53":3,"227":1}}],["equiv=",{"2":{"90":1}}],["e1",{"2":{"90":1}}],["e",{"2":{"90":4,"95":1,"103":3,"110":2,"304":8,"383":1}}],["either",{"2":{"86":1}}],["e6",{"2":{"86":1,"155":1}}],["e5",{"2":{"86":1,"155":1}}],["e7",{"2":{"86":1,"155":1}}],["each",{"2":{"86":1}}],["edu",{"2":{"83":2}}],["editor",{"2":{"392":3}}],["edit",{"2":{"14":1}}],["ef",{"2":{"59":1}}],["else",{"2":{"36":1,"46":1,"50":1,"53":1,"59":7,"61":2,"66":1,"67":4,"73":1,"74":2,"79":3,"90":5,"95":3,"135":1,"143":1,"198":2,"204":3,"208":2,"215":1,"258":2,"397":1}}],["env",{"2":{"116":1}}],["enum枚举声明",{"2":{"252":1}}],["enum宏声明的",{"2":{"218":1}}],["enum宏标注的",{"2":{"218":1}}],["enum或ns",{"2":{"218":1}}],["enum",{"2":{"90":1,"152":1,"200":2,"213":13,"218":2,"252":2,"255":1,"372":2}}],["entire",{"2":{"86":1}}],["enterprise",{"2":{"95":2}}],["enter",{"2":{"61":3,"95":3,"392":2}}],["encodable",{"2":{"205":1}}],["encodestr",{"2":{"86":3}}],["encoded",{"2":{"86":2}}],["encode",{"2":{"86":3}}],["encoding=",{"2":{"94":1}}],["encoding",{"2":{"86":1,"205":1}}],["encrypt",{"2":{"57":1}}],["endian",{"2":{"350":3}}],["endif",{"2":{"46":2,"50":2,"397":1}}],["endregion",{"2":{"301":1}}],["endlinewithlinefeed",{"2":{"219":1}}],["end宏",{"2":{"142":1}}],["ends",{"2":{"86":1}}],["end",{"2":{"59":2,"90":3,"142":1,"143":1,"145":3,"151":1,"176":2,"245":1,"249":1,"251":2,"257":1,"258":1}}],["enabled",{"2":{"232":1}}],["enabled和cf",{"2":{"188":1}}],["enable",{"2":{"27":1}}],["en",{"2":{"27":1,"66":1,"90":1,"94":1,"286":1}}],["extern",{"2":{"217":1}}],["extensible",{"2":{"213":7}}],["extensions",{"2":{"275":1,"278":1}}],["extension",{"0":{"275":1},"1":{"276":1,"277":1,"278":1},"2":{"145":1}}],["extends",{"2":{"120":1}}],["expr",{"2":{"396":1}}],["expression",{"2":{"111":1}}],["explain",{"2":{"392":1}}],["expirations",{"2":{"185":2}}],["experimental",{"2":{"103":1}}],["exportipapath",{"2":{"95":3}}],["exportipapath=$",{"2":{"95":1}}],["exportpath",{"2":{"95":1}}],["exportarchive",{"2":{"95":1}}],["exportappstore",{"2":{"95":1}}],["exportoptionsplistpath",{"2":{"95":1}}],["exportoptionsplistpath=$",{"2":{"95":3}}],["exportoptionsplist",{"2":{"95":1}}],["exportoptions",{"2":{"94":1,"95":2}}],["export",{"2":{"4":2,"23":6,"95":2,"276":1,"292":1,"293":1,"295":1,"296":3,"297":1,"298":1,"299":1,"301":1,"302":4,"306":1}}],["exists",{"2":{"196":1}}],["exit",{"2":{"95":4,"395":1}}],["exif",{"2":{"36":8}}],["example",{"2":{"86":5,"198":1,"329":1}}],["examples",{"0":{"268":1,"275":1},"1":{"269":1,"270":1,"271":1,"272":1,"273":1,"276":1,"277":1,"278":1},"2":{"2":1}}],["exchangeimplementations",{"2":{"153":1}}],["exception",{"2":{"74":1,"90":6,"199":1}}],["exclusivegram",{"2":{"67":1}}],["页面后缀",{"0":{"284":1}}],["页面的网址",{"2":{"66":1}}],["页面",{"2":{"14":1}}],["备注",{"2":{"14":1,"67":1,"92":1}}],["此时鼠标悬停时显示的文字是图片的title",{"2":{"330":1}}],["此时实例本身已被完全初始化",{"2":{"194":1}}],["此语法同时支持行高亮",{"2":{"301":1}}],["此数据将可用于页面的其余部分",{"2":{"286":1}}],["此头文件不是上小节描述的",{"2":{"240":1}}],["此方法的最后一个参数是",{"2":{"198":1}}],["此方法成功或是失败可以通过是否返回",{"2":{"197":1}}],["此外",{"2":{"196":1,"283":1,"292":1,"297":1}}],["此处的",{"2":{"243":1}}],["此处的uitableview和uitextfield对象和你在",{"2":{"133":1}}],["此处成功导出p12推送证书",{"2":{"14":1}}],["此密码用于其他人员读取p12文件时使用",{"2":{"14":1}}],["允许",{"2":{"14":1}}],["证书是否过期",{"2":{"371":1}}],["证书就生成完毕",{"2":{"14":1}}],["证书助理",{"2":{"14":1}}],["选项来进一步自定义",{"2":{"306":1}}],["选项配置",{"2":{"289":1}}],["选项配置锚点的渲染",{"2":{"280":1}}],["选项集类似于",{"2":{"219":1}}],["选项集用一个遵守optionset协议的结构体表示",{"2":{"219":1}}],["选项集的声明如下",{"2":{"219":1}}],["选项集会像枚举一样把前缀移除",{"2":{"219":1}}],["选项集",{"0":{"219":1},"2":{"210":1,"219":1}}],["选项卡中的",{"2":{"27":1}}],["选定的数据大小的阈值是",{"2":{"44":1}}],["选取",{"2":{"14":1}}],["选择一个commit",{"2":{"386":1}}],["选择file",{"2":{"159":1,"231":1}}],["选择器用selector结构体表示",{"2":{"154":1}}],["选择器是一种用于引用",{"2":{"154":1}}],["选择器语法",{"2":{"152":1}}],["选择器的所有部分在调用时都必须写上",{"2":{"137":1}}],["选择器的其余部分作为相应的参数名",{"2":{"137":1}}],["选择器的第一部分将会成为基本方法名并出现在圆括号的前面",{"2":{"137":1}}],["选择器",{"0":{"154":1},"1":{"155":1},"2":{"66":1,"132":1,"156":1,"202":1}}],["选择支持的最低版本",{"2":{"26":1}}],["选择对应的app",{"2":{"14":1}}],["选择导出",{"2":{"14":1}}],["选择存储位置",{"2":{"14":2}}],["选择存储到磁盘",{"2":{"14":1}}],["选择需要更新的app",{"2":{"14":1}}],["选择",{"2":{"14":1,"111":1}}],["选择证书的适用的场景",{"2":{"14":1}}],["选择右上角的新建+",{"2":{"14":1}}],["找到我",{"2":{"322":1}}],["找到已过期的的描述文件",{"2":{"14":1}}],["找到已过期或者即将过期的",{"2":{"13":1}}],["找到之前创建的csr文件",{"2":{"14":1}}],["钥匙串访问",{"2":{"14":3}}],["下次再试",{"2":{"372":1}}],["下午好",{"2":{"321":1}}],["下的index文件中的一个标题上",{"2":{"283":1}}],["下的",{"2":{"283":1}}],["下的certificates",{"2":{"14":1}}],["下划线",{"2":{"259":1}}],["下图展示了同时使用两种语言时",{"2":{"236":1}}],["下标",{"2":{"176":1,"250":1}}],["下标和构造器",{"2":{"151":1}}],["下面我要告诉你的是",{"2":{"350":1}}],["下面我们按照步骤创建csr",{"2":{"14":1}}],["下面描述的流程适用于非框架类型的",{"2":{"237":1}}],["下面是个未使用ns",{"2":{"218":1}}],["下面是一个",{"2":{"147":1}}],["下面的例子展示了使用",{"2":{"200":1}}],["下面的例子中",{"2":{"167":1}}],["下面的代码阐明了这个过程",{"2":{"193":1}}],["下面的",{"2":{"169":1}}],["下面这句代码将抛出异常",{"2":{"155":1}}],["下面这句代码不会导致编译错误",{"2":{"155":1}}],["下面这个例子为cgrect结构增加了一个叫area的计算型属性",{"2":{"146":1}}],["下面示例的创建",{"2":{"83":1}}],["下拉取消回弹效果",{"0":{"77":1}}],["下增加如下内容",{"2":{"23":1}}],["下载远程仓库的所有变动",{"2":{"389":1}}],["下载一个项目和它的整个代码历史",{"2":{"382":1}}],["下载旧版本的",{"2":{"27":1}}],["下载问题",{"0":{"16":1}}],["下载完毕后会得到一个aps",{"2":{"14":1}}],["下载到本地磁盘",{"2":{"14":1}}],["下载",{"2":{"4":1,"23":1,"71":1}}],["带行号",{"2":{"301":1}}],["带行高亮",{"2":{"301":1}}],["带有内置的",{"2":{"279":1}}],["带apple",{"2":{"14":1}}],["带推送的",{"2":{"14":1}}],["也就意味着第3步的完成",{"2":{"372":1}}],["也就是需要加上应用的名字",{"2":{"167":1}}],["也就是发送请求的时候",{"2":{"92":1}}],["也就是ios",{"2":{"50":1}}],["也能实现换行效果",{"2":{"324":1}}],["也适合做一篇文章的tag",{"2":{"323":1}}],["也无法在编译期访问它们",{"2":{"245":1}}],["也提供了多种指针类型以供直接操作内存",{"2":{"223":1}}],["也会在set类型和nsset类之间桥接",{"2":{"184":1}}],["也会将一些",{"2":{"177":1}}],["也会自动调用该类父类中的dealloc方法",{"2":{"166":1}}],["也可使用",{"2":{"168":1}}],["也可以提供定制的代码组",{"2":{"302":1}}],["也可以像这样在大括号内",{"2":{"301":1}}],["也可以直接用于元素",{"2":{"293":1}}],["也可以为产品模块名提供一个自定义的名称",{"2":{"259":1}}],["也可以传递一个泛型类型的闭包属性或者泛型方法",{"2":{"227":1}}],["也可以传递闭包字面量",{"2":{"227":1}}],["也可以定义具有匿名类型的字段",{"2":{"222":1}}],["也可以调用默认构造器",{"2":{"219":1}}],["也可以双击",{"2":{"209":1}}],["也可以对一个非托管对象使用retain",{"2":{"189":1}}],["也可以使用终端通过编程的方式打开应用程序",{"2":{"209":1}}],["也可以使用as",{"2":{"204":1}}],["也可以使用",{"2":{"163":1,"296":1,"301":1,"303":1}}],["也可以在代码组中导入代码片段",{"2":{"302":1}}],["也可以在",{"2":{"157":1}}],["也可以省略类型",{"2":{"133":1}}],["也可以作为函数b的返回值",{"2":{"25":1}}],["也可以等于其他值",{"2":{"9":1}}],["也称为快速应用切换",{"2":{"63":1}}],["也很容易实现",{"2":{"44":1}}],["也即是上线",{"2":{"14":1}}],["环境来使用",{"2":{"157":1}}],["环境",{"0":{"158":1},"1":{"159":1,"160":1},"2":{"14":1,"157":1}}],["如",{"2":{"326":1,"359":1}}],["如何将接口导入到",{"2":{"248":1}}],["如何导入它",{"2":{"144":1}}],["如同",{"2":{"227":1}}],["如上例子在",{"2":{"208":1}}],["如前文错误处理中所述",{"2":{"199":1}}],["如比较8",{"2":{"53":1}}],["如来电",{"2":{"37":1}}],["如程序启动和关闭",{"2":{"37":1}}],["如下表格使用type作为类型名称的占位符来表示相应的映射语法",{"2":{"223":1}}],["如下示例展示了如何为",{"2":{"258":1}}],["如下示例展示了如何在",{"2":{"200":1,"258":3}}],["如下示例代码演示了如何在",{"2":{"215":1}}],["如下是使用as",{"2":{"204":1}}],["如下列所示",{"2":{"151":1}}],["如下列子",{"2":{"61":1}}],["如下代码演示了如何编写一个表示食品杂货店商品的",{"2":{"205":1}}],["如下代码展示了",{"2":{"144":1}}],["如下代码展示了string",{"2":{"143":1}}],["如下代码在编译时没有任何编译警告",{"2":{"141":1}}],["如下代码设置了uitextfield对象的textcolor和text属性",{"2":{"136":1}}],["如下所示",{"2":{"53":1,"205":1}}],["如下",{"2":{"26":1,"144":2}}],["如下图所示",{"2":{"14":2}}],["如果代码没有任何新变化",{"2":{"385":1}}],["如果服务器要求客户的身份认证",{"2":{"371":1}}],["如果合法验证通过",{"2":{"371":1}}],["如果合法验证没有通过",{"2":{"371":1}}],["如果引用其他github仓库中的图片要注意格式",{"2":{"326":1}}],["如果引用本仓库中的图片",{"2":{"326":1}}],["如果指定的文件不存在",{"2":{"303":1}}],["如果指针的类型在",{"2":{"223":1}}],["如果无法从文件扩展名推测出源语言",{"2":{"301":1}}],["如果不需要",{"2":{"371":1}}],["如果不是用英语书写",{"2":{"292":1}}],["如果不能推断任何约定",{"2":{"195":1}}],["如果产品名以数字开头",{"2":{"259":1}}],["如果产品名包含特殊字符",{"2":{"259":1}}],["如果产生错误的",{"2":{"195":2}}],["如果需要自定义枚举值的名称",{"2":{"255":1}}],["如果需要在",{"2":{"231":1}}],["如果这个头文件中的",{"2":{"240":1}}],["如果这种类型必须符合hashable协议",{"2":{"150":1}}],["如果应用程序的",{"2":{"240":1}}],["如果应用程序在版本低于ios",{"2":{"208":1}}],["如果为",{"2":{"233":1}}],["如果想为",{"2":{"231":1}}],["如果想要立即生效",{"2":{"23":1}}],["如果函数接受autoreleasingunsafemutablepointer",{"2":{"226":1}}],["如果函数接受unsafemutablerawpointer参数",{"2":{"225":1}}],["如果函数接受unsafemutablepointer",{"2":{"225":1}}],["如果函数接受unsaferawpointer参数",{"2":{"224":1}}],["如果函数接受unsafepointer",{"2":{"224":1}}],["如果定义了一个类似下面这样的函数",{"2":{"224":2,"225":2,"226":1}}],["如果type是int8或者uint8",{"2":{"224":1}}],["如果所有被导入的结构体成员都有默认值",{"2":{"216":1}}],["如果该方法在",{"2":{"198":2}}],["如果该方法无法使用文档的常规文件内容来创建对象",{"2":{"198":1}}],["如果该类有父类的话",{"2":{"165":1}}],["如果在",{"2":{"260":1}}],["如果在初始化的基础上还需要进行额外的设置",{"2":{"203":1}}],["如果在一个",{"2":{"198":2}}],["如果在提示不能删除itunes",{"2":{"27":1}}],["如果简化后的方法名会和其他方法名冲突",{"2":{"195":1}}],["如果存在",{"2":{"195":1}}],["如果还需在初始化的基础上进行额外的设置",{"2":{"194":1}}],["如果属性的初始化过程十分复杂或者代价昂贵",{"2":{"194":1}}],["如果步骤1和步骤2的检查顺利通过",{"2":{"193":1}}],["如果只调用那些带有内存管理标注并且不会间接返回",{"2":{"188":1}}],["如果自定义的",{"2":{"188":1}}],["如果先将",{"2":{"186":1}}],["如果从故事版或者xib文件实例化对象",{"2":{"169":1}}],["如果希望在对象释放前进行额外的清理工作",{"2":{"166":1}}],["如果有一个或者多个自定义的构造器或者有不具有默认初始值的属性",{"2":{"164":1}}],["如果要覆盖父类中的实现",{"2":{"163":1}}],["如果要为",{"2":{"152":1}}],["如果一个惰性属性还未被初始化就被多个线程同时访问",{"2":{"194":1}}],["如果一个类型不会以此种方式实例化时",{"2":{"164":1}}],["如果一个类型没有任何为空性标注",{"2":{"142":1}}],["如果一个",{"2":{"152":1}}],["如果nsset对象没有使用轻量泛型",{"2":{"184":1}}],["如果nsset中的元素没有类型限定",{"2":{"150":1}}],["如果nsarray对象没有使用轻量泛型",{"2":{"183":1}}],["如果nsdictionary对象没有使用轻量泛型",{"2":{"185":1}}],["如果nsdictionary或nsset对其键或元素的类型做了参数化",{"2":{"150":1}}],["如果nsdictionary的键类型不带有类限定",{"2":{"150":1}}],["如果块捕获了self",{"2":{"148":1}}],["如果协议是在",{"2":{"146":1}}],["如果未特别指定类型限定",{"2":{"145":1}}],["如果未安装",{"2":{"63":1}}],["如果带有协议限定",{"2":{"145":1}}],["如果",{"2":{"145":1,"151":3,"152":1,"195":2,"198":1,"240":1,"254":2}}],["如果可选值的值为nil",{"2":{"143":1}}],["如果是变量",{"2":{"140":1}}],["如果是被用户自己中断的那么直接断开连接",{"2":{"90":1}}],["如果确信对象的类型",{"2":{"139":1}}],["如果其具体类型已知或者可以断定",{"2":{"139":1}}],["如果调用一个无参数的方法",{"2":{"137":1}}],["如果初始化不会失败",{"2":{"135":1}}],["如果构造器接收参数",{"2":{"133":1}}],["如果它接收参数",{"2":{"133":1}}],["如果你需要使用原本的",{"2":{"179":1}}],["如果你想和其他javascript框架一起使用",{"2":{"124":1}}],["如果你使用的是zsh",{"2":{"23":1}}],["如果网络通的话",{"2":{"90":1}}],["如果发现第三方库没有安装",{"2":{"84":1}}],["如果运行失败",{"2":{"84":1}}],["如果安装下载速度过慢",{"2":{"82":1}}],["如果安装了原生",{"2":{"63":1}}],["如果使用的是servertrust方式",{"2":{"372":1}}],["如果使用session创建的task进行网络访问",{"2":{"372":1}}],["如果使用框架",{"2":{"260":1}}],["如果使用以上命令报错",{"2":{"116":1}}],["如果使用",{"2":{"63":1,"260":1}}],["如果用户没登录twitter账号",{"2":{"74":1}}],["如果用户想要分享开放图谱动态",{"2":{"63":1}}],["如果用户安装了",{"2":{"63":1}}],["如果做的事包含block任务",{"2":{"61":1}}],["如果选择创建",{"2":{"238":1}}],["如果选择",{"2":{"50":1}}],["如果低于ios9",{"2":{"50":1}}],["如果数据还未同步时程序挂掉",{"2":{"44":1}}],["如果显示为默认源",{"2":{"20":1}}],["如果下载的队列为",{"2":{"16":1}}],["如果下载的delegate队列为",{"2":{"16":1}}],["如遇到native与js交互的时候",{"2":{"8":1}}],["中午好",{"2":{"321":1}}],["中添加相同的可用性信息",{"2":{"258":1}}],["中都有提供",{"2":{"258":1}}],["中为特定平台编译应用时",{"2":{"258":1}}],["中为bundle",{"2":{"13":1}}],["中通过扩展提供一个优雅的",{"2":{"257":1}}],["中通过如下两步实现键值观察",{"2":{"201":1}}],["中能使用哪些",{"2":{"248":1}}],["中任何标记internal修饰符的声明",{"2":{"240":1}}],["中有",{"2":{"240":1}}],["中所有",{"2":{"239":1,"244":1}}],["中所有的类都是全局命名空间的一部分",{"2":{"167":1}}],["中将",{"0":{"239":1,"241":1,"244":1,"246":1}}],["中将保持其原子性",{"2":{"136":1}}],["中移除相关的",{"2":{"234":1}}],["中移除",{"2":{"233":1}}],["中移除之前立刻被调用",{"2":{"124":1}}],["中导入",{"2":{"251":1}}],["中导入应用程序的",{"2":{"240":1}}],["中导入一系列",{"2":{"238":1}}],["中导入代码的基本原理",{"2":{"236":1}}],["中导入代码",{"0":{"237":1,"242":1},"1":{"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1},"2":{"235":2}}],["中导入代码小节",{"2":{"231":1,"233":1}}],["中导入的类中的方法",{"2":{"152":1}}],["中无法表示",{"2":{"223":1}}],["中你可以像下面这样做",{"2":{"197":1}}],["中等效的代码如下所示",{"2":{"196":1}}],["中等价的构造器声明如下所示",{"2":{"133":1}}],["中会产生错误的方法转换为根据",{"2":{"195":1}}],["中可以定义能让",{"2":{"176":1}}],["中可用并且没有任何命名空间",{"2":{"152":1}}],["中打开",{"2":{"175":1}}],["中配置一个nsmanagedobject的子类供",{"2":{"175":1}}],["中查看",{"2":{"170":1}}],["中对自定义视图进行交互式设计",{"2":{"170":1}}],["中声明一个",{"2":{"169":1}}],["中id",{"2":{"165":2}}],["中耳熟能详的既有特性来编写",{"2":{"162":1}}],["中相对应的概念",{"2":{"161":1}}],["中呈现",{"2":{"161":1}}],["中创建一个",{"0":{"159":1}}],["中访问应用程序的",{"2":{"240":1}}],["中访问",{"2":{"158":1}}],["中调用+collectionwithvalues",{"2":{"256":1}}],["中调用vasprintf函数",{"2":{"215":1}}],["中调用",{"2":{"198":2}}],["中调用方法时如何处理错误",{"2":{"196":1}}],["中调用这些",{"2":{"153":1}}],["中调用的",{"2":{"153":1}}],["中被重写后",{"2":{"152":1}}],["中被一个或多个协议限定的类会作为协议组合类型导入到",{"2":{"144":1}}],["中不是必须的",{"2":{"231":1}}],["中不存在的语言特性",{"2":{"161":1}}],["中不可用",{"0":{"256":1},"2":{"152":1,"235":1}}],["中不支持的字符",{"2":{"152":1}}],["中抛出错误的方法会成为接受nserror",{"2":{"151":1}}],["中具有平台适应性的整数类型",{"2":{"182":1}}],["中具有class特性的属性",{"2":{"151":1}}],["中具有原子性的属性在",{"2":{"136":1}}],["中直接使用",{"2":{"151":1}}],["中继承一个",{"2":{"151":1}}],["中继承",{"2":{"151":1,"230":1,"234":1}}],["中未指定的类型或id类型时",{"2":{"150":1}}],["中如下所示",{"2":{"147":1,"208":1}}],["中定义的类",{"2":{"192":1}}],["中定义的",{"2":{"146":3}}],["中文版",{"2":{"142":1,"148":1,"153":1,"166":2,"172":1,"173":1,"174":1,"194":1,"203":1,"204":2,"227":1,"232":1,"240":1,"245":1,"258":1,"260":1}}],["中称为nil",{"2":{"142":1}}],["中使用这部分",{"2":{"260":1}}],["中使用这些设计模式",{"2":{"192":1}}],["中使用相同的可用性信息",{"2":{"258":1}}],["中使用的",{"0":{"252":1},"2":{"235":1}}],["中使用目标",{"2":{"202":1}}],["中使用该自定义错误类型生成错误",{"2":{"200":1}}],["中使用起来更加自然",{"2":{"177":1}}],["中使用点语法调用方法",{"2":{"137":1}}],["中使用点语法对属性进行存取",{"2":{"136":1}}],["中使用",{"0":{"248":1},"1":{"249":1,"250":1,"251":1,"252":1},"2":{"136":2,"157":2,"231":1,"234":2,"235":1,"241":2,"246":2,"248":1,"260":2}}],["中实例化的一样",{"2":{"133":1}}],["中实例化一个",{"2":{"133":1}}],["中兴通讯",{"2":{"113":1}}],["中引入刚才创建的服务",{"2":{"113":1}}],["中",{"2":{"44":1,"155":1,"161":1,"167":1,"195":1,"197":2,"198":1,"199":2,"205":2,"231":1}}],["中的头文件路径是头文件自身相对于项目的路径",{"2":{"260":1}}],["中的普通方法",{"2":{"257":1}}],["中的外部框架",{"2":{"247":1}}],["中的访问控制章节",{"2":{"240":1,"245":1,"260":1}}],["中的一些",{"2":{"240":1,"241":1,"246":1}}],["中的一些内建结构体可以和nsvalue桥接",{"2":{"191":1}}],["中的命名更改为isenabled",{"2":{"232":1}}],["中的nsdecimal类型",{"2":{"221":1}}],["中的应用程序图标",{"2":{"209":1}}],["中的全限定名是myframework",{"2":{"167":1}}],["中的替代类型",{"2":{"161":1}}],["中的同等类型",{"2":{"161":1}}],["中的类名",{"2":{"231":2}}],["中的类经常会声明一些枚举和常量类型",{"2":{"180":1}}],["中的类",{"2":{"161":1}}],["中的类工厂方法被导入为",{"2":{"134":1}}],["中的声明特性部分",{"2":{"153":1,"258":1}}],["中的可变参数函数",{"2":{"215":1}}],["中的可变参数",{"2":{"152":1}}],["中的别名",{"2":{"152":1}}],["中的协议限定元类会作为协议元类导入到",{"2":{"144":1}}],["中的any类型导入",{"2":{"138":1}}],["中的id类型会作为",{"2":{"138":1}}],["中的属性或方法提供",{"2":{"232":1}}],["中的属性章节",{"2":{"232":1}}],["中的属性",{"2":{"136":1}}],["中的实例方法",{"2":{"136":1}}],["中的便利构造器",{"2":{"134":1}}],["中的接口",{"0":{"152":1},"2":{"132":1}}],["中的debug环境",{"2":{"14":1}}],["中的",{"2":{"14":2,"142":1,"148":1,"166":2,"169":1,"172":1,"173":1,"174":1,"179":1,"180":1,"189":1,"194":1,"198":1,"199":1,"200":1,"203":1,"204":2,"231":1,"241":1,"243":1,"245":1,"246":1,"306":1}}],["将设个含有签名的随机数和客户自己的证书也传给服务器",{"2":{"371":1}}],["将继续进行第四步",{"2":{"371":1}}],["将用户锚定到目录",{"2":{"283":1}}],["将用户导航至目录",{"2":{"283":1}}],["将用户导航至根目录下的",{"2":{"283":1}}],["将可用性信息添加到",{"0":{"258":1},"2":{"235":1}}],["将可选值桥接为",{"0":{"143":1},"2":{"132":1}}],["将原始的",{"2":{"233":1}}],["将复杂宏声明为函数",{"2":{"232":1}}],["将简单宏声明为全局常量",{"2":{"232":1}}],["将作为该数组的起始指针传入",{"2":{"225":1}}],["将作为该数组的起始指针传递给函数",{"2":{"224":1}}],["将这些",{"2":{"217":1}}],["将这些返回的",{"2":{"189":1}}],["将返回值赋值给名为fullscreensize的常量",{"2":{"193":1}}],["将错误转换为可选值",{"0":{"197":1},"2":{"192":1}}],["将常量或者变量声明为nsdictionary类型",{"2":{"185":1}}],["将常量或者变量声明为nsset类型",{"2":{"184":1}}],["将常量或变量声明为nsarray类型并为其赋值数组字面量时",{"2":{"183":1}}],["将会创建nsdictionary对象",{"2":{"185":1}}],["将会创建nsset对象",{"2":{"184":1}}],["将会创建nsarray对象",{"2":{"183":1}}],["将会失败并返回",{"2":{"182":1}}],["将表示数字500的",{"2":{"182":1}}],["将其初始化为git代码库",{"2":{"382":1}}],["将其转换为独立于体系结构的数据形式",{"2":{"205":1}}],["将其转换为",{"2":{"182":1}}],["将其向下转换到具体类型往往会更有用处",{"2":{"139":1}}],["将通过不同的方式指明这些属性特性",{"2":{"171":1}}],["将自定义的视图添加到",{"2":{"170":1}}],["将自动检查设备上是否安装了原生",{"2":{"63":1}}],["将在画布上实时渲染自定义视图",{"2":{"170":1}}],["将对象转换为anyobject类型",{"2":{"155":1}}],["将属性名加上getter",{"2":{"154":1}}],["将方法名传入即可",{"2":{"154":1}}],["将触发一个运行时错误",{"2":{"139":1}}],["将xxx替换成自己的fir平台的token",{"2":{"95":1}}],["将xxx替换成自己的工程的sheme名",{"2":{"95":1}}],["将xxx替换成自己的工程名",{"2":{"95":1}}],["将视图显示在最前方",{"0":{"76":1}}],["将",{"0":{"139":1,"238":1,"240":1,"243":1,"245":1},"1":{"239":1,"241":1,"244":1,"246":1},"2":{"64":2,"66":1,"95":1,"132":1,"214":1,"216":1,"220":1,"227":1,"233":1,"235":4,"240":1,"241":1,"248":1,"250":1,"260":2}}],["将以下",{"2":{"64":1}}],["将文件映射到内存",{"2":{"44":1}}],["将不会被加载",{"2":{"23":1}}],["将1",{"2":{"14":1}}],["将请求下来的的csr证书保存在桌面上",{"2":{"14":1}}],["将该",{"2":{"13":1}}],["将中文参数传送过来时",{"2":{"3":1}}],["示例代码",{"2":{"67":1}}],["示例就以生产中带推送的做参考",{"2":{"14":1}}],["示例",{"0":{"12":1},"1":{"13":1,"14":1},"2":{"14":1,"23":1,"66":1}}],["python",{"2":{"337":1,"338":1}}],["pm",{"2":{"304":2}}],["p27",{"0":{"350":1}}],["p2",{"2":{"227":1}}],["p1",{"2":{"227":1}}],["p12",{"2":{"14":2}}],["p12文件",{"2":{"14":1}}],["p后面的xxx替换成自己的密码",{"2":{"95":1}}],["pwdinputvc",{"2":{"391":1}}],["pwd",{"2":{"95":1}}],["p",{"2":{"95":3,"224":2,"225":2,"226":1,"227":1,"384":1}}],["pencil",{"2":{"183":1}}],["people",{"2":{"176":3}}],["peopleids",{"2":{"66":1}}],["pet",{"2":{"88":1}}],["permalink",{"2":{"306":2}}],["perm=true",{"2":{"116":3}}],["personal",{"2":{"391":7}}],["personnamecomponents",{"2":{"179":1}}],["person",{"2":{"156":13,"167":1,"175":3,"176":8}}],["performselector",{"2":{"155":1}}],["perform",{"2":{"155":1}}],["performance",{"2":{"88":1}}],["per",{"2":{"90":1}}],["percent",{"2":{"86":4}}],["po",{"2":{"396":1}}],["powered",{"2":{"276":1}}],["pon",{"2":{"90":1}}],["pong",{"2":{"90":4}}],["pongmessage",{"2":{"90":2}}],["pongpayload",{"2":{"90":1}}],["pod",{"2":{"83":2,"84":1}}],["point2d",{"2":{"214":6}}],["points",{"2":{"205":6}}],["point",{"2":{"77":3}}],["postcssisolatestyles",{"2":{"293":2}}],["postcss",{"2":{"293":3}}],["postwebrequest",{"2":{"92":2}}],["post",{"2":{"66":1,"70":1,"92":4,"129":1}}],["phases",{"2":{"395":1}}],["phase",{"2":{"71":1}}],["photo",{"2":{"64":2,"67":2}}],["photoshop",{"2":{"44":1}}],["plus",{"2":{"397":1}}],["plugin",{"2":{"306":2}}],["plugins",{"2":{"293":1}}],["play",{"2":{"151":1}}],["playsong",{"2":{"151":2}}],["place",{"2":{"95":2,"185":3}}],["placeid",{"2":{"66":1}}],["please",{"2":{"143":2,"392":1}}],["plist在build",{"2":{"239":1}}],["plist里提供nsdocument子类的类名",{"2":{"167":1}}],["plist>",{"2":{"94":1}}],["plist添加访问权限",{"2":{"74":1}}],["plist中",{"2":{"74":1}}],["plist",{"0":{"64":1},"2":{"64":1,"71":1,"94":4,"95":3,"190":1}}],["plist文件所在路径",{"2":{"95":1}}],["plist文件",{"2":{"42":1}}],["primeng",{"2":{"113":1}}],["prints",{"2":{"200":1,"205":1}}],["printstacktrace",{"2":{"90":4}}],["print",{"2":{"139":1,"141":1,"154":1,"155":1,"169":1,"181":1,"193":1,"196":3,"200":2,"201":1,"205":1,"206":2,"209":1,"215":1,"220":2,"222":3,"245":1}}],["println",{"2":{"90":9}}],["pragma",{"2":{"90":1}}],["prd",{"2":{"88":1}}],["preprocessor",{"0":{"397":1},"2":{"397":1}}],["preferredauthentications",{"2":{"380":2}}],["preferredstyle",{"2":{"79":1}}],["prefix",{"2":{"293":1}}],["pre>",{"2":{"268":6}}],["predicate",{"2":{"184":2}}],["preset",{"2":{"116":1}}],["present",{"2":{"397":1}}],["presentviewcontroller",{"2":{"73":1,"79":1}}],["presentopeninmenufromrect",{"2":{"67":3,"79":1}}],["presented",{"2":{"59":1}}],["presentedviewcontroller",{"2":{"59":2}}],["precedes",{"2":{"86":1}}],["pretty",{"2":{"46":1}}],["pro",{"2":{"397":2}}],["pro=1",{"2":{"397":1}}],["process",{"2":{"392":1}}],["processinfo的arguments属性",{"2":{"209":1}}],["processinfo",{"2":{"53":1}}],["protectionspace它代表着对需要验证的受保护空间的验证",{"2":{"372":1}}],["protocol",{"2":{"32":1,"176":1,"249":1,"250":1}}],["provides",{"2":{"276":1}}],["provided",{"2":{"268":1,"275":1}}],["provisioning",{"2":{"14":5}}],["programming",{"2":{"142":1,"148":1,"153":1,"166":2,"172":1,"173":1,"174":1,"189":1,"194":1,"199":1,"203":1,"204":2,"207":1,"227":1,"232":1,"240":1,"245":1,"258":1,"260":1}}],["progress",{"2":{"61":1}}],["proportional",{"2":{"304":2}}],["proposedsize",{"2":{"193":2}}],["prop",{"2":{"124":1}}],["props",{"0":{"121":1},"2":{"120":3}}],["property声明的属性才会导入为",{"2":{"136":1}}],["property语法声明的属性会以如下方式导入到",{"2":{"136":1}}],["propertylistdecoder",{"2":{"205":1}}],["propertylistencoder",{"2":{"205":1}}],["propertylist",{"2":{"94":1}}],["property",{"2":{"78":1,"86":1,"90":4,"142":3,"144":1,"145":3,"150":4,"151":4,"176":1,"183":2,"184":2,"185":2,"194":1}}],["propertyname",{"2":{"78":1}}],["promise",{"2":{"113":1}}],["prompt",{"2":{"98":1}}],["project",{"2":{"95":11,"103":3,"159":1,"252":2,"382":1,"395":1,"396":2}}],["projectname>",{"2":{"21":3,"106":3}}],["productname",{"2":{"246":3}}],["productmodulename",{"2":{"233":1,"241":3,"246":3,"251":1}}],["product",{"2":{"61":1,"175":1,"214":2,"259":1,"260":1}}],["products",{"2":{"26":3}}],["production",{"2":{"14":3,"88":1}}],["production可以看到所有的生产环境的证书",{"2":{"14":1}}],["profile==",{"2":{"66":1}}],["profile",{"2":{"23":4,"329":1}}],["profiles",{"2":{"11":1,"14":6}}],["pdf",{"2":{"44":1}}],["psd",{"2":{"44":1}}],["png",{"2":{"44":2,"79":1,"109":1,"135":1,"330":1}}],["pthread",{"2":{"43":1}}],["pick",{"2":{"386":1}}],["ping",{"2":{"90":3}}],["pindiskcache",{"2":{"44":1}}],["pi",{"2":{"36":5,"304":4}}],["pull",{"0":{"391":1},"2":{"389":1,"392":1}}],["pub中的内容粘帖到公司gitlab服务器的ssh",{"2":{"380":1}}],["pub私钥和公钥",{"2":{"380":1}}],["publickey",{"2":{"380":2}}],["public",{"2":{"67":2,"90":2,"94":1,"113":1,"219":7,"250":1,"252":1}}],["publish",{"2":{"66":2,"95":1}}],["pub",{"2":{"23":2}}],["push`",{"2":{"391":1}}],["push|fetch>",{"2":{"391":1}}],["push",{"2":{"14":5,"386":1,"387":3,"389":6,"390":1,"391":4}}],["past",{"2":{"326":1}}],["past的定义",{"2":{"326":1}}],["pass",{"2":{"86":1}}],["passing",{"2":{"86":1}}],["password=",{"2":{"2":1}}],["password",{"2":{"2":1,"86":4,"92":1}}],["pakaging",{"2":{"247":1}}],["packaging",{"2":{"244":1,"246":1,"259":1,"260":1}}],["packages",{"2":{"306":1}}],["package",{"2":{"103":2,"129":1}}],["pageencoding=",{"2":{"90":1}}],["page",{"0":{"271":1,"272":1},"2":{"90":1,"268":7,"271":1,"275":1}}],["pages",{"2":{"1":1}}],["partial",{"2":{"304":8}}],["parts",{"2":{"86":1,"303":4}}],["part",{"2":{"86":1,"303":2}}],["park",{"2":{"66":2}}],["params",{"2":{"92":4}}],["parameters",{"2":{"66":1}}],["param",{"2":{"36":1,"92":2}}],["pattern",{"2":{"194":3}}],["patchversion",{"2":{"53":1}}],["pathforresource",{"2":{"67":1}}],["path",{"2":{"23":1,"86":6,"92":2,"95":8,"156":5,"194":1,"196":4,"206":4,"209":2}}],["path=",{"2":{"23":1,"86":1}}],["path=$",{"2":{"95":2}}],["path=$flutter",{"2":{"23":1}}],["path=$path",{"2":{"4":1}}],["pay的证书",{"2":{"14":1}}],["微信",{"2":{"9":1}}],["在合并远程代码的时候",{"0":{"392":1}}],["在现有分支与指定的远程分支之间",{"2":{"386":1}}],["在当前目录新建一个git代码库",{"2":{"382":1}}],["在当前线程中出了",{"2":{"16":1}}],["在浏览器端进行访问的时候就弹出一个要求输入账号和密码的弹窗",{"2":{"372":1}}],["在握手过程中可选",{"2":{"371":1}}],["在三个反引号```后面加上编程语言的名字",{"2":{"355":1}}],["在哪种字节顺序是合适的这个问题上",{"2":{"350":1}}],["在github的issue中使用该语法是可以实时点击复选框来勾选或解除勾选的",{"2":{"347":1}}],["在文末有code",{"2":{"326":1}}],["在链接一节有介绍",{"2":{"326":1}}],["在连续几行的文本开头加入1个tab或者4个空格",{"2":{"321":1}}],["在一行开头加入1个tab或者4个空格",{"2":{"319":1}}],["在一个产生错误的",{"2":{"195":1}}],["在一个叫mygreatapp的应用里",{"2":{"167":1}}],["在配置文件中设置markdown",{"2":{"304":1}}],["在某一行添加",{"2":{"298":1,"299":1}}],["在某一行上添加",{"2":{"297":1}}],["在某些情况下",{"2":{"152":1}}],["在代码块中实现行高亮",{"0":{"296":1}}],["在方法名前加双下划线",{"2":{"257":1}}],["在第一个外部参数名前加双下划线",{"2":{"257":1}}],["在第一次渲染后调用",{"2":{"124":1}}],["在保护伞头文件中导入希望暴露给",{"2":{"244":1}}],["在单元测试的",{"2":{"240":1}}],["在同一",{"2":{"236":1}}],["在框架",{"0":{"242":1},"1":{"243":1,"244":1,"245":1,"246":1},"2":{"235":1}}],["在应用程序",{"0":{"237":1},"1":{"238":1,"239":1,"240":1,"241":1},"2":{"235":1,"238":1}}],["在将",{"2":{"234":1}}],["在相关代码中请使用新的",{"2":{"233":1}}],["在需要的时候",{"2":{"232":1}}],["在开始前",{"2":{"229":1}}],["在开始迁移代码之前",{"2":{"229":1}}],["在开始学习这些特性前",{"2":{"157":1}}],["在决定哪些特性和功能用",{"2":{"228":1}}],["在如下这个",{"2":{"222":1}}],["在上述例子中",{"2":{"220":1}}],["在所有支持的平台上",{"2":{"215":1}}],["在控制台打印方法的返回值",{"2":{"193":1}}],["在控制台打印输出警告内容",{"2":{"98":1}}],["在控制台打印输出错误内容",{"2":{"98":1}}],["在控制台打印输出内容",{"2":{"98":1}}],["在向代理发送可能无法响应的消息之前",{"2":{"193":1}}],["在许多情况下",{"2":{"192":1}}],["在协议声明前添加",{"2":{"176":1}}],["在nsmanagedobject子类中",{"2":{"175":1}}],["在运行时",{"2":{"169":1}}],["在对象被释放前",{"2":{"166":1}}],["在编写基于混合语言的框架时",{"2":{"242":1}}],["在编写基于混合语言的应用程序时",{"2":{"237":1}}],["在编写",{"2":{"162":1}}],["在编译阶段就检查当前sdk编译与构建应用是否能使用某个api",{"2":{"50":1}}],["在你建立",{"2":{"161":1}}],["在接口和实现之间没有显式划分",{"2":{"159":1}}],["在使用这个功能的时候请保证内容按预期呈现",{"2":{"303":1}}],["在使用这个对象前",{"2":{"189":1}}],["在使用它之前",{"2":{"189":1}}],["在使用类似键值监听",{"2":{"153":1}}],["在使用的组件中导入",{"2":{"113":1}}],["在导入这个自动生成的头文件前",{"2":{"240":1}}],["在导入标注ns",{"2":{"219":1}}],["在导入",{"2":{"150":1,"180":1}}],["在导航栏中点击",{"2":{"14":1}}],["在下面的代码中",{"2":{"141":1}}],["在没有任何为空性标注的情况下",{"2":{"135":1}}],["在没有等待情况出现时",{"2":{"43":1}}],["在",{"0":{"152":1,"159":1,"239":1,"241":1,"244":1,"246":1,"248":1,"249":1,"251":1},"1":{"249":1,"250":1,"251":1,"252":1},"2":{"132":1,"133":2,"134":2,"135":2,"136":4,"137":3,"141":1,"142":3,"148":1,"149":1,"151":1,"153":1,"154":1,"156":3,"157":2,"161":1,"163":2,"165":1,"167":2,"168":1,"169":1,"170":3,"171":2,"172":1,"173":1,"174":1,"175":2,"176":1,"177":1,"186":1,"190":1,"191":1,"193":2,"194":2,"195":2,"196":2,"197":4,"198":2,"199":2,"202":1,"203":2,"204":2,"205":2,"206":1,"207":2,"208":2,"213":1,"215":1,"218":2,"219":3,"231":1,"235":3,"239":2,"241":1,"258":1,"260":1,"295":2,"380":1}}],["在捕获",{"0":{"148":1},"2":{"132":1}}],["在组件完成更新后立即调用",{"2":{"124":1}}],["在组件接收到新的props或者state时被调用",{"2":{"124":1}}],["在组件接收到一个新的",{"2":{"124":1}}],["在初始化时不会被调用",{"2":{"124":2}}],["在初始化时或者使用forceupdate时不被调用",{"2":{"124":1}}],["在客户端也在服务端",{"2":{"124":1}}],["在渲染前调用",{"2":{"124":1}}],["在angular",{"2":{"113":1}}],["在app目录下",{"2":{"21":1,"106":1}}],["在业务逻辑里面引入viewchild",{"2":{"113":1}}],["在dom中命名",{"2":{"113":1}}],["在页面书写内容",{"2":{"98":1}}],["在项目中同时使用",{"0":{"235":1},"1":{"236":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":1,"246":1,"247":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1},"2":{"159":1,"161":1,"264":1}}],["在项目工程相同的目录下创建",{"2":{"94":1,"95":1}}],["在项目文件夹",{"2":{"85":1}}],["在wkwebview中需要换种方式处理",{"2":{"92":1}}],["在wkwebview中设置的content",{"2":{"92":1}}],["在uiwebview中content",{"2":{"92":1}}],["在自己工程的podfile第一行加上",{"2":{"83":1}}],["在import语句前加上",{"2":{"240":1}}],["在info",{"2":{"74":1}}],["在ios8中",{"2":{"92":1}}],["在ios",{"2":{"8":1,"74":1}}],["在移动平台上",{"2":{"66":1}}],["在移动平台上分享",{"0":{"63":1},"1":{"64":1,"65":1,"66":1}}],["在手机系统从新启动时",{"2":{"39":1}}],["在后台时退出",{"2":{"37":1}}],["在主界面时让程序退出",{"2":{"37":1}}],["在这个方法中可以做一些保存当前程序数据",{"2":{"37":1}}],["在macos",{"2":{"209":1}}],["在mac应用程序中找到",{"2":{"14":1}}],["在main函数中进行的设置uiapplication对象的代理",{"2":{"37":1}}],["在定时的时间",{"2":{"34":1}}],["在线教育",{"2":{"30":1}}],["在终端中输入命令",{"2":{"27":2}}],["在终端中csrutil",{"2":{"27":1}}],["在终端输入",{"2":{"26":1}}],["在重启的过程中按住command+r组合键进入到恢复工具界面",{"2":{"27":1}}],["在其他地方使用",{"2":{"26":1}}],["在其中添加与",{"2":{"23":1}}],["在环境配置完毕后",{"2":{"23":1}}],["在~",{"2":{"23":1,"380":1}}],["在该方法中使用异步队列复制或移动下载的零时文件",{"2":{"16":1}}],["在钥匙串中找到对应id的证书",{"2":{"14":1}}],["在tomcat中找到server",{"2":{"3":1}}],["注释将会为该行相应的着色",{"2":{"299":1}}],["注释将会为该行创建",{"2":{"298":1}}],["注释将聚焦它并模糊代码的其他部分",{"2":{"297":1}}],["注释实现行高亮",{"2":{"296":1}}],["注册facebook",{"0":{"65":1}}],["注册符",{"2":{"8":1}}],["注意例2的写法使用了url标识符的形式",{"2":{"326":1}}],["注意这里要加引号",{"2":{"326":1}}],["注意命名冲突",{"2":{"260":1}}],["注意长短连接与长短轮询的区别",{"2":{"31":1}}],["注意事项",{"2":{"16":1}}],["注意",{"2":{"2":1,"23":1,"27":1,"133":1,"141":1,"149":1,"151":1,"152":1,"154":1,"156":1,"160":1,"161":1,"165":1,"181":1,"182":1,"194":1,"195":3,"204":1,"208":1,"209":1,"213":1,"215":1,"217":1,"218":1,"219":1,"226":1,"227":1,"240":1,"245":1,"259":1,"260":1,"330":1}}],["®",{"2":{"8":1}}],["©",{"2":{"8":1}}],["ll",{"2":{"397":1}}],["llama",{"2":{"156":5}}],["llog",{"2":{"46":2}}],["ld",{"2":{"90":3,"92":1,"395":1}}],["lang",{"2":{"286":1}}],["language",{"2":{"142":1,"148":1,"153":1,"166":2,"172":1,"173":1,"174":1,"194":1,"203":1,"204":2,"227":1,"232":1,"240":1,"245":1,"258":1,"260":1}}],["language=",{"2":{"90":1}}],["layers",{"2":{"222":6}}],["layers和height两个字段嵌套在匿名union类型中",{"2":{"222":1}}],["layoutifneeded",{"2":{"137":1}}],["launchpad",{"2":{"209":1}}],["launchoptions",{"2":{"65":2}}],["lazyloading",{"2":{"305":2}}],["lazy",{"2":{"194":1}}],["lastrefreshdate",{"2":{"139":6}}],["last",{"2":{"59":1,"90":1}}],["lastobject",{"2":{"59":1}}],["learning",{"2":{"392":1}}],["leave",{"2":{"61":3}}],["left",{"2":{"391":2}}],["level",{"2":{"306":1}}],["length",{"2":{"92":2}}],["length与content",{"2":{"92":1}}],["length始终为0",{"2":{"92":1}}],["let语句使用",{"2":{"204":1}}],["let语句来有条件地解包这种可能无法被响应的方法的返回值",{"2":{"141":1}}],["let语法解包可能存在的返回值",{"2":{"193":1}}],["letsencrypt",{"2":{"57":1}}],["let",{"2":{"57":1,"111":1,"135":1,"139":3,"140":2,"141":3,"143":1,"146":4,"154":2,"155":4,"156":5,"181":4,"182":5,"193":1,"194":1,"196":3,"197":1,"198":3,"200":2,"201":2,"203":3,"204":2,"205":6,"206":5,"219":1,"224":1}}],["less",{"2":{"53":2}}],["lru",{"2":{"44":1}}],["lite",{"2":{"397":1}}],["little",{"2":{"350":1,"397":1}}],["lilliput和blefuscu这两大强国在过去36个月里一直在苦战",{"2":{"350":1}}],["li>",{"2":{"295":2}}],["li",{"2":{"295":2}}],["like",{"2":{"276":1,"286":1,"397":2}}],["lifecycle",{"2":{"189":1}}],["linux环境",{"2":{"366":1}}],["linux",{"2":{"323":1}}],["linker",{"2":{"395":1}}],["link",{"2":{"103":2}}],["line4",{"2":{"300":2}}],["line3",{"2":{"300":6}}],["line2",{"2":{"300":4}}],["linenumbers",{"2":{"300":1}}],["lines",{"2":{"297":1,"392":1}}],["linelength64characters",{"2":{"219":1}}],["line",{"2":{"46":2,"276":1,"296":2,"300":18,"301":1,"302":1,"392":1}}],["list参数",{"2":{"215":1}}],["listofobjects",{"2":{"145":2}}],["listofvalues",{"2":{"145":2}}],["listcontainer",{"2":{"145":4}}],["listbyappendingitemsinlist",{"2":{"145":2}}],["list",{"2":{"103":3,"111":1,"145":10,"215":2,"273":1,"278":1,"383":1}}],["libraries",{"2":{"113":1}}],["library",{"2":{"26":5,"151":3}}],["libc++abi",{"2":{"74":1}}],["lipo",{"2":{"26":2}}],["l",{"2":{"20":2,"103":1,"396":1}}],["lowercased",{"2":{"155":1}}],["loose",{"2":{"90":1}}],["long",{"2":{"90":2,"211":6,"213":1}}],["lorem",{"2":{"66":1,"296":2}}],["logo",{"2":{"326":1,"361":1}}],["logging",{"2":{"190":1}}],["logged",{"2":{"73":1}}],["log函数",{"2":{"190":1}}],["logsomevalue",{"2":{"143":3}}],["loginandregister",{"2":{"391":4}}],["login",{"2":{"95":1}}],["log",{"0":{"46":1},"2":{"98":1,"110":1,"143":4,"190":9,"292":2,"388":1,"395":1}}],["loader",{"2":{"95":1}}],["loadinstagram",{"2":{"67":1}}],["load",{"2":{"17":1,"65":2,"88":1}}],["locationmanager",{"2":{"208":6}}],["location",{"2":{"16":2}}],["localization",{"2":{"206":2}}],["localizeddescription",{"2":{"200":1}}],["locale",{"2":{"145":1,"155":3,"179":1}}],["localstorage",{"2":{"113":1}}],["local",{"2":{"4":2,"20":2,"391":1}}],["lt",{"2":{"8":2,"53":1,"64":1,"65":1,"78":1,"165":2,"181":1,"184":2,"189":2,"205":1,"223":5,"224":6,"225":3,"226":4,"246":1,"297":1}}],["描述文件的名称",{"2":{"94":1}}],["描述",{"2":{"8":1,"360":1,"361":1}}],["常量通常用来为属性或者方法参数提供一系列合适的值",{"2":{"213":1}}],["常量指针",{"0":{"224":1},"2":{"210":1}}],["常量存储属性和计算属性会成为",{"2":{"151":1}}],["常见服务端指定的验证方法的类型",{"2":{"372":1}}],["常见异步编程",{"2":{"113":1}}],["常见书写方式",{"2":{"61":1}}],["常见的git命令",{"0":{"381":1},"1":{"382":1,"383":1,"384":1,"385":1,"386":1,"387":1,"388":1,"389":1,"390":1}}],["常见的实现方式",{"0":{"33":1}}],["常见的如下",{"2":{"30":1}}],["常见转义字符",{"0":{"6":1},"1":{"7":1,"8":1}}],["常用于引用文本",{"0":{"349":1},"1":{"350":1}}],["常用html语法",{"0":{"365":1},"1":{"366":1,"367":1,"368":1,"369":1},"2":{"308":1}}],["常用名称",{"2":{"14":1}}],["常用的宏定义",{"2":{"45":1}}],["常用的文件头编码",{"2":{"44":1}}],["常用的是有不带推送的",{"2":{"14":1}}],["常用的解决方式",{"2":{"3":1}}],["待更新",{"2":{"5":1,"267":1}}],["highlightlines",{"2":{"301":1}}],["highlight",{"2":{"296":2}}],["highlighted",{"2":{"276":2,"296":8}}],["highlighting",{"0":{"276":1},"2":{"276":2}}],["hidenuts",{"2":{"152":1}}],["hidden",{"2":{"92":1}}],["hiddenfild",{"2":{"92":5}}],["hue",{"2":{"217":4}}],["human",{"2":{"64":2}}],["h1>",{"2":{"120":2}}],["h1>hello",{"2":{"120":2}}],["hard",{"2":{"390":3}}],["hacker",{"2":{"286":1}}],["have",{"2":{"66":1,"222":2,"397":1}}],["handle",{"2":{"90":3}}],["handler",{"2":{"79":1}}],["hand",{"2":{"59":1}}],["hash",{"2":{"389":1}}],["hashable",{"2":{"213":2}}],["hasownproperty",{"2":{"92":1}}],["hasgranted",{"2":{"66":1}}],["has",{"2":{"14":1,"78":1,"86":1,"164":1,"222":2,"397":2}}],["h",{"2":{"59":1,"65":1,"78":1,"90":2,"233":1,"238":1,"239":3,"240":1,"241":3,"246":2,"249":1,"251":1,"252":1,"260":1,"391":3}}],["hsk",{"2":{"56":1}}],["h>",{"2":{"46":2,"59":1,"90":2,"244":3,"246":1}}],["help",{"2":{"360":2}}],["helpful",{"2":{"190":2}}],["hello",{"2":{"66":1,"136":1,"138":3,"155":2,"206":4,"245":3,"292":2,"319":1,"356":1}}],["here",{"2":{"90":1}}],["heart",{"2":{"90":1}}],["heartbeat",{"2":{"90":6}}],["head",{"2":{"390":1,"391":4}}],["head~3",{"2":{"390":1}}],["head^",{"2":{"390":1}}],["heading",{"2":{"283":2}}],["head>",{"2":{"90":2}}],["headquarters",{"2":{"66":2}}],["headerlink",{"2":{"306":1}}],["header中设置了",{"2":{"239":1}}],["header",{"2":{"31":1,"238":2,"241":1,"246":1,"260":2}}],["height",{"2":{"36":17,"61":1,"133":1,"146":2,"154":1,"222":1}}],["h文件创建一个",{"2":{"231":1}}],["h文件",{"2":{"26":1,"230":1,"233":1,"249":1}}],["how",{"0":{"396":1,"397":1},"2":{"396":1}}],["hostname",{"2":{"380":2}}],["host",{"2":{"86":2,"380":2}}],["hosted",{"2":{"23":1}}],["hooks",{"2":{"67":1}}],["homepage",{"2":{"356":1}}],["home=$flutter",{"2":{"23":1}}],["home=",{"2":{"4":1,"23":1}}],["home",{"2":{"4":3,"21":1,"23":3,"106":1,"283":1}}],["ht208079",{"2":{"27":1}}],["httpmethod",{"2":{"66":1}}],["http",{"2":{"24":1,"31":1,"40":1,"56":2,"59":1,"66":2,"86":3,"90":2,"92":1,"94":1,"203":1,"326":1,"372":1,"389":1,"391":4,"395":1,"396":1}}],["https网站访问过程",{"0":{"371":1}}],["https",{"2":{"9":4,"20":3,"27":1,"39":2,"57":1,"62":1,"66":1,"67":1,"69":2,"73":2,"82":2,"83":2,"306":2,"326":1,"328":1}}],["html>",{"2":{"90":2}}],["html4",{"2":{"90":1}}],["html",{"0":{"8":1},"2":{"2":1,"44":2,"56":1,"66":1,"73":1,"86":2,"90":4,"118":1,"283":5,"284":1,"295":1}}],["48",{"2":{"391":1}}],["4ac",{"2":{"304":2}}],["41421",{"2":{"215":1}}],["41564920",{"2":{"44":1}}],["42",{"2":{"182":1}}],["424d",{"2":{"44":1}}],["40",{"2":{"133":1,"296":1}}],["47494638",{"2":{"44":1}}],["4的文件发送给开发人员",{"2":{"14":1}}],["4",{"0":{"73":1,"113":1},"2":{"4":1,"14":1,"36":1,"52":2,"63":4,"64":1,"66":1,"71":1,"90":1,"113":1,"219":1,"276":1,"296":4,"300":2,"301":2,"304":4,"371":2,"380":1,"391":1}}],["58`",{"2":{"391":1}}],["58",{"2":{"391":9}}],["50",{"2":{"146":1,"154":1}}],["504b0304",{"2":{"44":1}}],["5+",{"2":{"63":1}}],["57415645",{"2":{"44":1}}],["52",{"2":{"391":10}}],["52617221",{"2":{"44":1}}],["524946462a73010057454250",{"2":{"44":1}}],["5min发ping",{"2":{"34":1}}],["5",{"0":{"74":1,"114":1},"2":{"4":1,"14":1,"27":2,"36":1,"66":1,"113":1,"134":4,"141":4,"156":1,"182":1,"219":1,"222":1,"296":1}}],["3rd",{"2":{"185":1}}],["3x",{"2":{"94":1}}],["38",{"2":{"52":1}}],["38425053",{"2":{"44":1}}],["3c3f786d6c",{"2":{"44":1}}],["31",{"2":{"27":1}}],["3",{"0":{"25":1,"72":1,"85":1,"108":1,"109":1,"110":1,"111":2,"112":2,"118":1},"1":{"109":1,"110":1,"111":1,"112":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1},"2":{"4":1,"14":1,"16":1,"25":1,"36":3,"44":1,"52":2,"61":1,"64":1,"66":7,"71":1,"79":1,"90":1,"99":1,"113":2,"146":1,"160":2,"182":1,"190":1,"213":1,"219":1,"224":3,"225":3,"287":2,"296":1,"300":6,"303":2,"340":1,"358":2,"372":1,"380":1}}],["0$",{"2":{"304":4}}],["0或者macos",{"2":{"208":1}}],["0和macos10",{"2":{"208":1}}],["01",{"2":{"90":1}}],["06",{"2":{"86":2}}],["0x92def",{"2":{"74":1}}],["0x9057b",{"2":{"74":1}}],["0x906e5",{"2":{"74":1}}],["0x1928b5",{"2":{"74":1}}],["0x24eabac9",{"2":{"74":1}}],["0x27f8d189",{"2":{"74":1}}],["0x27f236d3",{"2":{"74":1}}],["0x27f25125",{"2":{"74":1}}],["0x27f5468f",{"2":{"74":1}}],["0x27f5bc7f",{"2":{"74":1}}],["0x27f5c005",{"2":{"74":1}}],["0x27f5c6e1",{"2":{"74":1}}],["0x27f5c755",{"2":{"74":1}}],["0x27f446d3",{"2":{"74":1}}],["0x2801ddb9",{"2":{"74":1}}],["0x28296f91",{"2":{"74":1}}],["0x28296d25",{"2":{"74":1}}],["0x28294ab1",{"2":{"74":1}}],["0x23563873",{"2":{"74":1}}],["0x238bb015",{"2":{"74":1}}],["0x238bb229",{"2":{"74":1}}],["0x2396bd5b",{"2":{"74":1}}],["0x2396d9ed",{"2":{"74":1}}],["0x2396ddff",{"2":{"74":1}}],["0x239ab91b",{"2":{"74":1}}],["0x23146e17",{"2":{"74":1}}],["07",{"2":{"54":1,"59":1}}],["0以上版本进行定义",{"2":{"52":1}}],["0及以上才可以使用",{"2":{"50":1}}],["0及以上则编译此部分代码",{"2":{"50":1}}],["0则编译此部分代码",{"2":{"50":1}}],["05",{"2":{"40":1,"100":1}}],["039",{"2":{"397":1}}],["03",{"2":{"21":1,"61":1,"78":1,"155":1,"397":1}}],["0",{"2":{"20":2,"36":28,"46":1,"48":1,"50":2,"52":4,"53":5,"59":3,"63":2,"67":4,"74":1,"77":2,"79":2,"82":1,"90":2,"94":4,"95":1,"133":6,"134":10,"146":7,"154":2,"160":5,"190":3,"194":2,"200":1,"208":4,"215":2,"218":1,"219":2,"224":11,"225":11,"227":2,"252":1,"257":8,"304":4,"372":2,"391":2}}],["09",{"2":{"9":1,"17":1,"26":1,"88":1}}],["04",{"2":{"8":1,"14":1,"37":1,"53":1,"59":1,"66":1,"67":1,"74":1,"79":1,"372":1,"377":1,"390":1,"392":1}}],["000001b3",{"2":{"44":1}}],["000001ba",{"2":{"44":1}}],["00",{"2":{"3":2,"4":2,"8":2,"9":2,"17":2,"21":2,"26":2,"27":2,"34":2,"36":2,"37":2,"40":2,"44":2,"53":2,"54":2,"57":2,"61":2,"67":2,"86":2,"88":2,"90":2,"95":2,"100":2,"372":2,"377":2,"390":2,"397":2}}],["08",{"2":{"3":1,"44":1,"57":1}}],["26389273",{"2":{"396":1}}],["293c",{"2":{"392":1}}],["2a",{"2":{"304":2}}],["234",{"2":{"300":1}}],["23",{"2":{"296":1}}],["2nd",{"2":{"185":1}}],["21",{"2":{"63":1,"391":1}}],["2e524d46",{"2":{"44":1}}],["2e7261fd",{"2":{"44":1}}],["22",{"2":{"37":1,"53":1,"90":2,"372":1}}],["24825123",{"2":{"59":1}}],["24",{"2":{"21":1}}],["209",{"2":{"391":4}}],["20types",{"2":{"155":1}}],["20data",{"2":{"155":1}}],["20cocoa",{"2":{"155":1}}],["20with",{"2":{"155":1}}],["200",{"2":{"133":1,"205":3}}],["20",{"2":{"67":1,"74":1,"79":1,"392":1}}],["20k",{"2":{"44":2}}],["2020",{"2":{"21":1,"40":1,"95":1}}],["2016",{"2":{"377":1}}],["2019",{"2":{"8":1,"14":1,"390":1}}],["2017",{"2":{"4":1,"9":1,"17":1,"26":1,"34":1,"36":1,"37":1,"44":1,"53":1,"54":1,"57":1,"59":1,"61":1,"66":1,"67":1,"74":1,"78":1,"79":1,"86":1,"88":1,"90":1,"372":1,"392":1,"397":1}}],["2018",{"2":{"3":1,"27":1,"100":1}}],["2880px",{"2":{"66":1}}],["28",{"2":{"14":1,"78":1,"377":1,"397":1}}],["250",{"2":{"391":10}}],["255044462d312e",{"2":{"44":1}}],["25",{"2":{"8":1}}],["2790987080",{"2":{"86":2}}],["27",{"2":{"4":1,"34":1,"36":1,"90":1,"296":1}}],["2",{"0":{"14":1,"21":1,"24":1,"40":1,"47":1,"71":1,"83":1,"84":1,"103":1,"106":1,"107":1,"110":1,"117":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"107":1},"2":{"3":1,"14":3,"16":1,"26":1,"36":5,"44":1,"48":1,"52":2,"53":2,"61":1,"64":1,"66":1,"71":5,"74":1,"79":1,"86":2,"90":4,"95":4,"113":2,"137":2,"146":2,"159":1,"200":2,"215":1,"219":1,"222":2,"224":3,"225":3,"252":1,"287":2,"296":2,"300":7,"301":3,"302":1,"306":1,"340":1,"358":2,"371":1,"372":1,"380":1}}],["84",{"2":{"86":1,"391":2}}],["8081",{"2":{"391":10}}],["8080",{"2":{"90":2}}],["80",{"2":{"86":2}}],["89",{"2":{"59":1,"86":1,"155":1}}],["89504e47",{"2":{"44":1}}],["8",{"2":{"3":1,"36":1,"48":1,"50":1,"52":6,"53":3,"86":2,"90":4,"94":1,"160":1,"208":6,"296":2}}],["8编码",{"2":{"3":1}}],["ul>",{"2":{"295":4}}],["uuid",{"2":{"179":1}}],["uat",{"2":{"88":1,"94":2,"95":4}}],["u=142020185",{"2":{"86":2}}],["up",{"2":{"391":3}}],["upstream\\thttp",{"2":{"391":2}}],["upstream",{"2":{"386":1,"389":1,"391":9,"392":1}}],["updating",{"2":{"124":1}}],["updated",{"2":{"201":1,"392":1}}],["updatedate",{"2":{"201":3}}],["update",{"2":{"83":1}}],["upload",{"2":{"66":1,"95":1}}],["u",{"2":{"67":2,"79":1,"95":3}}],["util",{"2":{"90":2,"391":4}}],["utils",{"2":{"59":2}}],["uti",{"2":{"67":3,"79":1}}],["utf8",{"2":{"205":1,"224":1}}],["utf8string",{"2":{"143":1}}],["utf",{"2":{"3":1,"86":2,"90":2,"94":1,"181":1}}],["unmanaged",{"2":{"189":2,"227":2}}],["unmounting",{"2":{"124":1}}],["unsigned",{"2":{"211":5}}],["unsupported",{"2":{"196":1}}],["unspecified",{"2":{"151":1}}],["unsafemutablerawpointer",{"2":{"223":1,"225":1}}],["unsafemutablepointer",{"2":{"214":1,"215":1,"223":2,"224":1,"225":1}}],["unsaferawpointer",{"2":{"223":1,"224":1,"227":1}}],["unsafepointer",{"2":{"223":2,"224":2}}],["unsafe",{"2":{"116":3,"136":1}}],["unavailable宏来传达一个提示信息",{"2":{"256":1}}],["unavailable",{"2":{"151":1,"256":1}}],["unannotatedproperty",{"2":{"142":2}}],["unqualifiedset",{"2":{"150":2}}],["unqualifieddictionary",{"2":{"150":2}}],["unowned",{"2":{"148":1}}],["union",{"2":{"222":1}}],["unicode",{"2":{"181":3}}],["unichar",{"2":{"141":1}}],["uniform",{"2":{"67":2,"79":1}}],["unretained属性特性的属性",{"2":{"136":1}}],["undefined",{"2":{"99":1,"395":1}}],["uncaught",{"2":{"74":1}}],["unc0ver",{"2":{"39":3}}],["unzip",{"2":{"71":1}}],["unknown",{"2":{"54":1,"59":1}}],["uiwindow",{"2":{"396":2}}],["uioffset",{"2":{"191":1}}],["uiedgeinsets",{"2":{"191":1}}],["uint",{"2":{"179":1,"219":1}}],["uinavigationcontroller",{"2":{"59":3}}],["uiviewalertforunsatisfiableconstraints",{"0":{"396":1},"2":{"396":2}}],["uiviewautoresizingflexiblebottommargin",{"2":{"219":1}}],["uiviewautoresizingflexibleheight",{"2":{"219":1}}],["uiviewautoresizingflexibletopmargin",{"2":{"219":1}}],["uiviewautoresizingflexiblerightmargin",{"2":{"219":1}}],["uiviewautoresizingflexiblewidth",{"2":{"219":1}}],["uiviewautoresizingflexibleleftmargin",{"2":{"219":1}}],["uiviewautoresizingnone",{"2":{"219":1}}],["uiviewautoresizing",{"2":{"219":8}}],["uiview",{"2":{"154":3,"170":1}}],["uiviewcontroller",{"2":{"59":12,"144":2,"154":1,"163":1,"165":1,"169":1,"176":1,"258":1}}],["uiviewcontroller+utils",{"2":{"59":2}}],["uibutton",{"2":{"154":2,"169":1,"204":6}}],["uibezierpath",{"2":{"146":1}}],["uicolor",{"2":{"134":2,"136":1,"170":1}}],["uitextfielddelegate",{"2":{"165":1}}],["uitextfield",{"2":{"133":1,"169":1}}],["uitableviewdelegate",{"2":{"144":1,"165":2}}],["uitableviewdelegate>",{"2":{"144":1}}],["uitableviewdatasource",{"2":{"144":2,"165":2,"204":3}}],["uitableviewcellstylesubtitle",{"2":{"218":1}}],["uitableviewcellstylevalue2",{"2":{"218":1}}],["uitableviewcellstylevalue1",{"2":{"218":1}}],["uitableviewcellstyle",{"2":{"218":3}}],["uitableviewcell",{"2":{"140":1,"176":3}}],["uitableview",{"2":{"133":3,"176":3}}],["uitableviewstylegrouped",{"2":{"133":1}}],["uitableviewstyle",{"2":{"133":2}}],["uitabbarcontroller",{"2":{"59":3}}],["ui",{"2":{"113":1,"169":1}}],["uialertactionstylecancel",{"2":{"79":1}}],["uialertaction",{"2":{"79":2}}],["uialertcontrollerstylealert",{"2":{"79":1}}],["uialertcontroller",{"2":{"79":2}}],["uiapplicationopenurloptionskey",{"2":{"65":1}}],["uiapplication",{"2":{"37":3,"59":1,"65":3,"67":5,"79":3}}],["uiapplicationdelegate协议",{"2":{"37":1}}],["uiscrollview",{"2":{"77":1}}],["uisplitviewcontroller",{"2":{"59":3}}],["uidocumentinteractioncontroller",{"2":{"67":3,"79":2}}],["uidevice",{"2":{"53":6}}],["uikit",{"2":{"46":2,"59":2,"154":1,"161":1,"163":1,"176":1,"177":1}}],["uigraphicsendimagecontext",{"2":{"36":1}}],["uigraphicsgetimagefromcurrentimagecontext",{"2":{"36":1}}],["uigraphicsgetcurrentcontext",{"2":{"36":2}}],["uigraphicsbeginimagecontext",{"2":{"36":1}}],["uiimagepngrepresentation",{"2":{"67":2,"79":1}}],["uiimageorientationright",{"2":{"36":2}}],["uiimageorientationrightmirrored",{"2":{"36":1}}],["uiimageorientationleft",{"2":{"36":2}}],["uiimageorientationleftmirrored",{"2":{"36":1}}],["uiimageorientationdownmirrored",{"2":{"36":1}}],["uiimageorientationdown",{"2":{"36":1}}],["uiimageorientationupmirrored",{"2":{"36":1}}],["uiimageorientationup",{"2":{"36":1}}],["uiimageorientation",{"2":{"36":1}}],["uiimage",{"2":{"36":3,"61":1,"67":4,"73":2,"79":1,"135":1}}],["uber",{"2":{"30":1}}],["url>",{"2":{"391":1}}],["url标识符是我起的名字",{"2":{"328":1}}],["url即图片的url地址",{"2":{"326":1}}],["urlfordirectory",{"2":{"197":2}}],["urlforresource",{"2":{"194":1}}],["urlrequest",{"2":{"179":1}}],["urlqueryitem",{"2":{"179":2}}],["urlcomponents",{"2":{"179":2}}],["urlencoded",{"2":{"92":1}}],["url2",{"2":{"86":2}}],["urlpathallowedcharacterset",{"2":{"86":1}}],["urlstr",{"2":{"86":2}}],["urlsession",{"2":{"16":1,"372":1}}],["urlhostallowedcharacterset",{"2":{"79":1}}],["urlwithstring",{"2":{"66":4,"67":4,"73":1,"79":3,"86":2,"90":1,"92":1}}],["url",{"0":{"86":1},"2":{"61":1,"64":5,"65":4,"66":2,"67":5,"79":1,"86":12,"92":5,"179":1,"185":3,"194":1,"195":2,"196":2,"197":4,"283":1,"326":1,"382":1,"389":4}}],["url=https",{"2":{"23":2}}],["uriencoding",{"2":{"3":1}}],["usage",{"2":{"268":1,"306":1,"391":1}}],["using",{"2":{"205":2,"303":4,"391":1,"397":1}}],["us",{"2":{"27":1,"286":1}}],["usr",{"2":{"4":2,"20":2}}],["useshinynewfeature",{"2":{"208":1}}],["usedata",{"2":{"268":3}}],["used",{"2":{"103":1,"268":1}}],["usebodyencodingforuri",{"2":{"3":1}}],["use",{"2":{"2":3,"86":3,"103":2,"306":1,"395":1}}],["userconfig",{"2":{"302":6}}],["userdomainmask",{"2":{"197":1}}],["userdefaults",{"2":{"139":3}}],["userinfo",{"2":{"90":1,"198":4,"200":1}}],["userid",{"2":{"73":1}}],["username=",{"2":{"2":1}}],["username",{"2":{"2":1,"86":2,"92":1}}],["user",{"2":{"2":3,"73":1,"86":2,"88":1,"170":1,"383":2}}],["users>",{"2":{"2":2}}],["users",{"2":{"2":2,"23":1,"26":3,"73":1}}],["=>",{"2":{"306":1}}],["=和",{"2":{"149":1}}],["==enter==",{"2":{"392":3}}],["==esc==",{"2":{"392":1}}],["==i==",{"2":{"392":1}}],["==运算符提供实现",{"2":{"149":1}}],["==运算符的默认实现会调用isequal",{"2":{"149":1}}],["===运算符的默认实现则会检查指针是否相同",{"2":{"149":1}}],["==urlqueryallowedcharacterset==",{"2":{"86":1}}],["==urlfragmentallowedcharacterset==",{"2":{"86":1}}],["==urlpathallowedcharacterset==",{"2":{"86":1}}],["==urlpasswordallowedcharacterset==",{"2":{"86":1}}],["==urlhostallowedcharacterset==",{"2":{"86":1}}],["==urluserallowedcharacterset==",{"2":{"86":1}}],["==stringbyaddingpercentencodingwithallowedcharacters==",{"2":{"86":1}}],["==nsstring==",{"2":{"86":1}}],["==publish",{"2":{"66":1}}],["==fb1767503776894317==",{"2":{"64":1}}],["==fb==",{"2":{"64":1}}],["==fb",{"2":{"64":1}}],["==",{"2":{"36":2,"53":3,"64":9,"66":1,"73":2,"90":2,"95":2,"194":1,"200":1}}],["=",{"2":{"3":2,"25":1,"36":46,"53":3,"54":4,"59":4,"61":10,"65":4,"66":24,"67":21,"73":7,"74":4,"77":3,"79":10,"86":8,"90":33,"92":12,"95":3,"109":1,"110":5,"111":3,"133":3,"134":2,"135":1,"136":2,"138":2,"139":6,"140":4,"141":3,"143":2,"146":4,"147":2,"148":4,"151":2,"152":1,"154":2,"155":6,"156":11,"167":1,"181":4,"182":5,"183":1,"184":1,"185":1,"189":1,"190":2,"193":2,"194":7,"196":8,"197":5,"198":6,"200":2,"201":8,"203":5,"204":2,"205":3,"206":6,"208":3,"213":2,"215":2,"218":4,"219":9,"220":2,"222":3,"224":4,"225":6,"226":1,"227":2,"239":2,"244":2,"248":1,"252":4,"257":4,"268":1,"300":13,"302":4,"304":12,"372":4,"391":1}}],["npx",{"2":{"117":1}}],["npm",{"2":{"82":8,"85":1,"102":1,"103":1,"105":1,"116":7,"117":3,"130":1,"293":1}}],["nibbundleornil",{"2":{"154":2}}],["nibnameornil",{"2":{"154":2}}],["nibname",{"2":{"154":2}}],["nio",{"2":{"90":5}}],["nilvalue",{"2":{"143":2}}],["nil",{"2":{"61":1,"67":1,"73":4,"74":1,"79":3,"90":7,"141":2,"143":1,"151":1,"156":1,"182":1,"194":2,"196":1,"197":4,"198":4,"203":1,"206":1,"215":2,"226":1,"227":3}}],["nabla",{"2":{"304":8}}],["navigationdelegate",{"2":{"92":1}}],["native",{"0":{"80":1},"1":{"81":1,"82":1,"83":1,"84":1,"85":1},"2":{"82":4,"84":2}}],["name中的名称即可",{"2":{"259":1}}],["name就是",{"2":{"231":1}}],["name宏来指定枚举值导入到",{"2":{"255":1}}],["name宏来指定类方法导入为",{"2":{"254":1}}],["name宏来指定类工厂方法导入为",{"2":{"254":1}}],["name宏来自定义它们导入到",{"2":{"253":1}}],["name宏来让",{"2":{"217":1}}],["name宏改变方法的参数顺序或参数数量",{"2":{"217":1}}],["name宏中的参数self引用着方法的调用者",{"2":{"217":1}}],["name宏的参数使用和",{"2":{"217":1}}],["name和friends属性都标记了",{"2":{"175":1}}],["namecountaccessor",{"2":{"156":2}}],["nameaccessor",{"2":{"156":2}}],["named",{"2":{"151":1}}],["names",{"2":{"151":1}}],["name=",{"2":{"120":1}}],["name=xxx",{"2":{"95":2}}],["name>",{"2":{"103":1,"391":1}}],["name",{"2":{"3":4,"64":2,"67":4,"79":2,"92":1,"95":9,"103":4,"120":2,"151":2,"152":3,"156":23,"163":1,"175":1,"190":2,"205":4,"206":3,"217":7,"231":1,"232":1,"254":2,"255":1,"260":2,"295":2,"382":1,"383":2,"386":4,"389":2}}],["need",{"2":{"392":1}}],["necessary",{"2":{"392":1}}],["ne",{"2":{"304":2}}],["next",{"2":{"296":2,"397":1}}],["neat",{"2":{"287":2,"358":2}}],["net",{"2":{"79":1}}],["networkingresulttypenodata",{"2":{"61":1}}],["networkingresulttypesuccess",{"2":{"61":1}}],["newmethod",{"2":{"258":2}}],["newvalue",{"2":{"217":2}}],["newer",{"2":{"208":1}}],["newdecoder",{"2":{"90":1}}],["news",{"2":{"39":1}}],["new",{"2":{"3":1,"21":2,"90":5,"103":2,"106":2,"159":2,"196":2,"231":1,"238":1,"389":1,"391":2}}],["nullableproperty",{"2":{"142":2}}],["nullable标注的类型",{"2":{"142":1}}],["nullable和",{"2":{"142":1}}],["nullable",{"2":{"92":2,"136":1,"142":3,"151":3,"257":4}}],["null",{"2":{"61":2,"90":1,"99":1,"136":1,"142":1,"151":1,"197":2}}],["numbers=2",{"2":{"300":2}}],["numbers",{"2":{"300":4,"301":1,"302":1}}],["numberstyle",{"2":{"194":1}}],["numberformatter",{"2":{"194":2}}],["number",{"2":{"42":1,"95":4,"99":1,"182":2}}],["ng2",{"2":{"113":1}}],["ngondestroy",{"2":{"113":1}}],["ngoninit",{"2":{"113":1}}],["ngafterviewinit",{"2":{"113":1}}],["ngafterviewinit生命周期函数里面获取dom",{"2":{"113":1}}],["ngstyle",{"2":{"112":1}}],["ngswitchdefault>output2",{"2":{"111":1}}],["ngswitchcase=",{"2":{"111":1}}],["ngswitch",{"2":{"111":2}}],["ngcalss",{"2":{"112":1}}],["ngif",{"2":{"111":1}}],["ngfor",{"2":{"111":1}}],["ngmodel",{"2":{"110":1,"112":1}}],["ng",{"2":{"21":4,"106":4,"113":2}}],["n",{"2":{"20":2,"90":1}}],["nsjsonserialiation",{"2":{"205":1}}],["nsjsonreadingoptions的选项集会被导入为jsonserialization",{"2":{"180":1}}],["nskeyvalueobservation",{"2":{"201":1}}],["nskeyedunarchiver",{"2":{"42":1}}],["nskeyedarchiver",{"2":{"42":1}}],["nsfilemanager",{"2":{"195":1,"196":1,"197":2}}],["nsfoundation版本宏",{"0":{"52":1}}],["nsxmldocument",{"2":{"194":3}}],["nsxpcconnection",{"2":{"180":1}}],["nswindow",{"2":{"193":1}}],["nswindowdelegate",{"2":{"193":1}}],["nsrange",{"2":{"191":1}}],["nsregularexpression",{"2":{"180":1,"194":2}}],["nsrunloopcommonmodes",{"2":{"90":1}}],["nsrunloop",{"2":{"90":1}}],["nspredicate",{"2":{"180":1,"184":2}}],["nspropertylistserialization",{"2":{"205":1}}],["nsproxy",{"2":{"180":1}}],["nsprocessinfo",{"2":{"53":1}}],["nspersonnamecomponents",{"2":{"179":1}}],["nsnotification",{"2":{"179":1}}],["nsnull",{"0":{"143":1},"2":{"132":1,"143":3}}],["nsnumericsearch",{"2":{"53":5}}],["nsnumber",{"2":{"42":1,"179":1,"182":10,"185":2}}],["nsindexset",{"2":{"179":1}}],["nsindexpath",{"2":{"179":1}}],["nsinteger",{"2":{"42":1,"53":3,"90":2,"182":1,"218":1,"252":1,"255":1,"372":1}}],["nsinternalinconsistencyexception",{"2":{"36":1}}],["nsautoreleasepool",{"2":{"180":1}}],["nsaffinetransform",{"2":{"179":1}}],["nsarray",{"2":{"42":1,"74":1,"145":2,"151":2,"155":2,"176":1,"179":1,"183":6,"256":2}}],["nsmeasurement",{"2":{"179":1}}],["nsmanaged",{"2":{"175":6}}],["nsmanaged特性",{"2":{"175":2}}],["nsmanaged特性告知",{"2":{"175":1}}],["nsmanagedobject",{"0":{"175":1},"2":{"162":1,"175":1}}],["nsmutableurlrequest",{"2":{"92":2}}],["nsvalue>",{"2":{"145":1}}],["nsvalue",{"2":{"145":1}}],["nslocalizedstring",{"2":{"206":3}}],["nslocalizedstringfromtableinbundle",{"2":{"206":1}}],["nslocalizedstringfromtable",{"2":{"206":1}}],["nslocalizeddescriptionkey",{"2":{"200":1}}],["nslocale",{"2":{"145":1,"179":1}}],["nslog",{"2":{"46":1,"54":3,"61":1,"65":2,"66":2,"67":4,"73":3,"74":2,"79":1,"86":1,"90":7,"196":1,"397":2}}],["ns",{"2":{"142":2,"195":1,"200":2,"213":13,"218":1,"219":1,"254":2,"255":2,"256":1,"257":1,"372":2}}],["nstimezone",{"2":{"179":1}}],["nstimeinterval",{"2":{"90":1}}],["nstimer",{"2":{"90":2}}],["nsthread",{"2":{"61":1,"90":1}}],["nscalendar",{"2":{"179":1}}],["nscache",{"2":{"145":2}}],["nscachesdirectory",{"2":{"67":2,"79":1,"197":1}}],["nsclassfromstring",{"2":{"167":2}}],["nscopying",{"2":{"174":1}}],["nscopying>",{"2":{"145":2,"256":1}}],["nscopying>>",{"2":{"145":1}}],["nscoder的方法decodeobjectofclass",{"2":{"177":1}}],["nscoder",{"2":{"154":1,"164":1}}],["nscoding协议要求采用协议的类型实现其所要求的构造器init",{"2":{"164":1}}],["nscoding",{"0":{"164":1},"2":{"144":1,"162":1}}],["nscoding>",{"2":{"144":1}}],["nscharacterset",{"2":{"79":1,"86":1,"179":1}}],["nssize",{"2":{"193":2}}],["nsset",{"2":{"150":2,"151":1,"175":3,"179":1,"184":6}}],["nsset以及nsdictionary类型的声明在使用轻量泛型参数化后",{"2":{"145":1}}],["nssearchpathfordirectoriesindomains",{"2":{"67":2,"79":1}}],["nsstringfromsize",{"2":{"193":1}}],["nsstring类以",{"2":{"181":1}}],["nsstring",{"2":{"42":1,"65":1,"66":5,"67":11,"79":7,"86":4,"90":9,"92":8,"138":5,"145":1,"150":2,"151":5,"155":2,"179":1,"181":3,"183":1,"184":3,"185":1,"205":1,"226":2,"252":1}}],["nsec",{"2":{"90":1}}],["nserrordomain",{"2":{"200":1}}],["nserror",{"2":{"61":1,"66":1,"74":1,"90":2,"92":1,"151":1,"195":5,"196":2,"198":6,"199":1,"200":1}}],["nsexception",{"2":{"36":1,"74":1,"180":1}}],["nsobject类为isequal",{"2":{"149":1}}],["nsobject",{"2":{"90":1,"145":5,"151":2,"152":1,"156":1,"193":1,"201":4,"245":2,"249":1,"257":1}}],["nsoperatingsystemversion",{"2":{"53":4}}],["nsoperation",{"0":{"17":1},"2":{"16":1}}],["nsoperationqueue",{"2":{"16":3,"90":2}}],["nsorderedascending",{"2":{"53":2}}],["nsordereddescending",{"2":{"53":2}}],["nsorderedsame",{"2":{"53":1}}],["nsdocument",{"2":{"198":3}}],["nsdecimalnumber",{"2":{"179":1}}],["nsdiscardablecontent>",{"2":{"145":1}}],["nsdiscardablecontent>>",{"2":{"145":1}}],["nsdictionary",{"2":{"42":1,"43":1,"65":2,"66":1,"145":1,"150":2,"155":2,"179":1,"180":1,"185":6,"205":1}}],["nsdateinterval",{"2":{"179":1}}],["nsdatecomponents",{"2":{"179":1}}],["nsdate",{"2":{"42":1,"67":2,"79":1,"140":1,"141":1,"145":1,"150":1,"179":1,"183":3,"185":2,"201":4,"226":2}}],["nsdata",{"2":{"42":2,"90":1,"92":1,"147":2,"179":1,"185":1}}],["nsusernotification",{"2":{"180":1}}],["nsuserdomainmask",{"2":{"67":2,"79":1,"197":1}}],["nsuserdefaults",{"2":{"42":1}}],["nsuuid",{"2":{"179":1}}],["nsuinteger",{"2":{"90":1,"182":1,"219":1,"254":1}}],["nsutf8stringencoding",{"2":{"86":1,"90":1,"92":1}}],["nsurlauthenticationmethodservertrust",{"2":{"372":1}}],["nsurlauthenticationmethodclientcertificate",{"2":{"372":1}}],["nsurlauthenticationmethodntlm",{"2":{"372":1}}],["nsurlauthenticationmethodhttpdigest",{"2":{"372":1}}],["nsurlauthenticationmethodhttpbasic",{"2":{"372":1}}],["nsurlauthenticationchalleng",{"2":{"372":1}}],["nsurlprotectionspace对象包含请求的主机host",{"2":{"372":1}}],["nsurlerrorcannotopenfile",{"2":{"198":3}}],["nsurlerrordomain",{"2":{"198":3}}],["nsurlrequest",{"2":{"179":1}}],["nsurlqueryitem",{"2":{"179":2}}],["nsurlcomponents",{"2":{"86":5,"179":2}}],["nsurlcache",{"2":{"44":2}}],["nsurl",{"2":{"16":1,"42":1,"61":1,"65":2,"66":7,"67":12,"73":1,"79":5,"86":4,"90":1,"92":1,"179":1,"180":1,"185":3,"195":1,"196":4,"197":1}}],["nsurlsessionauthchallengerejectprotectionspace",{"2":{"372":1}}],["nsurlsessionauthchallengecancelauthenticationchallenge",{"2":{"372":1}}],["nsurlsessionauthchallengeperformdefaulthandling",{"2":{"372":1}}],["nsurlsessionauthchallengeusecredential",{"2":{"372":1}}],["nsurlsessionauthchallengedisposition",{"2":{"372":1}}],["nsurlsessiondownloadtask",{"2":{"16":1}}],["nsurlsession",{"0":{"372":1},"2":{"16":1,"372":1}}],["nsbundle",{"2":{"26":1,"67":1}}],["nbsp",{"2":{"8":1}}],["normal",{"2":{"392":1}}],["noreferrer",{"2":{"285":1}}],["non",{"2":{"392":1}}],["nonobjc",{"2":{"152":1}}],["nonobjc特性",{"2":{"152":1}}],["nonnullproperty",{"2":{"142":2}}],["nonnull或者范围宏标注的类型",{"2":{"142":1}}],["nonnull标注",{"2":{"142":1}}],["nonnull",{"2":{"136":1,"142":6,"143":1,"151":6}}],["nonatomic",{"2":{"90":4,"136":1,"151":4,"176":1}}],["nowplaying",{"2":{"151":3}}],["now",{"2":{"90":1,"397":1}}],["node",{"2":{"82":1}}],["notice",{"2":{"397":1}}],["notify",{"2":{"61":3}}],["notification",{"2":{"14":1,"179":1}}],["nothrow",{"2":{"195":1}}],["notation",{"2":{"103":1}}],["not",{"0":{"395":1},"2":{"2":1,"54":1,"66":1,"67":8,"90":1,"103":2,"164":1,"188":1,"391":1,"395":2}}],["notebkko",{"2":{"183":1}}],["note",{"2":{"2":1,"294":2}}],["no",{"2":{"2":1,"61":2,"74":1,"79":3,"86":2,"103":2,"196":1,"222":2,"300":1,"391":1}}],["1e7ae50",{"2":{"391":1}}],["1st",{"2":{"185":1}}],["192",{"2":{"86":2,"90":2}}],["19",{"2":{"66":1}}],["1和8",{"2":{"53":1}}],["13",{"2":{"52":2,"258":2,"296":1}}],["171",{"2":{"391":1}}],["17",{"2":{"52":1,"61":1,"95":1,"296":1}}],["14159",{"2":{"182":1}}],["14925860141113",{"2":{"70":1}}],["14925836417059",{"2":{"70":1}}],["14",{"2":{"21":1,"27":1,"40":1,"52":1,"95":1,"100":1,"390":1}}],["18",{"2":{"17":1,"26":1,"88":1}}],["1中3所在位置",{"2":{"13":1}}],["153",{"2":{"391":1}}],["1561082740838259",{"2":{"66":1}}],["15",{"2":{"9":1,"52":1,"390":1}}],["10的平台上运行",{"2":{"208":1}}],["10开始才可用",{"2":{"208":1}}],["100",{"2":{"154":1,"288":1,"391":5}}],["1000",{"2":{"67":2,"79":1}}],["10",{"2":{"8":1,"39":2,"52":1,"53":1,"74":2,"100":1,"140":1,"146":1,"160":4,"190":3,"208":7,"258":2,"296":2,"303":2}}],["1199",{"2":{"52":1}}],["1145",{"2":{"52":1}}],["1144",{"2":{"52":1}}],["1142",{"2":{"52":1}}],["1141",{"2":{"52":1}}],["1140",{"2":{"52":1}}],["11",{"2":{"4":1,"34":1,"36":1,"39":1,"44":1,"52":1,"90":1,"258":7}}],["162",{"2":{"391":1}}],["166",{"2":{"391":4}}],["166793820034304",{"2":{"66":1}}],["168",{"2":{"86":2,"90":2}}],["16k",{"2":{"44":1}}],["16",{"2":{"3":1,"4":1,"9":1,"17":1,"26":1,"34":1,"36":1,"37":1,"44":1,"52":1,"53":1,"54":2,"57":2,"61":1,"67":1,"86":1,"88":1,"90":1,"181":2,"296":1,"372":1,"377":1,"397":1}}],["12522571",{"2":{"395":1}}],["123ts",{"2":{"300":1}}],["123",{"2":{"86":2,"181":3,"302":1,"391":1}}],["1234567890",{"2":{"190":1}}],["12345678",{"2":{"92":1}}],["123456",{"2":{"2":1}}],["1299",{"2":{"52":1}}],["1280",{"2":{"52":1}}],["124",{"2":{"391":3}}],["1242",{"2":{"52":2}}],["1241",{"2":{"52":1}}],["1240",{"2":{"52":1}}],["12",{"2":{"3":1,"27":6,"40":1,"95":1,"160":1,"190":1}}],["1解码",{"2":{"3":1}}],["1",{"0":{"3":1,"13":1,"20":1,"23":1,"39":1,"46":1,"59":1,"70":1,"81":1,"82":2,"83":1,"94":1,"95":1,"102":1,"105":1,"107":1,"109":1,"116":1},"1":{"82":1,"83":1},"2":{"3":2,"13":2,"14":3,"16":1,"20":1,"21":1,"25":1,"26":1,"36":9,"43":1,"44":1,"52":4,"53":7,"61":1,"64":1,"66":1,"71":1,"74":1,"78":1,"79":1,"90":1,"94":4,"95":6,"99":1,"106":1,"109":1,"113":2,"134":2,"159":1,"198":1,"200":2,"209":1,"215":1,"218":2,"219":7,"224":3,"225":3,"252":1,"296":1,"300":3,"301":3,"302":1,"303":1,"306":1,"326":1,"328":1,"330":1,"340":1,"343":3,"371":1,"372":1,"380":1,"395":1}}],[">`",{"2":{"293":1}}],[">>>>>",{"2":{"352":1}}],[">>>>",{"2":{"352":1}}],[">>>",{"2":{"352":1}}],[">>",{"2":{"145":1,"352":1}}],[">output",{"2":{"111":1}}],[">64",{"2":{"90":1}}],[">=",{"2":{"50":2,"53":1}}],[">",{"2":{"2":4,"59":3,"61":11,"64":5,"74":1,"90":7,"94":8,"111":1,"120":1,"142":3,"145":5,"147":1,"150":2,"151":3,"155":1,"176":1,"183":4,"184":4,"185":4,"189":1,"193":1,"214":4,"215":1,"217":1,"226":1,"227":2,"283":6,"294":9,"295":2,"301":2,"302":2,"303":2,"352":1,"369":1,"391":4}}],["cpp",{"2":{"356":1}}],["cppstring",{"2":{"356":1}}],["cpu",{"2":{"43":2}}],["cmyswiftclass",{"2":{"248":1}}],["cmtime",{"2":{"191":1}}],["cmtimerange",{"2":{"191":1}}],["cmtimemapping",{"2":{"191":1}}],["ctypedef",{"2":{"213":2,"218":2,"219":1,"255":1}}],["ctcellulardatarestrictedstate",{"2":{"54":2}}],["ctcellulardata",{"2":{"54":4}}],["cwidechar",{"2":{"211":1}}],["cint",{"2":{"211":1,"214":1,"356":1}}],["cif",{"2":{"208":1,"258":1}}],["cs",{"2":{"301":3}}],["css",{"2":{"293":2}}],["cstruct",{"2":{"216":1,"222":1}}],["cstring",{"2":{"215":2}}],["cshort",{"2":{"211":1}}],["csrutil",{"2":{"27":1}}],["csr",{"2":{"14":1}}],["ccolor",{"2":{"217":1}}],["cchar32",{"2":{"211":1}}],["cchar16",{"2":{"211":1}}],["cchar",{"2":{"211":1}}],["ccfstringref",{"2":{"189":1}}],["cbool",{"2":{"211":1}}],["cvalistpointer类型的值会传递给接受可变参数的",{"2":{"215":1}}],["cvararg",{"2":{"206":1,"215":1}}],["cvoid",{"2":{"147":1}}],["c+",{"2":{"203":1,"254":2,"256":1}}],["c++",{"2":{"161":1}}],["cfarraycreatemutable",{"2":{"227":1}}],["cfarraycallbacks",{"2":{"227":1}}],["cf",{"2":{"217":7}}],["cfloat",{"2":{"211":1}}],["cfstring>",{"2":{"189":1,"227":2}}],["cfstring",{"2":{"189":3}}],["cfstringref",{"2":{"189":2}}],["cfrelease",{"2":{"188":1}}],["cfnetworkdownload",{"2":{"16":1}}],["curl",{"2":{"304":2}}],["currencysymbol",{"2":{"194":1}}],["currency",{"2":{"194":1}}],["currencyformatter",{"2":{"194":1}}],["currentlyplaying",{"2":{"151":1}}],["currentsession",{"2":{"90":2}}],["currentrunloop",{"2":{"90":1}}],["currentaccesstoken",{"2":{"66":1}}],["currentthread",{"2":{"61":1}}],["currentviewcontroller",{"2":{"59":2}}],["current",{"0":{"58":1,"59":1},"1":{"59":1},"2":{"58":1,"59":1,"155":1,"268":1,"389":1}}],["currentdevice",{"2":{"53":6}}],["cunsignedlonglong",{"2":{"211":1}}],["cunsignedlong",{"2":{"211":1}}],["cunsignedint",{"2":{"211":1}}],["cunsignedshort",{"2":{"211":1}}],["cunsignedchar",{"2":{"211":1}}],["customerui",{"2":{"391":3}}],["customerrordomain",{"2":{"252":1}}],["customerrorc",{"2":{"252":1}}],["customerrorb",{"2":{"252":1}}],["customerrora",{"2":{"252":1}}],["customerror",{"2":{"252":3}}],["customcopydescription",{"2":{"227":2}}],["custom",{"0":{"277":1},"2":{"205":2,"239":1,"244":1}}],["customized",{"2":{"200":2}}],["customthrow",{"2":{"200":2}}],["customlog",{"2":{"190":2}}],["cuicolor",{"2":{"134":1}}],["cuitableview",{"2":{"133":1}}],["c",{"0":{"132":1,"152":1,"155":1,"162":1,"163":1,"167":1,"210":1,"228":1,"229":1,"235":1,"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"256":1,"257":1,"258":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"163":1,"164":2,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"236":1,"237":1,"238":1,"239":2,"240":1,"241":2,"242":1,"243":1,"244":2,"245":1,"246":2,"247":1,"248":1,"249":2,"250":2,"251":2,"252":2,"253":1,"254":2,"255":2,"256":1,"257":1,"258":1,"259":1,"260":1},"2":{"73":1,"132":5,"133":8,"134":2,"135":6,"136":4,"137":4,"138":2,"140":2,"141":2,"142":6,"143":4,"144":6,"145":8,"146":3,"147":5,"148":3,"149":1,"150":3,"151":16,"152":13,"153":3,"154":5,"155":2,"156":1,"157":8,"159":2,"161":19,"162":7,"163":6,"165":4,"166":5,"167":4,"168":1,"171":1,"174":1,"176":5,"177":5,"179":6,"180":2,"182":1,"183":2,"184":2,"185":2,"188":3,"189":2,"192":2,"193":2,"194":2,"195":8,"196":2,"197":2,"198":6,"199":6,"200":2,"202":2,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"210":3,"211":2,"212":2,"213":5,"214":2,"215":3,"216":2,"217":6,"218":7,"219":4,"220":5,"222":2,"223":3,"227":7,"228":5,"229":4,"230":1,"231":7,"232":10,"233":3,"234":8,"235":15,"236":2,"237":1,"238":9,"239":10,"240":11,"241":8,"242":1,"243":3,"244":5,"245":6,"246":8,"247":4,"248":6,"249":2,"250":2,"251":2,"252":3,"253":4,"256":3,"257":4,"258":4,"259":1,"260":15,"263":3,"264":1,"265":1,"301":3,"304":4,"356":1,"380":2,"396":1}}],["clone",{"2":{"382":1}}],["clonglong",{"2":{"211":1}}],["clong",{"2":{"211":1}}],["closure",{"2":{"148":1}}],["closes",{"2":{"360":1}}],["close",{"2":{"90":3,"146":1,"360":1}}],["cllocationmanager",{"2":{"208":4}}],["cllocationmanager实例的requestwheninuseauthorization方法从ios",{"2":{"208":1}}],["cllocationcoordinate2d",{"2":{"191":1}}],["clang",{"2":{"395":1}}],["clarity",{"2":{"113":1}}],["class$",{"2":{"395":1}}],["class=",{"2":{"293":1}}],["classname",{"2":{"78":1}}],["class",{"2":{"59":3,"78":2,"90":1,"120":2,"143":1,"144":1,"145":1,"151":2,"152":1,"154":1,"163":1,"170":2,"175":2,"201":1,"245":1,"249":1,"293":1,"395":1}}],["click",{"2":{"110":1,"397":1}}],["clientcertificate",{"2":{"372":1}}],["client",{"2":{"90":12}}],["clientset",{"2":{"90":4}}],["client>",{"2":{"90":1}}],["cli",{"2":{"82":2,"102":1,"105":1,"116":1}}],["clean",{"2":{"1":1,"95":1}}],["cextern",{"2":{"200":1}}],["centered",{"2":{"287":2,"358":2}}],["center",{"2":{"66":2,"369":1,"391":7}}],["cellstyle",{"2":{"218":1}}],["cell",{"2":{"176":3,"239":1,"244":1}}],["cellheight",{"2":{"61":1}}],["cellmodel",{"2":{"61":4}}],["cellulardatarestrictiondidupdatenotifier",{"2":{"54":1}}],["cellulardata",{"2":{"54":4}}],["certsigningrequest",{"2":{"14":1}}],["certificate",{"2":{"14":2}}],["certificates",{"2":{"14":2}}],["cer证书",{"2":{"14":1}}],["c文件是不会识别上面的条件编译和",{"2":{"46":1}}],["caution",{"2":{"294":2}}],["caught",{"2":{"200":3}}],["cake结构体被导入后会拥有一个逐一成员构造器",{"2":{"222":1}}],["cake",{"2":{"222":8}}],["catransform3d",{"2":{"191":1}}],["category",{"2":{"190":1}}],["catch",{"2":{"90":7,"196":4,"199":1,"200":2}}],["calibration",{"2":{"217":3}}],["calendar",{"2":{"179":1}}],["called",{"2":{"397":1}}],["callbacks",{"2":{"227":2}}],["call",{"2":{"74":1}}],["capacitor",{"2":{"103":2}}],["cardconfiguration",{"2":{"73":1}}],["card",{"2":{"73":3}}],["can",{"2":{"268":1,"303":4,"392":1,"397":4}}],["cancelaction",{"2":{"79":2}}],["cancell",{"2":{"73":1}}],["canopenurl",{"2":{"67":4,"79":2}}],["case",{"2":{"36":8,"54":3,"152":2,"198":1,"218":4,"252":1}}],["cached",{"2":{"384":1}}],["cacheddata",{"2":{"145":2,"185":2}}],["cachesdirectory",{"2":{"197":1}}],["cachetype",{"2":{"61":1}}],["cache",{"2":{"23":1}}],["cgvector",{"2":{"191":1}}],["cgpoint",{"2":{"77":1,"146":3,"191":1}}],["cgcontextdrawimage",{"2":{"36":1}}],["cgcontextconcatctm",{"2":{"36":1}}],["cgcontexttranslatectm",{"2":{"36":2}}],["cgcontextscalectm",{"2":{"36":2}}],["cgcontextref",{"2":{"36":1}}],["cgsizemake",{"2":{"36":1}}],["cgsize",{"2":{"36":1,"191":1}}],["cgrectzero",{"2":{"67":3,"79":1}}],["cgrectmake",{"2":{"36":2}}],["cgrect",{"2":{"36":1,"133":3,"146":2,"154":1,"191":1}}],["cgaffinetransformmakescale",{"2":{"36":1}}],["cgaffinetransformmaketranslation",{"2":{"36":6}}],["cgaffinetransformrotate",{"2":{"36":5}}],["cgaffinetransformscale",{"2":{"36":3}}],["cgaffinetransformidentity",{"2":{"36":2}}],["cgaffinetransform",{"2":{"36":1,"191":1}}],["cgfloat",{"2":{"36":4,"146":3,"170":1,"257":12}}],["cgimagegetheight",{"2":{"36":2}}],["cgimagegetwidth",{"2":{"36":2}}],["cgimage",{"2":{"36":1}}],["cgimageref",{"2":{"36":1}}],["created",{"2":{"303":4}}],["createpoint2d",{"2":{"214":2}}],["createelement",{"2":{"92":2}}],["create",{"2":{"26":2,"61":5,"73":1,"117":1,"197":3}}],["cdot",{"2":{"304":4}}],["cdouble",{"2":{"211":1}}],["cd",{"2":{"21":2,"27":1,"84":2,"95":1,"106":2,"107":1,"117":1}}],["cherry",{"2":{"386":1}}],["checkout",{"2":{"386":3,"387":2}}],["check",{"2":{"273":1,"278":1,"395":1,"397":2}}],["child",{"2":{"59":1}}],["china",{"2":{"20":1}}],["challenge",{"2":{"372":2}}],["change",{"2":{"201":2,"304":2}}],["changehandler",{"2":{"201":1}}],["changed",{"2":{"14":1}}],["char32",{"2":{"211":1}}],["char16",{"2":{"211":1}}],["char",{"2":{"211":3,"356":1}}],["charset=utf",{"2":{"90":2}}],["charsetdecoder",{"2":{"90":1}}],["charset",{"2":{"90":7}}],["charbuffer",{"2":{"90":3}}],["charactercodingexception",{"2":{"90":2}}],["characterset",{"2":{"179":1}}],["characters",{"2":{"86":1}}],["character",{"2":{"86":1,"141":3}}],["chat",{"2":{"9":1}}],["choose",{"2":{"14":1,"397":1}}],["cnsfilemanager",{"2":{"196":1,"197":1}}],["cnpm",{"2":{"21":1,"106":1,"107":2}}],["cn",{"2":{"9":4,"23":2,"83":2}}],["cool",{"2":{"287":2}}],["col",{"2":{"287":4,"358":4}}],["collectionwithvalues",{"2":{"256":1}}],["colorsetcalibrationcolor",{"2":{"217":1}}],["colorsethue",{"2":{"217":1}}],["colorgetcalibrationcolor",{"2":{"217":1}}],["colorgethue",{"2":{"217":1}}],["colorbondiblue",{"2":{"217":1}}],["colordarkencolor",{"2":{"217":1}}],["colorcreatewithcmyk",{"2":{"217":1}}],["colorwithred",{"2":{"134":1}}],["color",{"2":{"134":2,"152":2,"216":4,"217":23,"257":2}}],["colon",{"2":{"86":1}}],["coach",{"2":{"191":1}}],["codable",{"2":{"205":2}}],["coder",{"2":{"154":3,"164":3}}],["code",{"2":{"90":4,"113":1,"198":4,"200":2,"239":1,"260":1,"296":2,"297":3,"298":4,"299":4,"301":3,"302":2,"326":1,"395":1,"397":2}}],["codingclass",{"2":{"144":2}}],["coding",{"0":{"86":1}}],["cordova",{"2":{"103":2}}],["corresponding",{"2":{"86":1}}],["core",{"0":{"175":1,"186":1},"1":{"187":1,"188":1,"189":1},"2":{"162":1,"175":7,"177":1,"186":5,"187":2,"188":5,"189":5,"217":1,"227":1}}],["corefoudation",{"0":{"52":1}}],["coredata",{"2":{"42":1,"175":1}}],["counting",{"2":{"391":1}}],["count",{"2":{"59":3,"74":1,"141":1,"156":2}}],["cocoaerror",{"2":{"196":2}}],["cocoaasyncsocket",{"2":{"33":1}}],["cocoa",{"0":{"26":1,"177":1,"191":1,"192":1},"1":{"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"189":1,"190":1,"191":1,"193":1,"194":1,"195":1,"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"209":1},"2":{"26":2,"132":1,"155":2,"157":5,"158":1,"161":2,"177":3,"192":2,"195":1,"199":2,"202":1,"208":1,"232":2,"263":1}}],["cocoapods",{"0":{"18":1,"19":1,"20":1,"83":1},"1":{"19":1,"20":2,"21":2},"2":{"20":2,"83":2}}],["conflicts",{"2":{"391":1}}],["conflict",{"2":{"391":2}}],["confirm",{"2":{"98":1}}],["configure",{"2":{"176":2}}],["configurations",{"2":{"397":1}}],["configuration",{"2":{"92":1,"95":3,"303":4,"397":2}}],["config",{"2":{"82":2,"92":2,"292":1,"293":1,"302":11,"306":2,"380":2,"383":4}}],["convention",{"2":{"147":1,"227":3}}],["convenience",{"2":{"146":1}}],["conditionexpression",{"2":{"111":1}}],["console",{"2":{"90":5,"98":3,"110":1,"292":1}}],["constituent",{"2":{"86":1}}],["const",{"2":{"25":1,"200":1,"213":7,"217":1,"223":3,"252":1,"268":1,"300":12,"302":4,"356":2}}],["concurrent",{"2":{"90":1}}],["connect",{"2":{"90":2,"103":1}}],["connection",{"2":{"31":1,"66":1}}],["container",{"2":{"292":1}}],["containers",{"0":{"277":1}}],["contentsof",{"2":{"194":1}}],["contentsoffile",{"2":{"135":2}}],["contents",{"2":{"95":2}}],["content=",{"2":{"90":1}}],["contenttype=",{"2":{"90":1}}],["contenttitle",{"2":{"66":2}}],["contentoffset",{"2":{"77":2}}],["content权限没申请下来",{"2":{"67":1}}],["content可以拿到用户发布的图片和视频内容",{"2":{"67":1}}],["contentdescription",{"2":{"66":2}}],["contenturlstring",{"2":{"66":2}}],["contenturl",{"2":{"66":4}}],["content",{"2":{"66":11,"90":1,"92":2}}],["context",{"2":{"36":6,"156":1}}],["controller",{"0":{"59":1},"2":{"58":1,"59":5,"73":1,"391":1}}],["continue",{"2":{"14":1}}],["continu",{"2":{"14":1}}],["command",{"2":{"392":2,"395":1}}],["commandline",{"2":{"209":2}}],["commit",{"2":{"385":6,"386":2,"387":1,"389":1,"390":1,"391":2,"392":2}}],["comment",{"2":{"206":4}}],["commented",{"2":{"2":1}}],["commons",{"2":{"66":1}}],["complied",{"2":{"397":1}}],["completionblock",{"2":{"147":1}}],["completionhandler",{"2":{"92":1,"372":1}}],["completion",{"2":{"61":2,"73":2,"74":1,"79":1}}],["completed",{"2":{"61":1,"391":1}}],["compile",{"2":{"395":1}}],["compiler",{"2":{"239":1,"260":1}}],["compression",{"2":{"391":1}}],["compressing",{"2":{"391":2}}],["companyinfo",{"2":{"391":1}}],["company",{"2":{"190":1,"380":1}}],["comparison",{"2":{"149":1}}],["compare",{"2":{"53":5}}],["composer",{"2":{"73":11}}],["compose",{"2":{"73":2}}],["componentdidupdate",{"2":{"124":1}}],["componentdidmount",{"2":{"124":1}}],["componentwillunmount在组件从",{"2":{"124":1}}],["componentwillupdate在组件接收到新的props或者state但还没有render时被调用",{"2":{"124":1}}],["componentwillreceiveprops",{"2":{"124":1}}],["componentwillmount",{"2":{"124":1}}],["componentswithstring",{"2":{"86":1}}],["componentswithurl",{"2":{"86":1}}],["components",{"2":{"21":1,"106":1}}],["component",{"2":{"21":1,"86":13,"106":1,"120":1}}],["com",{"2":{"9":4,"20":1,"24":1,"27":1,"39":1,"40":1,"56":1,"59":1,"61":2,"62":1,"66":1,"67":4,"73":1,"86":2,"92":1,"94":1,"190":1,"198":1,"306":2,"326":2,"328":1,"380":8,"395":1,"396":1}}],["copydescription",{"2":{"227":1}}],["copyonwritearrayset",{"2":{"90":2}}],["copy",{"2":{"8":1,"90":1,"136":1,"151":1}}],["our",{"2":{"397":1}}],["outlet",{"0":{"169":1},"2":{"168":1,"169":6}}],["outlets",{"2":{"162":1,"169":1}}],["output",{"2":{"26":2,"95":2,"113":1,"276":1,"277":1}}],["out",{"2":{"2":1,"90":9,"273":1,"278":1,"397":1}}],["own",{"2":{"397":1}}],["o",{"2":{"395":1,"396":1}}],["otherwise",{"2":{"397":1}}],["other",{"2":{"200":1,"397":1}}],["otherlist",{"2":{"145":2}}],["old",{"2":{"196":2}}],["observation",{"2":{"201":2}}],["observed",{"2":{"201":4}}],["observe",{"2":{"201":2}}],["observer",{"2":{"167":1,"201":1}}],["objecive",{"2":{"152":1}}],["objecttoobserve",{"2":{"201":5}}],["objecttype",{"2":{"184":1}}],["objects",{"2":{"183":2,"184":2,"391":8}}],["objectlist",{"2":{"145":1}}],["object",{"2":{"97":2,"99":1,"139":1,"149":1,"189":1,"201":6,"204":9}}],["objective",{"0":{"132":1,"152":1,"155":1,"162":1,"163":1,"167":1,"228":1,"229":1,"235":1,"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"256":1,"257":1,"258":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"163":1,"164":2,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"236":1,"237":1,"238":1,"239":2,"240":1,"241":2,"242":1,"243":1,"244":2,"245":1,"246":2,"247":1,"248":1,"249":2,"250":2,"251":2,"252":2,"253":1,"254":2,"255":2,"256":1,"257":1,"258":1,"259":1,"260":1},"2":{"73":1,"132":5,"133":9,"134":3,"135":6,"136":4,"137":4,"138":2,"140":2,"141":2,"142":6,"143":4,"144":6,"145":8,"146":3,"147":6,"148":3,"149":1,"150":3,"151":16,"152":12,"153":3,"154":5,"155":2,"156":1,"157":8,"159":2,"161":16,"162":7,"163":6,"165":4,"166":5,"167":4,"168":1,"171":1,"174":1,"176":5,"177":5,"179":6,"180":2,"182":1,"183":2,"184":2,"185":2,"188":1,"189":1,"192":2,"193":2,"194":2,"195":8,"196":3,"197":3,"198":6,"199":6,"200":3,"202":2,"203":2,"204":1,"205":1,"206":1,"207":1,"208":2,"210":1,"212":1,"213":7,"214":2,"216":1,"217":1,"218":3,"219":3,"222":1,"228":5,"229":4,"230":1,"231":7,"232":10,"233":3,"234":8,"235":15,"236":2,"237":1,"238":9,"239":10,"240":11,"241":8,"242":1,"243":3,"244":5,"245":6,"246":8,"247":4,"248":7,"249":2,"250":2,"251":2,"252":2,"253":4,"254":2,"255":1,"256":4,"257":4,"258":5,"259":1,"260":15,"263":2,"264":1,"265":1}}],["obj",{"2":{"90":6,"396":1}}],["objc++",{"2":{"396":1}}],["objc的更多信息",{"2":{"231":1}}],["objc特性的",{"2":{"252":1}}],["objc特性和optional修饰符",{"2":{"250":1}}],["objc特性",{"2":{"250":1}}],["objc特性以及optional修饰符",{"2":{"176":1}}],["objc特性即可",{"2":{"176":1}}],["objcmembers",{"2":{"163":3}}],["objc方法的能力",{"2":{"140":1}}],["objc",{"2":{"46":1,"78":1,"151":1,"152":10,"153":4,"156":3,"163":4,"176":2,"201":4,"231":1,"232":2,"240":1,"245":2,"250":2,"252":1,"260":3,"395":2}}],["over",{"2":{"304":2}}],["override",{"2":{"154":1,"163":1,"198":1}}],["overview",{"2":{"62":1}}],["only",{"2":{"208":1}}],["on",{"0":{"396":1},"2":{"155":1,"208":1,"285":1,"392":1,"396":1}}],["onmesasge",{"2":{"90":2}}],["onmessage",{"2":{"90":8}}],["onopen",{"2":{"90":5}}],["onclick=",{"2":{"90":1}}],["onclose",{"2":{"90":5}}],["once函数包裹初始化代码",{"2":{"203":1}}],["oncetoken",{"2":{"90":2,"203":2}}],["once",{"2":{"90":2,"203":2}}],["onerror",{"2":{"90":3}}],["one",{"2":{"2":1,"283":2}}],["ok",{"2":{"79":1}}],["optionalmethod",{"2":{"250":1}}],["optionalbridging",{"2":{"143":3}}],["optional",{"2":{"86":1,"176":1,"250":1}}],["optionally",{"2":{"73":1}}],["options>",{"2":{"391":1}}],["options宏的",{"2":{"219":1}}],["options宏标注的",{"2":{"218":1,"219":1}}],["optionset",{"2":{"219":1}}],["options",{"2":{"53":5,"61":1,"65":6,"74":1,"103":3,"156":1,"194":3,"198":1,"201":1,"219":4,"306":1}}],["operator+",{"2":{"356":1}}],["operate",{"2":{"2":1}}],["open失败的时候调用",{"2":{"90":1}}],["openurl",{"2":{"65":4,"67":1,"79":1}}],["open",{"2":{"21":1,"90":2,"95":1,"106":1}}],["oslog",{"2":{"190":1}}],["os",{"2":{"50":4,"143":4,"159":2,"190":4}}],["osspinlock",{"2":{"43":3}}],["origin\\thttp",{"2":{"391":4}}],["originproject",{"2":{"389":1}}],["original",{"2":{"384":1}}],["origin",{"2":{"146":6,"386":1,"387":1,"389":1,"390":1,"391":4,"392":1}}],["orientation",{"2":{"36":1}}],["orient",{"2":{"36":4}}],["oray",{"2":{"56":1}}],["or",{"2":{"53":2,"86":3,"95":1,"151":1,"190":1,"208":1,"391":2,"397":1}}],["org",{"2":{"20":2,"57":1,"66":2,"82":2,"90":1,"285":1}}],["oczzdw",{"2":{"16":1}}],["oftype",{"2":{"67":1,"198":2,"206":1}}],["of",{"2":{"2":1,"74":1,"86":2,"103":2,"111":1,"151":1,"268":2,"273":1,"275":1,"278":1,"304":8,"391":2,"392":1,"395":1,"397":1}}],["dubug",{"2":{"397":1}}],["during",{"2":{"190":1}}],["dr",{"2":{"386":1}}],["drag",{"2":{"71":1}}],["dso",{"2":{"190":1}}],["dns",{"2":{"103":1}}],["dlog",{"2":{"92":1}}],["dtds",{"2":{"94":1}}],["dtd",{"2":{"90":2,"94":2}}],["d",{"2":{"46":1,"90":1,"95":1,"190":1,"293":1,"304":1,"386":1,"387":1}}],["dylib",{"2":{"44":1,"74":1}}],["dynamic",{"2":{"25":1,"26":1,"153":2,"201":4}}],["dmg",{"2":{"27":1}}],["dpccvvatsquaxidgmdutjxwkmggy",{"2":{"26":3}}],["dangerlabel",{"2":{"292":1}}],["dangerous",{"2":{"277":2,"291":2}}],["danger",{"2":{"277":2,"291":2,"292":1}}],["darwinboolean",{"2":{"227":1}}],["darken",{"2":{"217":2}}],["darkgray",{"2":{"136":1}}],["dart",{"0":{"25":1},"2":{"23":5}}],["datasource常量的类型为uitableviewdatasource",{"2":{"204":1}}],["datasource",{"2":{"204":2}}],["datamanager",{"2":{"167":1}}],["dataonmessage",{"2":{"90":1}}],["datausingencoding",{"2":{"90":1,"92":1}}],["data",{"0":{"175":1,"270":1,"271":1},"2":{"42":1,"86":1,"90":3,"147":3,"162":1,"175":8,"179":1,"185":1,"198":2,"205":1,"219":2,"268":3,"276":2,"296":6,"297":2,"298":2,"299":2}}],["dateinterval",{"2":{"179":1}}],["datecomponents",{"2":{"179":1}}],["datesbeforedate",{"2":{"183":2}}],["dates",{"2":{"145":2,"183":2}}],["date",{"2":{"3":1,"4":1,"8":1,"9":1,"17":1,"21":1,"26":1,"27":1,"34":1,"36":1,"37":1,"40":1,"42":1,"44":1,"53":1,"54":1,"57":1,"59":1,"61":1,"67":1,"78":1,"86":1,"88":1,"90":1,"95":1,"99":1,"100":1,"139":4,"145":1,"150":1,"179":1,"183":5,"372":1,"377":1,"390":1,"391":1,"397":1}}],["dir",{"2":{"384":1}}],["directory",{"2":{"103":1}}],["digest的验证方式",{"2":{"372":1}}],["digest与ntlm认证都是基于用户名",{"2":{"372":1}}],["diff+",{"2":{"364":1}}],["diff语法",{"0":{"362":1},"1":{"363":1,"364":1},"2":{"308":1}}],["diff",{"2":{"298":1}}],["different",{"2":{"86":1,"397":1}}],["divergence",{"2":{"304":2}}],["dividend",{"2":{"214":2}}],["div>",{"2":{"111":3,"369":1}}],["div",{"2":{"111":3,"293":1,"369":1}}],["dialog",{"2":{"66":6}}],["didreceivechallenge",{"2":{"372":1}}],["didreceivepong",{"2":{"90":1}}],["didreceivemessage",{"2":{"90":1}}],["didclosewithcode",{"2":{"90":1}}],["didfailwitherror",{"2":{"90":1}}],["didfinishlaunchingwithoptions",{"2":{"37":2,"65":2}}],["didfinishdownloadingtourl",{"2":{"16":1}}],["did",{"2":{"66":1,"67":8}}],["dict>",{"2":{"64":2,"94":4}}],["dict",{"2":{"64":1}}],["dictionary",{"2":{"42":1,"66":6,"179":1}}],["display",{"2":{"360":1}}],["dispatch",{"0":{"60":1,"61":1},"2":{"16":1,"43":1,"61":26,"67":8,"79":6,"90":12,"203":2}}],["disable",{"2":{"377":1}}],["disabled宏围住那些遵循",{"2":{"188":1}}],["disable命令",{"2":{"27":1}}],["disconnect",{"2":{"90":4}}],["disconnecttype",{"2":{"90":1}}],["disconnectbyserver",{"2":{"90":1}}],["disconnectbyuser",{"2":{"90":2}}],["distance",{"2":{"214":2}}],["dist",{"2":{"82":1}}],["disturl",{"2":{"82":1}}],["distribution",{"2":{"14":3,"94":2}}],["decimal",{"2":{"179":1}}],["decodable",{"2":{"205":1}}],["decoder",{"2":{"90":2,"205":2}}],["decode",{"2":{"86":1,"90":1,"205":1}}],["decoding",{"2":{"86":1,"205":1}}],["deltas",{"2":{"391":1}}],["delta",{"2":{"155":1,"391":5}}],["deleted",{"2":{"391":2}}],["delete",{"2":{"386":1,"391":4}}],["delegate",{"0":{"59":1},"2":{"58":1,"59":1,"66":1,"67":3,"73":2,"79":1,"90":1,"193":2}}],["deleloper",{"2":{"14":1}}],["dependencies",{"2":{"103":1}}],["deps",{"2":{"103":1}}],["deployment",{"2":{"48":2,"50":2}}],["designated",{"2":{"151":1}}],["destoryheartbeat",{"2":{"90":3}}],["description",{"2":{"66":3,"205":4,"304":2}}],["demonstrates",{"2":{"268":1,"275":1}}],["demo",{"2":{"84":2,"95":2}}],["detailview",{"2":{"391":3}}],["details>",{"2":{"366":2}}],["detailslabel",{"2":{"292":1}}],["details",{"2":{"277":4,"291":4,"292":1}}],["detail",{"2":{"61":2}}],["devisor",{"2":{"214":2}}],["dev",{"2":{"39":1,"88":1,"107":1,"116":3}}],["developers",{"2":{"62":1,"66":1}}],["developer",{"2":{"26":3,"67":1}}],["development",{"2":{"14":5,"23":1,"88":1,"95":8,"190":1}}],["deriveddata",{"2":{"26":3}}],["debug=1",{"2":{"397":1}}],["debugging",{"2":{"190":1}}],["debug",{"0":{"46":1},"2":{"14":2,"46":1,"95":1,"113":1,"190":2,"397":3}}],["defineconfig",{"2":{"292":1,"306":2}}],["defines",{"2":{"244":1,"246":1,"247":1,"260":2}}],["defined",{"2":{"170":1,"397":2}}],["define",{"0":{"45":1,"397":1},"2":{"2":1,"46":2,"52":12,"53":5,"90":1,"92":1,"397":1}}],["defaultmanager",{"2":{"196":1,"197":1}}],["default",{"2":{"2":1,"36":1,"54":1,"143":2,"196":1,"197":1,"218":1,"276":2,"292":1,"293":1,"295":2,"296":6,"297":2,"298":2,"299":2,"300":1,"301":3,"302":5,"304":1,"305":1,"306":1,"397":1}}],["does",{"2":{"222":2}}],["dosomething",{"2":{"144":1,"148":2}}],["dosomethingforclass",{"2":{"144":1}}],["domain",{"2":{"196":2,"198":3,"200":1}}],["dom",{"2":{"97":2,"124":3,"130":1}}],["don",{"2":{"86":1,"397":1}}],["done",{"2":{"73":1,"95":1,"391":6}}],["doc",{"2":{"293":1}}],["dock",{"2":{"209":1}}],["documentation",{"2":{"273":1,"278":1}}],["document",{"2":{"90":2,"92":3,"97":1,"98":1,"194":1,"198":1}}],["documentinteractioncontroller",{"2":{"67":12}}],["doctype",{"2":{"90":1,"94":1}}],["docs",{"2":{"62":1,"73":1,"293":1,"303":4}}],["dolor",{"2":{"66":1}}],["dot",{"2":{"56":2}}],["double",{"2":{"42":1,"179":1,"182":1,"211":2,"222":1,"254":1}}],["downloading",{"2":{"190":1}}],["downloadimagewithurl",{"2":{"61":1}}],["downloaderror",{"2":{"61":1}}],["downloadtask",{"2":{"16":2}}],["download",{"0":{"15":1},"1":{"16":1,"17":1},"2":{"14":2,"71":1}}],["do",{"2":{"2":1,"43":1,"61":6,"86":2,"95":1,"103":2,"196":1,"200":1,"391":1,"392":1}}],["aborts",{"2":{"392":1}}],["aboutvc",{"2":{"391":1}}],["abcrecordsideb",{"2":{"255":1}}],["abcrecordsidea",{"2":{"255":1}}],["abcrecordside",{"2":{"255":1}}],["abc",{"2":{"181":1}}],["ax^2",{"2":{"304":2}}],["a1",{"2":{"155":2}}],["ae",{"2":{"155":1}}],["awesome",{"2":{"113":1,"296":2}}],["awei$",{"2":{"391":7}}],["awei",{"2":{"26":3}}],["available一样",{"2":{"208":1}}],["available特性标记的方法可以安全地使用满足指定平台要求的",{"2":{"208":1}}],["available特性标注自己的",{"2":{"208":1}}],["available特性的语法和",{"2":{"208":1}}],["available",{"2":{"103":1,"208":4,"258":6,"372":2}}],["avi",{"2":{"44":2}}],["attributes",{"2":{"170":2}}],["atindex",{"2":{"137":2}}],["atomic",{"2":{"136":1}}],["atomically",{"2":{"67":2,"79":1}}],["at",{"2":{"86":1,"141":5,"154":1,"195":2,"196":2,"391":1}}],["affinetransform",{"2":{"179":1}}],["afterdelay",{"2":{"155":1}}],["after",{"2":{"90":1}}],["af",{"2":{"86":1,"155":1}}],["already",{"2":{"391":1,"397":2}}],["align=",{"2":{"369":1}}],["aligned",{"2":{"287":2}}],["alt表示图片显示失败时的替换文本",{"2":{"326":1}}],["alt和title即对应html中的alt和title属性",{"2":{"326":1}}],["alt",{"2":{"326":1}}],["altitude",{"2":{"146":2}}],["altool",{"2":{"95":1}}],["altoolpath=",{"2":{"95":1}}],["alpha",{"2":{"134":2,"155":1,"257":5}}],["allkeysforobject",{"2":{"155":1}}],["all",{"2":{"103":1,"213":1,"389":1,"391":4}}],["allow",{"2":{"116":3}}],["allowed",{"2":{"50":2}}],["alloc",{"2":{"16":1,"54":2,"66":7,"67":2,"73":2,"74":1,"90":3,"92":2,"133":1,"194":1,"203":1,"248":1}}],["alertutil",{"2":{"391":6}}],["alert",{"2":{"90":1,"98":1}}],["alertcontrollerwithtitle",{"2":{"79":1}}],["alertcontroller",{"2":{"79":3}}],["asreadonlybuffer",{"2":{"90":1}}],["associated",{"2":{"391":1}}],["assume",{"2":{"142":4}}],["assurance",{"2":{"88":1}}],["assets",{"2":{"109":1}}],["assign",{"2":{"90":1}}],["as",{"2":{"73":1,"138":6,"139":5,"143":2,"154":1,"181":2,"182":3,"196":1,"198":1,"200":1,"204":3,"206":1,"224":1,"391":1,"392":1}}],["async",{"2":{"16":1,"61":4,"67":4,"79":3,"90":5}}],["amount",{"2":{"217":3}}],["amend",{"2":{"385":2}}],["amenities",{"2":{"184":2}}],["amet",{"2":{"66":1}}],["am",{"2":{"73":1}}],["amp",{"0":{"127":1},"2":{"8":10,"14":1,"165":1,"219":1}}],["anchor",{"2":{"280":1,"281":2,"306":4}}],["another",{"2":{"244":1}}],["anotherprotocol",{"2":{"165":1}}],["anotherprotocol这种协议组合的形式",{"2":{"165":1}}],["animal",{"2":{"156":6}}],["animated",{"2":{"67":3,"73":1,"79":2}}],["anything",{"2":{"397":1}}],["anyclass",{"2":{"167":1}}],["anyhashable由任意hashable类型隐式转换而来",{"2":{"150":1}}],["anyhashable>",{"2":{"150":1,"184":1}}],["anyhashable",{"2":{"150":1,"184":1,"185":2}}],["anyobject",{"2":{"140":1,"141":1,"145":1,"169":1}}],["any",{"0":{"139":1},"2":{"132":1,"138":1,"139":1,"142":9,"143":2,"150":1,"183":2,"185":2,"198":2,"391":1}}],["antd",{"0":{"128":1}}],["angular",{"0":{"104":1,"105":1},"1":{"105":1,"106":1,"107":1,"108":1,"109":1,"110":1,"111":1,"112":1,"113":1,"114":1},"2":{"103":2,"105":1,"110":1,"113":1}}],["an",{"2":{"86":3,"103":1,"143":2,"151":2,"277":2,"291":2,"392":2}}],["annotation",{"2":{"65":4}}],["andreturnerror",{"2":{"151":1,"195":1}}],["android",{"2":{"33":1}}],["and",{"2":{"2":1,"42":1,"71":2,"73":1,"86":3,"103":1,"205":1,"206":1,"268":2,"296":2,"304":2,"391":4,"392":3,"397":3}}],["audio",{"2":{"44":1}}],["autolayouttrace",{"2":{"396":2}}],["automatic",{"2":{"391":1}}],["autoreleasingunsafemutablepointer",{"2":{"223":1,"224":1,"226":1}}],["autoreleasepool标记",{"2":{"207":1}}],["autoreleasepool",{"2":{"36":1,"207":1}}],["auto",{"2":{"90":2,"391":13}}],["author",{"2":{"3":1,"4":1,"8":1,"9":1,"17":1,"21":1,"26":1,"27":1,"34":1,"36":1,"37":1,"40":1,"44":1,"53":1,"54":1,"57":1,"59":1,"61":1,"67":1,"78":1,"86":1,"88":1,"90":1,"95":1,"100":1,"372":1,"377":1,"390":1,"397":1}}],["ac",{"2":{"86":1}}],["acceptance",{"2":{"88":1}}],["access",{"2":{"64":2,"86":1,"268":1}}],["accounts",{"2":{"74":1}}],["accountswithaccounttype",{"2":{"74":1}}],["accounttypewithaccounttypeidentifier",{"2":{"74":1}}],["acaccounttypeidentifiertwitter",{"2":{"74":1}}],["acaccounttype",{"2":{"74":1}}],["acaccountstore",{"2":{"74":2}}],["action",{"0":{"169":1},"2":{"92":1,"110":3,"154":3,"168":1,"169":1,"396":1}}],["actionwithtitle",{"2":{"79":1}}],["actions",{"2":{"66":2,"162":1,"169":1}}],["actions==",{"2":{"66":1}}],["action权限",{"2":{"63":1}}],["active",{"2":{"14":1}}],["acrobat",{"2":{"44":1}}],["adetaildescriptioncell",{"2":{"391":1}}],["adetailnamecell",{"2":{"391":1}}],["adetailreasoncell",{"2":{"391":1}}],["adecoder",{"2":{"164":1}}],["adopting",{"2":{"229":1}}],["adobe",{"2":{"44":2}}],["admin",{"2":{"113":1}}],["advanced",{"2":{"103":1,"207":1}}],["address",{"2":{"383":1}}],["added",{"2":{"298":2,"396":1}}],["additional",{"2":{"190":1,"276":1}}],["addingtimeinterval",{"2":{"140":1}}],["adddatesparsedfromtimestamps",{"2":{"183":2}}],["addfriends",{"2":{"175":1}}],["addfriendsobject",{"2":{"175":1}}],["addobserver",{"2":{"156":1}}],["addoperationwithblock",{"2":{"16":1}}],["addtarget",{"2":{"154":1}}],["addtimer",{"2":{"90":1}}],["addline",{"2":{"146":2}}],["addaction",{"2":{"79":1}}],["add",{"2":{"71":2,"83":1,"90":1,"293":1,"304":1,"384":4,"389":1,"391":4,"397":1}}],["addsubview",{"2":{"66":1,"76":1,"92":1}}],["apis",{"2":{"268":1,"273":1}}],["api",{"0":{"132":1,"167":1,"208":1,"210":1,"258":1,"268":1},"1":{"133":1,"134":1,"135":1,"136":1,"137":1,"138":1,"139":1,"140":1,"141":1,"142":1,"143":1,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":1,"153":1,"154":1,"155":1,"156":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"269":1,"270":1,"271":1,"272":1,"273":1},"2":{"64":1,"66":2,"71":1,"132":1,"143":1,"151":1,"152":1,"153":3,"155":1,"156":1,"157":2,"161":7,"162":1,"167":1,"177":1,"179":2,"188":2,"189":3,"190":1,"192":1,"208":6,"217":1,"232":2,"235":1,"238":1,"256":1,"258":4,"260":1,"263":2,"268":1}}],["apt",{"2":{"24":1,"40":1}}],["apns",{"2":{"14":5}}],["apos",{"2":{"8":1}}],["apache",{"2":{"4":1}}],["approval",{"2":{"391":3}}],["appropriatefor",{"2":{"197":1}}],["appropriateforurl",{"2":{"197":2}}],["appropriate",{"2":{"86":1}}],["appkit",{"2":{"177":1}}],["appendchild",{"2":{"92":2}}],["appcardconfigurationwithpromoimage",{"2":{"73":1}}],["appdelegate",{"2":{"65":1,"395":1}}],["appdelegate的主要作用就是处理",{"2":{"37":1}}],["app第一次启动完毕后就会调用",{"2":{"37":1}}],["app容易受到干扰",{"2":{"37":1}}],["appname",{"2":{"14":5}}],["apple",{"2":{"9":4,"14":4,"27":1,"73":1,"94":2}}],["applicationwillterminate",{"2":{"37":2}}],["applicationwillresignactive",{"2":{"37":1}}],["applicationwillenterforeground",{"2":{"37":2}}],["applicationdidbecomeactive",{"2":{"37":2}}],["applicationdidreceivememorywarning",{"2":{"37":1}}],["applicationdidenterbackground",{"2":{"37":3}}],["applications",{"2":{"27":1,"95":2}}],["application",{"2":{"2":2,"37":4,"65":10,"92":1,"95":1,"103":1,"159":1}}],["appstore",{"0":{"9":1}}],["app",{"0":{"10":1,"13":1,"37":1,"59":1},"1":{"11":1,"12":1,"13":1,"14":1},"2":{"2":1,"9":4,"13":2,"14":6,"27":1,"58":1,"59":1,"64":6,"65":4,"67":4,"79":1,"95":6,"103":5,"113":1,"117":5,"209":2,"397":1}}],["armv7",{"0":{"395":1},"2":{"395":3}}],["argv",{"2":{"356":1}}],["argc",{"2":{"356":1}}],["argument",{"2":{"209":2}}],["argumentname",{"2":{"209":2}}],["arguments的第一个元素总是可执行文件的路径",{"2":{"209":1}}],["arguments获取应用程序启动时指定的一系列命令行参数",{"2":{"209":1}}],["arguments",{"2":{"206":1,"209":2,"215":3}}],["args",{"2":{"46":1,"356":1}}],["architecture",{"0":{"395":1},"2":{"395":3}}],["archivepath",{"2":{"95":2}}],["archive",{"2":{"44":2,"95":1}}],["arc4random",{"2":{"67":2,"79":1}}],["array>",{"2":{"64":6,"79":2}}],["array",{"2":{"42":1,"74":3,"99":1,"151":1,"155":2,"179":1}}],["arbitrary",{"2":{"2":1}}],["area",{"2":{"146":3}}],["are",{"2":{"2":2,"86":1,"287":4,"296":2,"304":4,"358":2}}],["a",{"2":{"2":1,"20":1,"71":1,"86":8,"95":1,"103":2,"190":1,"200":2,"201":1,"205":3,"225":4,"239":1,"252":1,"257":3,"277":8,"286":1,"291":8,"293":1,"356":1,"360":1,"379":1,"385":1,"386":1,"391":1,"392":4,"397":1}}],["ssh",{"2":{"380":12}}],["ssl安全通道建立",{"2":{"371":1}}],["ssl的握手部分结束",{"2":{"371":1}}],["snippet",{"2":{"301":9,"302":5}}],["snippets",{"2":{"301":6,"302":2}}],["swfit",{"2":{"197":1,"219":2,"239":1}}],["swift在1726年关于大小端之争历史的描述",{"2":{"350":1}}],["swift的",{"2":{"350":1}}],["swift宏",{"2":{"257":1}}],["swift宏标记",{"2":{"257":1}}],["swiftmethod",{"2":{"248":1}}],["swiftmyobject",{"2":{"141":1}}],["swiftmytableview",{"2":{"137":2}}],["swiftmytextfield",{"2":{"136":1}}],["swiftobject",{"2":{"248":2}}],["swiftos",{"2":{"190":1}}],["swift小节",{"2":{"234":1,"241":1,"246":1,"260":1}}],["swift文件替换对应的",{"2":{"230":1}}],["swift文件中",{"2":{"159":1}}],["swiftunion",{"2":{"220":1}}],["swiftpublic",{"2":{"216":1,"219":1}}],["swiftprintf",{"2":{"215":2}}],["swiftfor",{"2":{"209":1}}],["swiftfunc",{"2":{"144":1,"189":1,"195":1,"200":1,"214":1,"215":1,"224":2,"225":2,"226":1,"227":1}}],["swiftstruct",{"2":{"205":1,"213":2,"218":1}}],["swiftself",{"2":{"148":1}}],["swiftdo",{"2":{"196":1}}],["swiftlazy",{"2":{"194":2}}],["swiftlet",{"2":{"133":2,"134":1,"139":3,"143":1,"147":1,"155":2,"156":1,"167":1,"183":1,"184":1,"185":1,"189":1,"190":1,"196":1,"197":1,"205":1,"206":1,"208":3,"218":1,"219":1,"222":1,"239":1,"244":1}}],["swiftenum",{"2":{"218":1}}],["swiftet",{"2":{"190":1}}],["swiftextension",{"2":{"146":2,"213":1,"217":1,"257":1}}],["swiftrequired",{"2":{"164":1}}],["swift来创建一个新的",{"2":{"159":1}}],["swiftclass",{"2":{"145":1,"151":1,"156":1,"165":1,"169":1,"193":1,"198":1,"201":2,"203":2}}],["swiftvar",{"2":{"138":1,"140":1,"142":1,"144":1,"145":1,"150":1,"165":1,"183":1,"184":1,"185":1,"194":1,"220":1,"222":1,"224":2,"225":2,"226":1,"232":1}}],["swiftimport",{"2":{"154":1,"161":1,"163":1,"175":1,"176":1,"181":1,"182":1,"190":1,"207":1,"247":1}}],["swiftif",{"2":{"135":1,"204":3,"206":1,"258":1}}],["swiftinit",{"2":{"133":1}}],["swift",{"0":{"151":1,"152":1,"158":1,"159":1,"161":1,"162":1,"167":1,"228":1,"235":1,"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"256":1},"1":{"152":1,"153":1,"159":1,"160":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"236":1,"237":1,"238":1,"239":2,"240":1,"241":2,"242":1,"243":1,"244":2,"245":1,"246":2,"247":1,"248":1,"249":2,"250":2,"251":2,"252":2,"253":1,"254":2,"255":2,"256":1,"257":1,"258":1,"259":1,"260":1},"2":{"132":6,"133":10,"134":2,"135":2,"136":7,"137":3,"138":4,"140":1,"141":3,"142":7,"143":4,"144":4,"145":8,"146":2,"147":7,"148":2,"149":3,"150":5,"151":17,"152":11,"153":4,"154":1,"156":2,"157":12,"158":2,"159":6,"160":6,"161":18,"162":5,"163":6,"165":3,"166":11,"167":10,"168":3,"169":3,"170":1,"171":1,"172":2,"173":2,"174":2,"175":2,"176":2,"177":8,"179":8,"180":3,"181":2,"182":5,"183":6,"184":7,"185":7,"186":4,"187":2,"188":1,"189":3,"190":1,"191":1,"192":3,"193":2,"194":2,"195":11,"196":2,"197":1,"198":5,"199":3,"200":1,"201":2,"202":3,"203":2,"204":3,"205":3,"206":2,"207":1,"208":4,"210":1,"211":4,"212":2,"213":7,"214":3,"215":2,"216":4,"217":14,"218":8,"219":5,"220":6,"221":3,"222":1,"223":7,"226":1,"227":6,"228":4,"229":2,"230":3,"231":8,"232":6,"233":3,"234":6,"235":13,"236":2,"237":1,"238":4,"239":5,"240":10,"241":7,"242":1,"243":1,"244":5,"245":11,"246":7,"247":3,"248":5,"249":3,"250":2,"251":3,"252":7,"253":5,"254":8,"255":4,"256":6,"257":7,"258":5,"259":1,"260":15,"263":1,"264":1,"265":1,"396":1}}],["switch",{"2":{"36":1,"54":1}}],["symbolic",{"2":{"396":1}}],["symbols",{"2":{"395":2}}],["symbol",{"0":{"395":1},"2":{"395":1}}],["syntax",{"0":{"276":1},"2":{"276":1}}],["synthesize",{"2":{"176":1}}],["system",{"2":{"53":5,"88":4,"90":1}}],["systemversion",{"2":{"53":6}}],["squirrel",{"2":{"152":1}}],["squareroot",{"2":{"146":2}}],["sqrt",{"2":{"146":1,"215":1,"304":2}}],["sqlite3",{"2":{"44":1}}],["sqlite",{"2":{"42":1,"44":6}}],["srcdir",{"2":{"301":1,"303":1}}],["src",{"2":{"109":1,"110":1}}],["srwebsocketdelegate",{"2":{"90":1}}],["srwebsocketdelegate>",{"2":{"90":1}}],["srwebsocket",{"2":{"90":7}}],["slug",{"2":{"103":1}}],["slug>",{"2":{"103":1}}],["spctl",{"2":{"377":1}}],["sprinkles",{"2":{"222":5}}],["spritekit",{"2":{"161":1}}],["spa",{"2":{"130":1}}],["specific",{"2":{"200":3,"397":1}}],["specificerror2",{"2":{"200":3}}],["specificerror1",{"2":{"200":2}}],["specified",{"2":{"86":2}}],["specify",{"2":{"103":3}}],["specs",{"2":{"83":2}}],["split",{"2":{"86":1}}],["shnpm",{"2":{"304":1}}],["sh$",{"2":{"293":1}}],["shiki",{"2":{"276":1,"295":3}}],["shortname",{"2":{"389":4}}],["short",{"2":{"211":2}}],["shouldcomponentupdate",{"2":{"124":1}}],["should",{"2":{"95":1,"196":1}}],["shows",{"2":{"395":1}}],["showtwittersessionshare",{"2":{"73":1}}],["showtwittercompose",{"2":{"73":1,"74":1}}],["showfromviewcontroller",{"2":{"73":1}}],["showalterwithstr",{"2":{"67":4,"79":4}}],["show",{"2":{"66":1,"73":1,"90":2,"387":1,"389":1}}],["sh",{"2":{"95":1}}],["shell",{"2":{"95":1}}],["sharetowhatsappwithimg",{"2":{"79":1}}],["sharetowhatsappwithtxt",{"2":{"79":1}}],["sharetoinstagrambydocumentnnamewith",{"2":{"67":1}}],["sharetoinstagrambydocumentimage",{"2":{"67":1}}],["sharetoinstagrambyimage",{"2":{"67":1}}],["share",{"0":{"68":1},"2":{"66":1,"73":2}}],["sharecontent",{"2":{"66":3}}],["sharebutton",{"2":{"66":4}}],["shared",{"2":{"90":2}}],["sharedinstance",{"2":{"65":3,"73":1,"203":6}}],["sharedmanager",{"2":{"61":1}}],["sharedapplication",{"2":{"59":1,"67":5,"79":3}}],["sharing",{"2":{"62":1,"67":1}}],["svc",{"2":{"59":9}}],["s",{"0":{"395":1},"2":{"46":1,"57":1,"65":2,"143":1,"304":2,"391":2,"392":1,"395":1,"397":3}}],["sdimagecachetype",{"2":{"61":1}}],["sdwebimagelowpriority",{"2":{"61":1}}],["sdwebimageretryfailed",{"2":{"61":1}}],["sdwebimagemanager",{"2":{"61":1}}],["sdwebimage",{"2":{"44":1}}],["sdk中定义的分享按钮如下图",{"2":{"66":1}}],["sdk",{"2":{"23":2,"48":2,"63":5,"160":2}}],["sauna",{"2":{"184":1}}],["saurik",{"2":{"24":1,"40":1}}],["sara",{"2":{"120":1}}],["safe",{"2":{"90":4}}],["safari",{"2":{"39":1,"63":1}}],["save",{"2":{"82":1,"85":1,"107":2,"116":1,"130":1,"392":1}}],["savepath",{"2":{"67":6,"79":3}}],["simple",{"2":{"392":1}}],["simplecake",{"2":{"222":3}}],["singleton",{"2":{"203":5}}],["since",{"2":{"2":1}}],["silver",{"2":{"185":1}}],["signed",{"2":{"211":1}}],["sign",{"2":{"86":1,"397":1}}],["site",{"2":{"268":1}}],["sit",{"2":{"66":1,"88":1}}],["sidemenu",{"2":{"103":1}}],["side",{"2":{"59":1}}],["size",{"2":{"36":18,"61":2,"190":1}}],["scnvector4",{"2":{"191":1}}],["scnvector3",{"2":{"191":1}}],["scnmatrix4",{"2":{"191":1}}],["schroedingerscat",{"2":{"220":3}}],["schoolsupplies",{"2":{"183":2}}],["scheduledtimerwithtimeinterval",{"2":{"90":1}}],["scheme名",{"2":{"95":1}}],["scheme或者document",{"2":{"67":1}}],["scheme",{"2":{"64":5,"67":1,"79":2,"95":5,"196":1}}],["scrollview",{"2":{"77":4}}],["scrollviewdidscroll",{"2":{"77":1}}],["script>",{"2":{"90":2,"268":1}}],["script",{"2":{"2":2,"71":1,"268":1}}],["scaleratio",{"2":{"36":5}}],["scoket+xml",{"2":{"33":1}}],["so",{"2":{"392":1,"397":1}}],["solutions",{"2":{"304":2}}],["something",{"2":{"397":1}}],["some",{"2":{"200":1,"268":1,"275":1,"303":1,"358":2}}],["someprotocol",{"2":{"165":2}}],["somevalue",{"2":{"143":2}}],["songs",{"2":{"151":3}}],["song",{"2":{"151":2}}],["socketmanager",{"2":{"90":7}}],["socket+protocol",{"2":{"33":1}}],["socket",{"2":{"33":1,"323":1}}],["socketrocket",{"2":{"33":1,"90":2}}],["sourceapplication",{"2":{"65":6}}],["source",{"2":{"20":1,"23":3,"83":1,"159":1,"231":1,"238":1}}],["sources",{"2":{"20":3,"395":1}}],["suggested",{"2":{"396":1}}],["sure",{"2":{"391":2,"397":1}}],["summary>",{"2":{"366":1}}],["summary>linux环境",{"2":{"366":1}}],["suffix",{"2":{"185":2}}],["super",{"2":{"92":1,"154":2,"201":1}}],["supportedlocales",{"2":{"145":2}}],["supported",{"2":{"90":1}}],["support",{"2":{"27":1,"95":1}}],["subsystem",{"2":{"190":1}}],["submit",{"2":{"92":1,"397":1}}],["subcomponent",{"2":{"86":2}}],["subtitle",{"2":{"86":1,"218":1,"239":1,"244":1}}],["sudo",{"2":{"82":3,"102":1,"105":1,"116":3,"377":1}}],["success",{"2":{"61":1,"196":2}}],["such",{"2":{"2":1,"196":1}}],["skia",{"2":{"23":1}}],["skip",{"2":{"21":1,"106":1}}],["search",{"2":{"397":1}}],["sent",{"2":{"208":1}}],["sender",{"2":{"154":2,"169":1}}],["sendtext",{"2":{"90":1}}],["sendping的时候",{"2":{"90":1}}],["sendpingerror=",{"2":{"90":1}}],["sendping",{"2":{"90":1}}],["sendheartmessage",{"2":{"90":2}}],["sendmessage",{"2":{"90":3}}],["send",{"2":{"79":1,"90":5}}],["serialized",{"2":{"198":1}}],["serializeddocument",{"2":{"198":2}}],["serve",{"2":{"21":1,"106":1}}],["serverendpoint",{"2":{"90":2}}],["server",{"2":{"14":1,"90":1,"116":2}}],["services",{"2":{"113":3}}],["service",{"2":{"14":1,"113":4}}],["see",{"2":{"103":1,"395":1}}],["sec",{"2":{"90":1}}],["sections",{"2":{"391":11}}],["section",{"2":{"2":1,"395":1}}],["setnewpwdvc",{"2":{"391":1}}],["setting",{"2":{"247":1,"259":1,"260":2}}],["settings中指定的路径",{"2":{"239":1}}],["settings",{"2":{"239":1,"244":1,"246":1,"397":1}}],["setter",{"2":{"217":2}}],["setter=",{"2":{"136":1}}],["settext",{"2":{"73":1}}],["setcacheexpirations",{"2":{"185":2}}],["setcontentoffset",{"2":{"77":1}}],["setstate",{"0":{"125":1},"2":{"125":1}}],["setinterval或者发送ajax请求等操作",{"2":{"124":1}}],["setattribute",{"2":{"92":5}}],["sethttpbody",{"2":{"92":1}}],["sethttpmethod",{"2":{"92":1}}],["setvalue",{"2":{"92":2}}],["setdelegateoperationqueue",{"2":{"90":1}}],["set",{"2":{"73":1,"82":2,"86":1,"90":2,"150":2,"151":2,"179":1,"184":4,"217":1,"220":2,"386":1,"389":3,"391":1,"397":2}}],["seturl",{"2":{"73":1}}],["setup>",{"2":{"268":1}}],["setup",{"2":{"20":1}}],["selector表达式相同的语法",{"2":{"217":1}}],["selector表达式创建一个选择器",{"2":{"154":1}}],["selector",{"2":{"78":1,"90":2,"154":4,"155":6,"156":1,"208":2,"293":1}}],["selectedviewcontroller",{"2":{"59":1}}],["self",{"0":{"148":1},"2":{"66":4,"67":22,"73":3,"74":1,"76":2,"79":6,"90":35,"92":5,"132":1,"146":1,"148":6,"151":1,"154":1,"156":1,"194":1,"198":1,"203":1,"205":2,"217":3}}],["semaphore",{"2":{"43":1}}],["sessionstore",{"2":{"73":1}}],["session",{"2":{"16":1,"73":3,"90":21}}],["stuff",{"2":{"303":3}}],["stop",{"2":{"292":2}}],["storyboards",{"2":{"164":1}}],["storgeservice",{"2":{"113":4}}],["storge",{"2":{"113":5}}],["storage",{"2":{"23":2}}],["store",{"0":{"10":1},"1":{"11":1,"12":1,"13":1,"14":1},"2":{"14":1,"74":4,"95":3}}],["steam",{"2":{"184":1}}],["style",{"2":{"79":1,"133":5}}],["standard",{"2":{"139":1}}],["stack",{"2":{"74":1}}],["stackoverflow",{"2":{"59":1,"395":1,"396":1}}],["starting",{"2":{"392":1}}],["started",{"2":{"303":3}}],["starter",{"2":{"103":2}}],["start",{"2":{"103":4,"117":2}}],["startwithcompletionhandler",{"2":{"66":1}}],["startbootstrap",{"2":{"1":1}}],["state",{"0":{"123":1},"2":{"54":3}}],["static",{"2":{"26":1,"90":7,"198":1,"203":4,"213":8,"217":2,"219":6,"252":1,"356":1}}],["status",{"2":{"14":1,"388":1}}],["stripes",{"2":{"287":2,"358":2}}],["string类型的值会被自动转换为",{"2":{"224":1}}],["strings",{"2":{"206":1}}],["string2",{"2":{"189":1}}],["string1",{"2":{"189":1}}],["stringliteral",{"2":{"181":3}}],["stringbyaddingtwostrings",{"2":{"189":3}}],["stringbyaddingpercentescapesusingencoding",{"2":{"86":1}}],["stringbyaddingpercentencodingwithallowedcharacters",{"2":{"79":1,"86":2}}],["stringbyappendingpathcomponent",{"2":{"67":2,"79":1}}],["stringwithformat",{"2":{"67":2,"79":2,"90":1,"92":3}}],["string>p",{"2":{"94":1}}],["string>manual",{"2":{"94":1}}],["string>iphone",{"2":{"94":1}}],["string>instagram",{"2":{"64":1}}],["string>demouat",{"2":{"94":1}}],["string>enterprise",{"2":{"94":1}}],["string>export",{"2":{"94":1}}],["string>weixin",{"2":{"64":1}}],["string>wechat",{"2":{"64":1}}],["string>whatsapp",{"2":{"64":1,"79":1}}],["string>",{"2":{"64":15,"79":1,"94":6,"150":1,"151":2,"184":3}}],["string>fbshareextension",{"2":{"64":1}}],["string>fbauth2",{"2":{"64":1}}],["string>fbapi",{"2":{"64":1}}],["string>fb",{"2":{"64":2}}],["string",{"2":{"3":2,"42":1,"86":4,"90":4,"99":1,"138":5,"139":1,"143":2,"145":1,"150":1,"151":4,"152":1,"154":1,"155":2,"156":2,"175":1,"179":1,"181":5,"183":1,"185":1,"194":1,"198":3,"205":3,"206":1,"213":2,"215":3,"219":1,"226":1,"356":3}}],["str2",{"2":{"189":1}}],["str1",{"2":{"189":1}}],["strongself",{"2":{"148":2}}],["strong",{"2":{"90":2,"136":1,"148":1,"151":1,"176":1,"223":1}}],["strongly",{"2":{"2":1}}],["stress",{"2":{"88":1}}],["str",{"2":{"79":4,"86":3,"90":2}}],["struct和union类型既可以定义匿名字段",{"2":{"222":1}}],["struct",{"2":{"53":1,"214":3,"216":2,"219":1,"220":1,"222":1}}],["mjs",{"2":{"293":1}}],["m文件中",{"2":{"241":1}}],["m文件",{"2":{"234":1,"241":1,"245":1,"246":2,"247":1,"251":1}}],["m文件在target",{"2":{"233":1}}],["m和",{"2":{"230":1,"231":1,"233":1}}],["mkcoordinatespan",{"2":{"191":1}}],["mkdir",{"2":{"95":1}}],["mdit",{"2":{"306":3}}],["mdwhen",{"2":{"304":1}}],["mdsome",{"2":{"303":2}}],["md```ts",{"2":{"300":1}}],["md```js",{"2":{"276":1}}],["md>",{"2":{"294":1}}],["md",{"2":{"155":1,"268":2,"277":1,"283":12,"291":1,"292":1,"293":1,"301":6,"302":2,"303":8,"306":2,"329":1}}],["msg=",{"2":{"90":2}}],["msg",{"2":{"90":8,"92":1,"276":2,"296":6,"297":2,"298":4,"299":4,"392":1}}],["msgurl",{"2":{"79":2}}],["mirror",{"2":{"391":2}}],["mirrors",{"2":{"83":2}}],["mittens",{"2":{"220":5}}],["mixin",{"2":{"85":1}}],["minorversion",{"2":{"53":1}}],["min",{"2":{"50":2}}],["myh1",{"2":{"356":1}}],["myothercell",{"2":{"244":2}}],["myobjcclass",{"2":{"249":2,"251":3}}],["myobjecttoobserve",{"2":{"201":5}}],["myobject",{"2":{"140":4,"141":5}}],["myobserver",{"2":{"201":2}}],["myerror",{"2":{"200":4}}],["myerrordomain",{"2":{"200":5}}],["mywindow",{"2":{"193":3}}],["mydelegate",{"2":{"193":2}}],["mydate",{"2":{"139":3,"201":7}}],["mygreatapp",{"2":{"167":1}}],["mypersonclass",{"2":{"167":1}}],["myframework框架中的datamanager类在",{"2":{"167":1}}],["myswiftprotocol>",{"2":{"249":1,"251":1}}],["myswiftprotocol",{"2":{"249":1,"250":1}}],["myswiftclass",{"2":{"248":1,"249":2}}],["myswiftviewcontroller",{"2":{"163":1,"165":1}}],["mysize",{"2":{"193":1}}],["mysubview",{"2":{"137":2}}],["mybutton",{"2":{"154":3}}],["myviewcontroller",{"2":{"154":4,"169":1,"258":1}}],["mycell",{"2":{"239":2}}],["mycustomcontroller",{"2":{"176":2}}],["mycustomprotocol>",{"2":{"176":1}}],["mycustomprotocol",{"2":{"176":1}}],["mycustomview",{"2":{"170":1}}],["mycomponent",{"2":{"295":2}}],["mycontroller",{"2":{"144":2}}],["mycount",{"2":{"141":2}}],["mycount常量会被推断为int",{"2":{"141":1}}],["mychar",{"2":{"141":2}}],["myimage",{"2":{"135":1}}],["mytextfield",{"2":{"133":1,"136":1}}],["mytableview",{"2":{"133":2,"137":1}}],["myapp",{"2":{"103":3,"260":1}}],["myrefid",{"2":{"66":1}}],["my",{"2":{"66":1,"103":1,"117":3,"281":2,"356":1}}],["mpg",{"2":{"44":2}}],["mpeg",{"2":{"44":2}}],["merging",{"2":{"391":14}}],["merges",{"2":{"392":1}}],["merge",{"2":{"386":1,"391":3,"392":2}}],["meridian",{"2":{"39":1}}],["meridia",{"2":{"39":1}}],["membership选择框中的勾选取消",{"2":{"233":1}}],["memory",{"2":{"189":1,"207":1}}],["memorymanagedresult",{"2":{"189":2}}],["mei",{"2":{"206":2}}],["medalrankings",{"2":{"185":2}}],["media",{"2":{"44":1,"70":1}}],["measurement",{"2":{"179":1}}],["measge",{"2":{"90":3}}],["meta",{"2":{"90":1}}],["method",{"2":{"78":1,"86":1,"92":3,"153":1}}],["menlo",{"2":{"66":2}}],["messagedisposition",{"2":{"218":5}}],["messagedispositiondeleted",{"2":{"218":2}}],["messagedispositionread",{"2":{"218":2}}],["messagedispositionunread",{"2":{"218":2}}],["message",{"2":{"66":1,"79":1,"90":13,"190":1,"385":3,"392":3}}],["messenger",{"2":{"64":1}}],["me",{"2":{"66":2,"143":2}}],["mmap",{"2":{"44":4}}],["mutablearray",{"2":{"227":1}}],["mutex",{"2":{"43":1}}],["multiplicand",{"2":{"214":2}}],["multiplier",{"2":{"214":2}}],["must",{"2":{"2":1,"73":1,"397":1}}],["m",{"2":{"36":5,"59":1,"65":1,"90":1,"217":3,"251":1,"385":3,"391":17,"392":1,"395":1,"397":1}}],["mqtt",{"2":{"33":1}}],["mqttkit",{"2":{"33":1}}],["motd",{"2":{"296":2}}],["mordern",{"2":{"229":1}}],["more",{"0":{"273":1,"278":1},"2":{"61":1}}],["mounting",{"2":{"124":1}}],["modal",{"2":{"392":2}}],["modified",{"2":{"391":2}}],["modify",{"2":{"391":2}}],["module设置为yes",{"2":{"244":1,"246":1,"247":1}}],["module",{"2":{"175":2,"259":1,"260":3}}],["modules",{"2":{"113":1}}],["modes",{"2":{"155":1}}],["model",{"2":{"97":2,"175":1}}],["modelarray",{"2":{"61":1}}],["mode=release",{"2":{"95":3}}],["mode",{"2":{"66":1,"95":5,"392":2}}],["mozwebsocket",{"2":{"90":2}}],["mobileassistant",{"2":{"391":18}}],["mobile",{"2":{"67":1}}],["mobileprovision",{"2":{"14":2}}],["moveitem",{"2":{"196":2}}],["moveitematurl",{"2":{"196":1}}],["move",{"2":{"146":1}}],["mov",{"2":{"44":1}}],["mongodb也有同样的问题",{"2":{"44":1}}],["mojave",{"2":{"27":1}}],["m与",{"2":{"26":1}}],["mt=8",{"2":{"9":5}}],["mvvm`",{"2":{"391":1}}],["mvvm",{"2":{"391":1}}],["mv",{"2":{"4":1,"384":1}}],["make",{"2":{"392":1,"397":1}}],["makewkwebviewpostrequestwithurl",{"2":{"92":2}}],["master",{"2":{"326":1,"377":1,"391":13,"392":1}}],["mathbf",{"2":{"304":22}}],["math",{"2":{"304":2}}],["mathjax3",{"2":{"304":2}}],["may",{"2":{"190":2}}],["mac",{"0":{"376":1},"1":{"377":1},"2":{"167":1,"392":1}}],["macosx",{"2":{"258":1}}],["macosapplicationextension",{"2":{"208":1}}],["macos",{"2":{"160":1,"190":1,"208":4,"231":1,"238":1,"258":1,"377":1}}],["macros",{"0":{"397":1},"2":{"397":1}}],["macro",{"0":{"45":1},"2":{"397":4}}],["markdown是支持html语法的",{"2":{"365":1}}],["markdown基础语法",{"0":{"307":1},"1":{"308":1,"309":1,"310":1}}],["markdownitfoo",{"2":{"306":2}}],["markdownitanchor",{"2":{"306":2}}],["markdown",{"0":{"274":1,"275":1,"279":1,"303":1},"1":{"276":1,"277":1,"278":1,"280":1,"281":1,"282":1,"283":1,"284":1,"285":1,"286":1,"287":1,"288":1,"289":1,"290":1,"291":1,"292":1,"293":1,"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"301":1,"302":1,"303":1,"304":1,"305":1,"306":1},"2":{"275":1,"278":1,"279":1,"280":1,"289":2,"292":1,"295":1,"300":1,"303":3,"304":3,"305":2,"306":10,"307":1}}],["mark",{"2":{"90":1}}],["management",{"2":{"189":2,"207":1}}],["manager",{"2":{"2":6}}],["man",{"2":{"73":1}}],["manual",{"2":{"69":1}}],["majorversion",{"2":{"53":1}}],["maxwell",{"2":{"304":2}}],["maxconcurrentoperationcount",{"2":{"90":1}}],["max",{"2":{"50":2,"52":2}}],["mainbundle",{"2":{"26":1,"67":1,"194":1}}],["main",{"2":{"16":1,"61":5,"67":2,"79":2,"90":6,"194":1,"206":1,"268":1,"306":1,"356":2,"391":1}}],["mainqueue",{"2":{"16":2}}],["maven3",{"2":{"4":2}}],["maven",{"0":{"4":1},"2":{"4":6}}],["wq",{"2":{"392":1}}],["w",{"2":{"392":1}}],["would",{"2":{"392":1}}],["wordy",{"2":{"358":2}}],["wordsmatchingpredicate",{"2":{"184":2}}],["words",{"2":{"184":4}}],["world",{"2":{"66":1,"136":1}}],["works",{"2":{"268":1}}],["workspace",{"2":{"95":1}}],["working",{"2":{"155":1}}],["work",{"2":{"61":6}}],["writing",{"2":{"391":1}}],["write",{"2":{"98":1}}],["writetofile",{"2":{"67":2,"79":1}}],["wraps",{"2":{"293":1}}],["wchar",{"2":{"211":1}}],["wkwebviewconfiguration",{"2":{"92":2}}],["wkwebview",{"0":{"92":1},"2":{"92":8}}],["w3",{"2":{"90":1}}],["w3c",{"2":{"90":1}}],["ws",{"2":{"90":9}}],["watchosapplicationextension",{"2":{"208":1}}],["watchos",{"2":{"159":2,"160":1,"190":1,"208":1,"231":1,"238":1}}],["waituntildone",{"2":{"155":1}}],["warninglabel",{"2":{"292":1}}],["warning",{"2":{"277":6,"291":6,"294":2,"299":4,"303":1}}],["warn",{"2":{"98":1}}],["wasclean",{"2":{"90":4}}],["want",{"2":{"86":1,"95":2}}],["wav",{"2":{"44":1}}],["wave",{"2":{"44":1}}],["why",{"2":{"392":1}}],["whyframe",{"2":{"293":1}}],["whenever",{"2":{"392":1}}],["when",{"2":{"304":1,"391":1,"397":1}}],["where",{"2":{"200":1}}],["wha",{"2":{"304":2}}],["what",{"2":{"86":1}}],["whatsapp",{"0":{"79":1},"2":{"64":1,"79":7}}],["while语句",{"2":{"208":1}}],["while",{"2":{"43":1,"46":1,"95":1}}],["www",{"2":{"56":1,"67":1,"73":1,"86":2,"90":1,"92":2,"94":1,"326":1,"328":1}}],["were",{"2":{"392":1}}],["weakself",{"2":{"148":2}}],["weak",{"2":{"136":1,"148":1,"169":1}}],["welcome",{"2":{"120":3,"356":1}}],["wechat",{"2":{"64":1}}],["we",{"2":{"9":1,"397":1}}],["webview",{"0":{"91":1},"1":{"92":1},"2":{"92":4}}],["websocketdidopen",{"2":{"90":1}}],["websocket",{"2":{"90":36}}],["webscoket+json",{"2":{"33":1}}],["webscoket",{"0":{"89":1,"90":1},"1":{"90":1},"2":{"33":1}}],["webpack",{"2":{"116":5}}],["webp",{"2":{"44":1}}],["web三端通用",{"2":{"33":1}}],["web",{"0":{"97":1},"2":{"2":2,"205":1}}],["will",{"2":{"392":1}}],["willusefullscreencontentsize",{"2":{"193":3}}],["willdisplay",{"2":{"176":1}}],["window",{"2":{"90":2,"193":3,"360":2}}],["windows",{"2":{"44":1}}],["wikimedia",{"2":{"66":1}}],["wiki",{"2":{"66":1}}],["wikipedia",{"2":{"66":2}}],["widthofwindow",{"2":{"61":1}}],["width",{"2":{"36":17,"61":1,"133":1,"146":2,"154":1}}],["within",{"2":{"395":1}}],["withcstring",{"2":{"215":1}}],["withvalist",{"2":{"215":3}}],["witherror",{"2":{"195":1}}],["withextension",{"2":{"194":2}}],["with单词会被移除",{"2":{"133":1}}],["with",{"2":{"2":1,"74":1,"155":4,"164":1,"198":1,"205":1,"276":1,"301":1,"302":3,"391":1,"392":1,"395":1,"396":1,"397":1}}],["wish",{"2":{"2":1}}],["rsa",{"2":{"380":8}}],["rsa和gitlab",{"2":{"380":1}}],["rho$",{"2":{"304":2}}],["rgba",{"2":{"257":1}}],["rpm",{"2":{"254":2}}],["rpath下找到",{"2":{"160":1}}],["r",{"2":{"216":3,"257":3,"386":1}}],["rxjs",{"2":{"113":1}}],["rules",{"2":{"86":1}}],["runtime",{"0":{"268":1},"1":{"269":1,"270":1,"271":1,"272":1,"273":1},"2":{"78":1,"170":1,"268":1,"273":1}}],["run",{"2":{"71":2,"84":1}}],["ruby",{"2":{"20":2}}],["rubygems",{"2":{"20":2}}],["right",{"2":{"59":1,"287":2}}],["rich",{"2":{"44":1}}],["rate",{"2":{"304":2}}],["raw",{"0":{"293":1},"2":{"293":3,"326":2}}],["rawrepresentable",{"2":{"213":2,"218":1}}],["rawvalue",{"2":{"200":1,"213":12,"219":1}}],["ram",{"2":{"44":1}}],["rar",{"2":{"44":2}}],["raise",{"2":{"36":1}}],["rtf",{"2":{"44":1}}],["room",{"2":{"184":1}}],["root",{"2":{"116":3}}],["rootviewcontroller",{"2":{"59":1}}],["router",{"0":{"130":1},"2":{"130":1}}],["rotateimage",{"2":{"36":1}}],["roles=",{"2":{"2":1}}],["rolename=",{"2":{"2":2}}],["role",{"2":{"2":3}}],["rf",{"2":{"27":1}}],["rm",{"2":{"27":1,"44":1,"384":2}}],["re",{"2":{"392":1}}],["reused",{"2":{"391":2}}],["rename",{"2":{"389":1}}],["renamed",{"2":{"384":1}}],["render",{"2":{"120":1}}],["remote",{"2":{"386":3,"387":3,"389":16,"391":10}}],["removed",{"2":{"298":2}}],["removeitem",{"2":{"195":2}}],["removeitematurl",{"2":{"195":1}}],["removewords",{"2":{"184":2}}],["removefriends",{"2":{"175":1}}],["removefriendsobject",{"2":{"175":1}}],["remove",{"2":{"20":1,"90":2}}],["remainder",{"2":{"214":2}}],["retain",{"2":{"227":1}}],["retained宏标注这些函数或方法",{"2":{"188":1}}],["retained或者cf",{"2":{"188":1}}],["returninstanceadoptingswiftprotocol",{"2":{"249":1}}],["returnswiftclassinstance",{"2":{"249":1}}],["returns",{"2":{"188":2}}],["returnsunannotatedvalue",{"2":{"142":2}}],["returnsnullablevalue",{"2":{"142":2}}],["returnsnonnullvalue",{"2":{"142":2}}],["return",{"2":{"36":2,"59":14,"65":3,"90":3,"92":1,"120":2,"146":1,"151":2,"193":1,"194":2,"203":2,"208":1,"213":1,"215":4,"257":1,"276":2,"296":6,"297":2,"298":2,"299":2}}],["redyellow",{"2":{"213":1}}],["red",{"2":{"134":1,"152":1,"213":2,"257":3}}],["redux",{"0":{"131":1}}],["reverse",{"2":{"103":1}}],["representedobject",{"2":{"198":2}}],["repeats",{"2":{"90":1}}],["repo",{"2":{"83":2,"103":1}}],["receiving",{"2":{"391":1}}],["received",{"2":{"143":2}}],["receivemsg",{"2":{"90":2}}],["receivemessage",{"2":{"90":3}}],["rect",{"2":{"146":2}}],["reconnect",{"2":{"90":3}}],["reconnecttime",{"2":{"90":7}}],["recordwithquality",{"2":{"254":1}}],["recordwithrpm",{"2":{"254":1}}],["record",{"2":{"35":1,"254":1}}],["recommended",{"2":{"2":1}}],["referenced",{"2":{"395":1}}],["refs",{"2":{"387":1}}],["refined",{"2":{"257":3}}],["ref",{"2":{"66":1,"187":1,"395":1}}],["reset",{"2":{"390":3}}],["resettable属性特性",{"2":{"142":1}}],["resettable",{"2":{"136":1}}],["resolving",{"2":{"391":1}}],["resolvingagainstbaseurl",{"2":{"86":1}}],["resource",{"2":{"194":1}}],["respondstoselector",{"2":{"78":1}}],["results",{"0":{"269":1},"1":{"270":1,"271":1,"272":1},"2":{"268":1,"397":1}}],["result=",{"2":{"66":1}}],["result",{"2":{"65":2,"66":2,"73":3,"79":2,"155":2,"391":1}}],["restricted",{"2":{"54":1}}],["restrictedstate",{"2":{"54":1}}],["restricrted",{"2":{"54":1}}],["readme",{"2":{"331":1}}],["readingoptions",{"2":{"180":1}}],["readonly",{"2":{"151":2}}],["read",{"2":{"95":2,"198":2}}],["reader",{"2":{"90":1}}],["readystate",{"2":{"90":1}}],["readystate=",{"2":{"90":1}}],["readable",{"2":{"64":2}}],["react",{"0":{"80":1,"115":1},"1":{"81":1,"82":1,"83":1,"84":1,"85":1,"116":1,"117":1,"118":1,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":1},"2":{"82":3,"84":2,"85":1,"103":1,"117":2,"120":1,"130":1}}],["reason",{"2":{"64":2,"90":4}}],["really",{"2":{"397":1}}],["real",{"2":{"42":1,"44":2}}],["rel=",{"2":{"285":1}}],["related",{"2":{"35":1}}],["release",{"2":{"14":3,"26":2,"95":1,"189":1,"227":1,"397":3}}],["registervc",{"2":{"391":1}}],["registry",{"2":{"82":2}}],["region",{"2":{"301":3,"302":3}}],["regularfilecontents",{"2":{"198":1}}],["regex",{"2":{"194":1}}],["reg",{"2":{"8":1}}],["requestwheninuseauthorization",{"2":{"208":4}}],["requestwithurl",{"2":{"92":1}}],["requestaccesstoaccountswithtype",{"2":{"74":1}}],["request",{"0":{"391":1},"2":{"3":1,"92":5}}],["requiredmethod",{"2":{"250":1}}],["required",{"2":{"2":1,"50":2,"154":1}}],["tvosapplicationextension",{"2":{"208":1}}],["tvos",{"2":{"159":2,"160":1,"190":1,"208":1,"231":1,"238":1}}],["t>",{"2":{"145":4}}],["tsexport",{"2":{"304":1}}],["tsfunction",{"2":{"302":1}}],["tsimport",{"2":{"302":1}}],["tsinghua",{"2":{"83":2}}],["ts",{"2":{"113":1,"292":2,"300":2,"302":3}}],["tls",{"2":{"103":1}}],["tuna",{"2":{"83":5}}],["tagname",{"2":{"387":1}}],["tags",{"2":{"387":2,"389":1,"391":3}}],["tag",{"2":{"387":10,"391":1}}],["tada",{"2":{"288":1}}],["tables",{"2":{"287":2}}],["tablename",{"2":{"206":2}}],["tableview",{"2":{"176":6}}],["tableviewcontroller",{"2":{"165":1}}],["tabs",{"2":{"103":2}}],["takeunretainedvalue",{"2":{"155":1,"189":1}}],["takesanautoreleasingpointer",{"2":{"226":2}}],["takesamutablevoidpointer",{"2":{"225":5}}],["takesamutablepointer",{"2":{"225":3}}],["takesavoidpointer",{"2":{"224":5}}],["takesapointer",{"2":{"224":3}}],["takesunannotatedparameter",{"2":{"142":2}}],["takesnullableparameter",{"2":{"142":2}}],["takesnonnullparameter",{"2":{"142":2}}],["tapped",{"2":{"154":1,"169":1}}],["tappedbutton",{"2":{"154":3}}],["taobao",{"2":{"82":2}}],["targets",{"2":{"397":1}}],["target=",{"2":{"90":1,"285":1}}],["target选择的版本",{"2":{"50":1}}],["target设置为ios",{"2":{"48":1}}],["target",{"0":{"237":1,"239":1,"241":1,"242":1,"244":1,"246":1},"1":{"238":1,"239":1,"240":1,"241":1,"243":1,"244":1,"245":1,"246":1},"2":{"48":1,"50":1,"90":3,"95":1,"110":1,"231":2,"233":2,"234":1,"235":2,"236":1,"237":1,"238":1,"239":1,"240":7,"241":2,"243":1,"244":2,"245":1,"246":3,"247":1,"260":4}}],["txt",{"2":{"79":2}}],["testable特性",{"2":{"240":1}}],["testing",{"2":{"88":5}}],["templates",{"2":{"103":1}}],["template",{"2":{"103":2}}],["template>",{"2":{"103":1}}],["terminating",{"2":{"74":1}}],["textfields",{"2":{"169":1}}],["textfielddelegate",{"2":{"165":1}}],["textcolor",{"2":{"136":1,"170":1}}],["text=",{"2":{"79":1}}],["text",{"2":{"44":1,"90":4,"136":1,"295":2,"358":2,"392":3}}],["two",{"2":{"283":1,"304":2}}],["twtrcardconfiguration",{"2":{"73":2}}],["twtrcomposerviewcontroller",{"2":{"73":2}}],["twtrcomposerresultcancelled",{"2":{"73":1}}],["twtrcomposerresultdone",{"2":{"73":1}}],["twtrcomposerresult",{"2":{"73":1}}],["twtrcomposer",{"2":{"73":2}}],["twtrsession",{"2":{"73":1}}],["tweets",{"2":{"73":2}}],["twittertype",{"2":{"74":3}}],["twitterkit",{"2":{"69":2}}],["twitter",{"0":{"68":1,"69":1,"73":1},"1":{"70":1,"71":1,"72":1,"73":1,"74":1},"2":{"71":1,"73":4}}],["tiplabel",{"2":{"292":1}}],["tip",{"2":{"277":4,"291":4,"294":2,"301":1,"303":1,"347":1}}],["tips",{"0":{"75":1,"376":1,"393":1},"1":{"76":1,"77":1,"78":1,"377":1}}],["times",{"2":{"304":4}}],["timestamps",{"2":{"183":2}}],["timesincenow",{"2":{"140":1}}],["timezone",{"2":{"179":1}}],["timeintervalsincenow",{"2":{"140":1}}],["timeintervalsincereferencedate",{"2":{"67":2,"79":1,"139":2}}],["timeinterval",{"2":{"139":1}}],["time",{"2":{"90":2}}],["timer",{"2":{"85":1}}],["title表示鼠标悬停在图片时的显示文本",{"2":{"326":1}}],["title>",{"2":{"90":1}}],["title>insert",{"2":{"90":1}}],["title",{"2":{"66":4,"90":1,"286":1,"326":1}}],["t",{"2":{"61":5,"86":1,"90":4,"95":3,"143":1,"145":2,"203":1,"211":3,"296":2,"304":4,"380":4,"391":1,"397":1}}],["typealias",{"2":{"213":2}}],["typed",{"2":{"213":11}}],["typedef",{"2":{"53":1,"90":1,"200":1,"213":1,"216":1,"252":1,"372":1}}],["types",{"2":{"205":2}}],["typename",{"2":{"198":1}}],["typeof",{"2":{"148":2}}],["type>",{"2":{"103":1}}],["type默认会自动创建出来",{"2":{"92":1}}],["type=",{"2":{"90":3,"103":1}}],["type",{"2":{"59":1,"74":1,"90":1,"92":2,"103":1,"144":1,"190":3,"223":10,"224":7,"225":4,"226":2,"292":1,"302":4,"392":3}}],["tk",{"2":{"56":2}}],["tmdiskcache",{"2":{"44":1}}],["tmpurl",{"2":{"197":3}}],["tmp",{"2":{"16":1}}],["tree",{"2":{"306":1,"391":2}}],["trap",{"0":{"396":1},"2":{"396":1}}],["track",{"2":{"386":1,"391":2}}],["trafficlightcomboredyellow",{"2":{"213":1}}],["trafficlightcombojustgreen",{"2":{"213":1}}],["trafficlightcombojustyellow",{"2":{"213":1}}],["trafficlightcombojustred",{"2":{"213":1}}],["trafficlightcombo",{"2":{"213":13}}],["trafficlightcolorgreen",{"2":{"213":1}}],["trafficlightcoloryellow",{"2":{"213":1}}],["trafficlightcolorred",{"2":{"213":1}}],["trafficlightcolor",{"2":{"213":13}}],["translation",{"2":{"206":2}}],["transitional",{"2":{"90":1}}],["transform",{"2":{"36":26}}],["try",{"2":{"194":2,"196":2,"197":2,"198":1,"199":1,"200":1,"205":1}}],["troubleshooting",{"2":{"190":1}}],["trianglesidelength",{"2":{"146":4}}],["tr",{"2":{"90":1}}],["true",{"2":{"42":1,"94":1,"182":1,"197":1,"220":2,"222":1,"300":1,"304":2,"305":3}}],["tcp",{"2":{"31":1,"34":1}}],["three",{"2":{"283":5}}],["threads",{"2":{"391":1}}],["thread",{"2":{"61":2}}],["throws",{"2":{"90":1,"151":1,"195":3,"198":1,"200":1}}],["throwable",{"2":{"90":2}}],["throw",{"2":{"74":1,"151":1,"198":3,"199":1,"200":1}}],["thumb",{"2":{"66":1}}],["than",{"2":{"53":4,"397":1}}],["that",{"2":{"2":1,"78":1,"86":1,"190":2,"397":2}}],["this",{"2":{"2":1,"90":1,"113":1,"120":1,"122":1,"190":3,"268":1,"275":1,"277":10,"291":10,"296":4,"300":12,"392":2}}],["therefore",{"2":{"397":1}}],["there",{"2":{"304":2}}],["theme",{"0":{"270":1},"2":{"268":4,"270":1}}],["then",{"2":{"95":4,"391":1}}],["they",{"2":{"2":1,"304":2}}],["the",{"0":{"59":2},"2":{"2":6,"35":1,"58":2,"59":2,"73":3,"86":16,"95":2,"103":4,"142":1,"148":1,"153":1,"166":2,"172":1,"173":1,"174":1,"181":2,"194":1,"203":1,"204":2,"222":2,"227":1,"232":1,"240":1,"245":1,"258":1,"260":1,"268":3,"273":2,"275":1,"278":2,"296":2,"304":2,"360":1,"391":2,"392":3,"395":1,"397":6}}],["tow",{"2":{"397":1}}],["total",{"2":{"391":2}}],["toc",{"0":{"289":1},"2":{"289":4,"306":3}}],["tourl",{"2":{"196":6}}],["touchidutil",{"2":{"391":3}}],["touchupinside",{"2":{"154":1}}],["touch",{"0":{"26":1},"2":{"26":2,"161":1,"380":1}}],["tostring",{"2":{"90":2}}],["todos",{"2":{"295":2}}],["todo",{"2":{"90":5,"295":6}}],["token",{"2":{"67":1}}],["topic",{"2":{"392":1}}],["topics",{"2":{"199":1}}],["toppings",{"2":{"222":4}}],["toppings字段则是一个匿名struct类型",{"2":{"222":1}}],["topviewcontroller",{"2":{"59":1}}],["top",{"2":{"59":1}}],["to",{"0":{"396":1,"397":1},"2":{"2":2,"14":1,"35":1,"53":3,"71":1,"73":1,"86":6,"95":2,"103":5,"146":3,"194":1,"196":6,"201":2,"208":1,"209":2,"214":2,"268":1,"304":4,"356":1,"391":6,"392":7,"395":1,"396":1,"397":1}}],["tomcat用户密码",{"2":{"2":1}}],["tomcat",{"0":{"2":1},"1":{"3":1},"2":{"2":4,"3":1}}],["ico",{"2":{"326":1}}],["iconheight",{"2":{"170":1}}],["icing",{"2":{"222":3}}],["iec",{"2":{"190":1}}],["ibinspectable",{"2":{"170":2}}],["ibinspectable特性添加到类型兼容用户定义运行时属性",{"2":{"170":1}}],["ibinspectable特性开启实时渲染",{"2":{"170":1}}],["ibdesignable",{"2":{"170":1}}],["ibdesignable特性",{"2":{"170":1}}],["ibdesignable和",{"2":{"170":1}}],["ibaction",{"2":{"169":1,"240":1,"260":1}}],["ibaction特性",{"2":{"169":1}}],["iboutlet",{"2":{"169":2,"240":1}}],["iboutlet特性",{"2":{"169":1}}],["iboutlet或者",{"2":{"260":1}}],["iboutlet或",{"2":{"169":1}}],["i",{"2":{"73":1,"85":1,"392":3,"396":1,"397":2}}],["ignored",{"2":{"392":1}}],["ig",{"2":{"67":1}}],["igo",{"2":{"67":1}}],["ipa包导出失败",{"2":{"95":1}}],["ipa包已导出",{"2":{"95":1}}],["ipa",{"2":{"95":4}}],["ipa文件所在路径",{"2":{"95":1}}],["ipadir",{"2":{"95":3}}],["ipadappid",{"2":{"73":1}}],["ipsum",{"2":{"66":1,"296":2}}],["iphoneappid",{"2":{"73":1}}],["iphone",{"2":{"50":6,"67":1}}],["iphone拍照的部分图片在windows上显示被旋转的问题",{"0":{"36":1}}],["iphoneos",{"2":{"26":1}}],["iphonesimulator",{"2":{"26":1}}],["img",{"2":{"70":1,"79":2,"326":2,"330":1}}],["imgref",{"2":{"36":6}}],["implicit",{"2":{"188":2}}],["implemented",{"2":{"164":1}}],["implementation",{"2":{"59":1,"90":1,"143":1,"176":1,"251":1}}],["imports",{"2":{"110":1}}],["important",{"2":{"86":1,"294":2}}],["import",{"2":{"46":2,"59":2,"65":1,"90":20,"110":1,"233":1,"239":3,"241":3,"244":3,"246":3,"247":3,"251":1,"268":1,"302":3,"306":2,"391":1}}],["import等指令的",{"2":{"46":1}}],["imagecache",{"2":{"326":1}}],["imagecopy",{"2":{"36":2}}],["imagename",{"2":{"67":2}}],["imagenamed",{"2":{"67":2,"73":1}}],["images",{"2":{"109":1}}],["imagestr",{"2":{"67":4}}],["imagesize",{"2":{"36":9}}],["imageurlstring",{"2":{"66":2}}],["imageurl",{"2":{"61":1,"66":4,"67":2}}],["imageorientation",{"2":{"36":1}}],["image",{"0":{"35":1},"1":{"36":1},"2":{"35":1,"36":5,"61":3,"66":1,"67":4,"73":3,"79":1,"135":1,"305":1}}],["im",{"0":{"28":1,"29":1},"1":{"29":1,"30":2,"31":2,"32":2,"33":2,"34":2}}],["ionic1",{"2":{"103":1}}],["ionic",{"0":{"101":1},"1":{"102":1,"103":1},"2":{"102":1,"103":6,"113":1}}],["ioexception",{"2":{"90":2}}],["iosapplicationextension",{"2":{"208":1}}],["ios示例",{"2":{"90":1}}],["ios8及以下系统不会回调",{"2":{"65":1}}],["ios宏定义",{"0":{"49":1},"1":{"50":1,"51":1,"52":1,"53":1}}],["ios10",{"2":{"48":1}}],["ios版本兼容",{"0":{"47":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"53":1}}],["ios开发中难免会遇到一些oc与c混编的时候",{"2":{"46":1}}],["ios",{"0":{"37":1,"54":1,"93":1},"1":{"94":1,"95":1},"2":{"33":1,"39":3,"44":1,"48":1,"50":1,"52":13,"53":1,"63":4,"69":2,"74":2,"84":2,"95":2,"159":2,"160":1,"190":1,"208":5,"231":1,"238":1,"258":9,"391":5}}],["io",{"2":{"23":2,"69":2,"73":1,"90":3}}],["ide",{"0":{"394":1},"1":{"395":1,"396":1,"397":1}}],["identityfile",{"2":{"380":2}}],["identityfile指定私钥的路径",{"2":{"380":1}}],["identity",{"2":{"170":2}}],["id=",{"2":{"90":5,"103":3}}],["id>",{"2":{"65":1,"103":2}}],["id重新生成certifictes",{"0":{"14":1},"2":{"11":1}}],["id后面的数值",{"2":{"9":1}}],["id",{"0":{"13":1,"138":1},"1":{"139":1,"140":1,"141":1},"2":{"9":2,"11":1,"13":3,"14":2,"64":4,"65":1,"66":1,"90":5,"92":1,"94":1,"103":3,"132":1,"142":9,"143":1,"145":2,"155":1,"203":1,"205":1,"249":1,"254":1,"295":2,"380":7,"390":1}}],["id414478124",{"2":{"9":4}}],["it来提供一个占位实现",{"2":{"164":1}}],["item",{"2":{"111":1}}],["its",{"2":{"86":1}}],["itunessoftwareservice",{"2":{"95":1}}],["itunes",{"2":{"9":4,"27":3}}],["it",{"2":{"2":1,"78":1,"222":2,"268":1,"304":2,"306":7,"392":3,"397":4}}],["ifdef",{"2":{"46":2,"397":1}}],["if",{"2":{"2":1,"36":1,"50":2,"52":1,"53":2,"59":7,"61":2,"66":1,"67":4,"73":3,"74":2,"77":1,"78":1,"79":3,"86":3,"90":10,"92":2,"95":4,"139":1,"141":1,"143":1,"151":1,"155":1,"181":1,"193":1,"194":1,"196":1,"197":2,"198":2,"208":1,"392":2,"395":1,"397":3}}],["indirectory",{"2":{"206":1}}],["indomain",{"2":{"197":2}}],["index和range",{"2":{"181":1}}],["indexset",{"2":{"179":1}}],["indexpath",{"2":{"179":1}}],["index",{"2":{"56":1,"86":2,"141":1,"181":1,"283":7}}],["insert",{"2":{"392":1}}],["insertsubview",{"2":{"137":2,"154":1}}],["inspector",{"2":{"170":3,"175":1}}],["instancesrespondtoselector",{"2":{"208":1}}],["instance异常",{"2":{"208":1}}],["instance",{"2":{"90":3,"189":2,"203":2}}],["instancetype",{"2":{"90":2,"133":2,"151":1,"203":1,"254":1,"256":1}}],["instagramurl",{"2":{"67":6}}],["instagram",{"0":{"67":1},"2":{"64":1,"67":16}}],["install",{"2":{"20":2,"21":2,"67":8,"69":2,"79":3,"82":3,"84":2,"102":1,"103":1,"105":1,"106":2,"107":2,"116":7,"130":1}}],["innerhtml=",{"2":{"356":1}}],["innerhtml",{"2":{"110":1}}],["inputs",{"2":{"103":1}}],["inputstream",{"2":{"90":1}}],["input",{"2":{"90":3,"92":1,"113":1,"276":1,"277":1}}],["includefiles",{"2":{"293":1}}],["include",{"2":{"103":2,"303":2}}],["included",{"2":{"2":1}}],["inclusion",{"2":{"86":1}}],["invocation",{"2":{"395":1}}],["invoke",{"2":{"215":1}}],["inview",{"2":{"67":3,"79":1}}],["invalidate",{"2":{"90":1}}],["invalid",{"2":{"36":1}}],["infolabel",{"2":{"292":1}}],["info",{"0":{"64":1},"2":{"64":1,"71":1,"90":5,"190":3,"277":4,"291":4}}],["intarray",{"2":{"224":2}}],["int类型的",{"2":{"215":1}}],["int32的形式导入到",{"2":{"227":1}}],["int32>",{"2":{"214":1}}],["int32",{"2":{"214":6}}],["int8>",{"2":{"215":1}}],["int8",{"2":{"182":2}}],["intree",{"2":{"152":1}}],["introduction",{"0":{"28":1,"89":1},"1":{"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"90":1}}],["int",{"2":{"141":1,"152":2,"154":1,"179":1,"181":1,"182":2,"205":1,"211":3,"213":1,"214":6,"218":1,"222":1,"224":1,"225":2,"252":1,"356":1}}],["int64",{"2":{"90":1}}],["into",{"2":{"86":1,"392":1}}],["integerliteral",{"2":{"182":1}}],["integer",{"2":{"181":2}}],["integervalue",{"2":{"181":2}}],["integration",{"2":{"88":1,"103":2}}],["intent",{"2":{"79":4}}],["intended",{"2":{"2":1}}],["internationalization",{"2":{"206":1}}],["interactioncontrollerwithurl",{"2":{"67":3,"79":1}}],["interaction",{"2":{"67":1}}],["interface",{"0":{"168":1},"1":{"169":1,"170":1},"2":{"59":1,"90":2,"145":3,"151":1,"162":1,"168":1,"169":2,"170":4,"176":1,"245":1,"249":1,"251":1,"257":1,"258":1}}],["interger",{"2":{"42":1}}],["init构造器",{"2":{"222":1}}],["init前缀变为init关键字",{"2":{"133":1}}],["initheartbeat",{"2":{"90":2}}],["initsocket",{"2":{"90":3}}],["initializer",{"2":{"151":1}}],["initialize",{"2":{"71":1,"103":1}}],["initwithcontentsofurl",{"2":{"194":1}}],["initwithcontenturl",{"2":{"66":1}}],["initwithname",{"2":{"152":1}}],["initwithsongs",{"2":{"151":1}}],["initwithstring",{"2":{"66":1,"67":1}}],["initwithframe",{"2":{"92":1,"133":2}}],["initwithformat",{"2":{"67":1}}],["initwithurl",{"2":{"90":1}}],["initwithuserid",{"2":{"73":1}}],["initwithgraphpath",{"2":{"66":1}}],["init",{"2":{"16":1,"54":2,"66":4,"73":1,"74":1,"84":1,"90":2,"92":1,"117":1,"133":2,"146":2,"151":1,"152":1,"154":4,"156":1,"164":2,"201":2,"203":1,"213":3,"215":1,"216":2,"217":2,"219":1,"220":3,"222":2,"248":1,"254":1,"382":2}}],["in",{"0":{"397":1},"2":{"2":2,"61":1,"70":1,"73":1,"86":2,"90":2,"92":1,"147":1,"148":1,"197":1,"201":1,"205":3,"209":1,"215":2,"227":1,"268":1,"275":1,"293":1,"295":2,"391":6,"392":3,"395":1,"397":3}}],["isn",{"2":{"296":2}}],["isenabled",{"2":{"232":1}}],["isdead",{"2":{"220":5}}],["isalive",{"2":{"220":6}}],["iscurrentlyplaying",{"2":{"151":1}}],["islast",{"2":{"90":2}}],["ismainthread",{"2":{"90":1}}],["issuccess",{"2":{"61":4,"65":2}}],["issues",{"0":{"15":1},"1":{"16":1,"17":1}}],["iskindofclass",{"2":{"59":3,"143":1}}],["isopen",{"2":{"90":2}}],["isoperatingsystematleastversion",{"2":{"53":1}}],["iso8859",{"2":{"3":1}}],["is",{"2":{"2":2,"86":8,"90":1,"181":2,"190":3,"204":1,"277":10,"287":4,"291":10,"296":2,"300":12,"304":4,"358":4,"392":1,"397":3}}],["xhdatepickerview",{"2":{"391":1}}],["xhdatepicker",{"2":{"391":1}}],["xyz",{"2":{"244":3}}],["xyzcustomviewcontroller",{"2":{"239":1,"244":1}}],["xyzcustomview",{"2":{"239":1,"244":1}}],["xyzcustomcell",{"2":{"239":2,"244":2}}],["xx",{"2":{"109":1}}],["xxxx",{"2":{"94":2,"366":2,"367":1,"368":1}}],["xxxxx",{"2":{"14":1,"73":1,"110":1,"380":2}}],["xxx",{"2":{"92":1,"94":1,"95":5,"107":2,"109":1}}],["xcarchive",{"2":{"95":2}}],["xcworkspace",{"2":{"95":1}}],["xcodebuild",{"2":{"95":3}}],["xcode打包需要配置",{"2":{"26":1}}],["xcode",{"0":{"159":1,"393":1,"394":1,"395":1,"397":1},"1":{"395":1,"396":1,"397":1},"2":{"13":1,"14":6,"26":3,"95":1,"158":1,"160":3,"161":1,"164":1,"175":1,"230":1,"231":1,"234":1,"238":2,"239":1,"240":2,"245":1,"251":1,"259":2,"260":2,"395":1}}],["x26",{"2":{"86":4,"90":1,"95":2,"144":2,"165":1,"196":1,"203":1,"215":1,"224":3,"225":6,"226":1,"227":1,"257":4,"356":3,"397":5}}],["x",{"2":{"52":2,"92":1,"133":1,"138":6,"146":5,"154":1,"159":2,"214":2,"224":4,"225":4,"226":2,"304":2,"346":3,"347":3}}],["xmpp",{"2":{"33":1}}],["xmppframework",{"2":{"33":1}}],["xmldocument",{"2":{"194":2}}],["xml语法",{"2":{"118":1}}],["xml表现力差",{"2":{"33":1}}],["xml常见用转义字符",{"0":{"7":1},"1":{"8":1}}],["xml文件",{"2":{"3":1}}],["xml",{"0":{"6":1},"1":{"7":1,"8":1},"2":{"2":1,"32":1,"44":2,"64":1,"94":1,"95":2,"194":8}}],["x3c",{"2":{"2":6,"21":3,"23":1,"46":2,"52":1,"59":1,"61":11,"64":49,"65":1,"77":1,"79":6,"90":21,"94":43,"103":6,"106":3,"111":6,"120":5,"144":2,"145":16,"150":4,"151":5,"176":2,"183":3,"184":7,"185":3,"189":1,"214":1,"215":1,"219":12,"224":1,"225":1,"226":1,"227":2,"244":3,"246":1,"249":1,"251":1,"256":1,"268":8,"283":6,"293":1,"295":8,"301":26,"302":8,"303":2,"366":4,"369":2,"391":7}}],["密码的认证",{"2":{"372":1}}],["密码",{"2":{"2":1}}],["gfm中可以显示的展示diff效果",{"2":{"362":1}}],["guodongxiaren",{"2":{"326":1}}],["guard",{"2":{"198":1,"208":2,"215":1}}],["guide",{"2":{"189":1,"206":1,"207":1}}],["gui",{"2":{"2":3}}],["go",{"2":{"392":1}}],["gold",{"2":{"185":1}}],["goodbye",{"2":{"138":3}}],["googleplayappid",{"2":{"73":1}}],["gabrielle",{"2":{"156":8}}],["gaofei",{"2":{"23":1,"391":5}}],["gao",{"2":{"3":1,"4":1,"8":1,"9":1,"17":1,"21":1,"26":1,"27":1,"34":1,"36":1,"37":1,"40":1,"44":1,"53":1,"54":1,"57":1,"59":1,"61":1,"67":1,"78":1,"86":1,"88":1,"90":1,"95":1,"100":1,"372":1,"377":1,"390":1,"397":1}}],["gp=0",{"2":{"86":1}}],["gp=0的副本",{"2":{"86":1}}],["global",{"2":{"67":2,"79":1,"82":2,"383":3}}],["groceryproduct",{"2":{"205":4}}],["grown",{"2":{"205":3}}],["grouped",{"2":{"133":1}}],["group",{"0":{"60":1,"61":1},"2":{"61":35,"302":2,"391":5}}],["greeting",{"2":{"206":2}}],["green",{"2":{"134":2,"205":2,"213":2,"257":5}}],["greater",{"2":{"53":2}}],["granted",{"2":{"74":2}}],["given",{"2":{"206":1}}],["gitlab",{"2":{"380":6}}],["git配置多个ssh",{"0":{"379":1},"1":{"380":1}}],["git",{"0":{"378":1},"1":{"379":1,"380":1,"381":1,"382":1,"383":1,"384":1,"385":1,"386":1,"387":1,"388":1,"389":1,"390":1,"391":1,"392":1},"2":{"83":4,"103":2,"380":2,"382":3,"383":4,"384":7,"385":6,"386":15,"387":10,"388":2,"389":15,"390":4,"391":21,"392":2}}],["github仓库中的图片",{"2":{"308":1}}],["github",{"0":{"287":1,"294":1},"2":{"1":1,"285":1,"294":1,"306":2,"326":1,"356":1,"380":6,"392":1}}],["gif",{"2":{"44":2,"326":2}}],["g",{"2":{"21":1,"82":2,"102":1,"103":3,"105":1,"106":1,"113":1,"116":6,"215":1,"216":3,"257":3}}],["gcd",{"2":{"16":1}}],["generation",{"2":{"239":1,"260":1}}],["generated",{"2":{"73":1,"90":2}}],["generate",{"2":{"14":1}}],["gem",{"2":{"20":2}}],["gems",{"2":{"20":1}}],["getting",{"2":{"303":3}}],["getter",{"2":{"154":1,"217":2}}],["getter=iscurrentlyplaying",{"2":{"151":1}}],["getter=",{"2":{"136":1}}],["getred",{"2":{"257":2}}],["getvalist",{"2":{"215":2}}],["getdomnode",{"2":{"124":1}}],["getelementbyid",{"2":{"90":2,"356":1}}],["getclientid",{"2":{"90":1}}],["getbasicremote",{"2":{"90":1}}],["getbytes",{"2":{"3":1}}],["getapplicationdata",{"2":{"90":1}}],["getsession",{"2":{"90":4}}],["getid",{"2":{"90":5}}],["getproperty",{"2":{"78":1}}],["getparameter",{"2":{"3":1}}],["get用户最新发布的media",{"2":{"67":1}}],["get",{"0":{"3":1,"58":1,"59":1},"1":{"59":1},"2":{"16":1,"58":1,"59":1,"61":4,"67":4,"79":3,"86":1,"90":2,"113":1,"129":1,"136":1,"176":1,"213":9,"217":1,"218":3,"219":6,"220":2,"232":1,"392":1}}],["gt",{"2":{"2":1,"8":2,"14":2,"37":4,"64":1,"65":1,"78":1,"154":2,"159":9,"165":2,"181":1,"184":2,"189":2,"205":1,"223":5,"224":6,"225":3,"226":4,"227":1,"231":5,"238":5,"239":2,"244":2,"246":3,"247":2,"259":2,"260":4,"297":1,"397":1}}],["介绍",{"0":{"2":1,"4":1,"23":1,"29":1},"1":{"3":1,"30":1,"31":1,"32":1,"33":1,"34":1}}],["bdlogo",{"2":{"326":1}}],["b^2",{"2":{"304":2}}],["bx",{"2":{"304":2}}],["b",{"2":{"216":3,"225":2,"252":1,"257":3,"304":12,"356":1,"379":1,"386":1,"387":2}}],["b1",{"2":{"155":1}}],["b989627",{"2":{"391":2}}],["b9",{"2":{"155":1}}],["black",{"2":{"152":1}}],["blank",{"2":{"103":1,"285":1}}],["blue",{"2":{"134":2,"257":5}}],["block变量的行为是",{"2":{"147":1}}],["block",{"2":{"61":3,"90":5,"147":1,"148":1,"277":2,"291":2}}],["blogging",{"2":{"286":1}}],["blog",{"0":{"0":1},"1":{"1":1},"2":{"1":1}}],["branch>",{"2":{"391":2}}],["branches",{"2":{"391":1}}],["branch",{"2":{"386":21,"387":3,"389":4,"391":4,"392":1}}],["bridging",{"2":{"188":2,"238":1,"239":1,"260":2}}],["bridgednumber",{"2":{"182":1}}],["bridgedstring",{"2":{"181":1}}],["bridge",{"2":{"143":2}}],["bringsubviewtofront",{"2":{"76":1}}],["brown",{"2":{"205":2}}],["browser",{"2":{"90":1,"97":1}}],["bronze",{"2":{"185":1}}],["broadcast",{"2":{"90":1}}],["breakpoint",{"2":{"396":1}}],["break",{"2":{"36":8,"54":4}}],["been",{"2":{"164":1,"397":1}}],["begin",{"2":{"142":1}}],["begin和ns",{"2":{"142":1}}],["because",{"2":{"86":1}}],["be",{"2":{"73":1,"190":2,"196":1,"268":1,"303":4,"392":1,"397":1}}],["bestfriend",{"2":{"156":6}}],["best",{"2":{"59":1}}],["below",{"2":{"2":1}}],["bc",{"2":{"59":1}}],["bmp",{"2":{"44":1}}],["bitpattern",{"2":{"215":1}}],["bitmap",{"2":{"44":1}}],["big",{"2":{"73":2,"350":1}}],["bing",{"2":{"328":1}}],["binding",{"2":{"110":1}}],["bin",{"2":{"4":1,"20":2,"23":4}}],["but",{"2":{"296":2,"397":1}}],["buttontapped",{"2":{"169":1}}],["button",{"2":{"66":1,"90":1,"154":1,"169":2,"204":2}}],["built",{"2":{"275":1}}],["builder",{"0":{"168":1},"1":{"169":1,"170":1},"2":{"162":1,"168":1,"169":2,"170":4}}],["build文件夹路径",{"2":{"95":1}}],["build",{"2":{"26":3,"71":1,"95":4,"395":1,"397":1}}],["bundle",{"2":{"94":1,"103":1,"154":3,"194":2,"206":8}}],["buffer",{"2":{"215":3}}],["buffers",{"2":{"32":1,"33":2}}],["buf",{"2":{"90":3}}],["back",{"2":{"392":1}}],["backend",{"2":{"14":1}}],["bar",{"2":{"283":7}}],["barrier",{"2":{"16":1}}],["banana",{"2":{"205":10}}],["babel",{"2":{"116":2}}],["baidu",{"2":{"61":1,"73":1,"326":2,"361":2}}],["basic方式",{"2":{"372":1}}],["basic",{"2":{"372":1}}],["basics",{"2":{"303":8}}],["base64encodedstring",{"2":{"219":1}}],["base64encodingoptions",{"2":{"219":1}}],["base",{"2":{"23":1,"48":2,"293":1}}],["bashecho",{"2":{"356":1}}],["bash",{"2":{"23":4,"356":1}}],["bogon",{"2":{"391":7}}],["box",{"2":{"277":2,"291":2,"397":1}}],["both",{"2":{"268":1,"397":1}}],["bondiblue",{"2":{"217":2}}],["bom",{"2":{"97":2}}],["body",{"2":{"92":1}}],["bodystr",{"2":{"92":5}}],["bodydata",{"2":{"92":3}}],["body>",{"2":{"90":2}}],["booleanliteral",{"2":{"182":1}}],["boolean",{"2":{"42":1,"90":3,"99":1,"397":1}}],["bool",{"2":{"37":1,"61":2,"65":5,"74":1,"79":1,"90":1,"151":4,"179":1,"182":1,"195":2,"196":1,"211":1,"220":6,"222":2,"232":1}}],["bootstrap",{"2":{"1":1}}],["boundheight",{"2":{"36":9}}],["bounds",{"2":{"36":19,"92":1}}],["boci",{"2":{"14":5}}],["bytes",{"2":{"190":1,"391":2}}],["byte",{"2":{"90":1}}],["bytebuffer",{"2":{"90":2}}],["by",{"2":{"2":1,"90":1,"268":1,"275":1,"276":1,"392":2,"397":1}}],["和无序列表一样",{"2":{"342":1}}],["和html的锚点",{"2":{"331":1}}],["和类方法",{"2":{"232":1}}],["和instancesrespondtoselector",{"2":{"208":1}}],["和autorelease",{"2":{"189":1}}],["和as",{"2":{"150":1}}],["和上述过程非常相似",{"2":{"161":1}}],["和文件存储结合起来",{"2":{"44":1}}],["和",{"0":{"169":1,"235":1,"299":1},"1":{"236":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":1,"246":1,"247":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1},"2":{"1":1,"8":1,"132":1,"133":1,"141":1,"148":1,"156":1,"157":3,"159":1,"161":2,"162":1,"168":1,"169":1,"177":1,"180":1,"182":1,"186":1,"191":1,"193":1,"199":1,"202":1,"205":2,"212":1,"213":2,"229":1,"236":1,"246":1,"260":1,"264":1,"289":1,"350":1,"363":1}}],["感谢",{"2":{"1":1}}],["感谢这个作者",{"2":{"1":1}}],["的地方",{"2":{"371":1}}],["的语法",{"2":{"363":1}}],["的语言特性扩展或简化这些",{"2":{"192":1}}],["的语言特性呈现",{"2":{"152":1}}],["的起源",{"2":{"350":1}}],["的选项",{"2":{"306":2}}],["的选择器",{"2":{"202":1}}],["的值对应于源代码根目录",{"2":{"301":1}}],["的样式和路由冲突",{"2":{"293":1}}],["的呈现效果",{"2":{"289":1}}],["的名称",{"2":{"260":1}}],["的替代代码",{"2":{"258":2}}],["的build",{"2":{"244":1,"246":1}}],["的保护伞头文件中",{"2":{"243":1}}],["的兼容性",{"2":{"235":1}}],["的实现文件中采用",{"0":{"251":1},"2":{"235":1}}],["的实例方法",{"2":{"197":1}}],["的独有特性",{"2":{"234":1,"260":1}}],["的时候",{"2":{"232":1}}],["的最新语言特性实现应用程序的部分功能",{"2":{"235":1}}],["的最有效的方式是逐个文件迁移",{"2":{"230":1}}],["的最低支持版本在ios8",{"2":{"50":1}}],["的集合类型set",{"2":{"219":1}}],["的源文件中定义的全局常量会自动被",{"2":{"212":1}}],["的可用性",{"2":{"208":1}}],["的更多信息",{"2":{"205":1}}],["的目标",{"2":{"202":1}}],["的互用性",{"2":{"192":1}}],["的cfarraycreatemutable",{"2":{"227":1}}],["的cftyperef类型会重映射为anyobject类型",{"2":{"187":1}}],["的copy属性特性被转化为",{"2":{"174":1}}],["的文本字符串",{"2":{"181":1}}],["的string类型由独立编码的",{"2":{"181":1}}],["的属性前",{"2":{"170":1}}],["的属性导入",{"2":{"136":1}}],["的类型特性小节",{"2":{"227":1}}],["的类",{"2":{"169":1}}],["的类名后面加上一个冒号",{"2":{"163":1}}],["的代码仓库中",{"2":{"295":1}}],["的代码",{"2":{"167":1}}],["的成员",{"2":{"163":1}}],["的一些特色功能",{"2":{"168":1}}],["的一些其它功能",{"2":{"162":1}}],["的一个模板来创建一个基于",{"2":{"158":1}}],["的封装",{"2":{"161":1}}],["的框架",{"2":{"161":1}}],["的应用",{"2":{"158":1}}],["的对象上调用方法",{"2":{"155":1}}],["的块变量",{"2":{"147":1}}],["的块会作为符合其调用约定的",{"2":{"147":1}}],["的nsobjectprotocol协议",{"2":{"165":1}}],["的nsobject协议会被重映射为",{"2":{"165":1}}],["的nsarray",{"2":{"145":1}}],["的nsnull实例",{"2":{"143":1}}],["的简称",{"2":{"97":2}}],["的仓库",{"2":{"83":1}}],["的工具",{"2":{"82":1}}],["的方式",{"2":{"67":1}}],["的自定义对话框",{"2":{"66":1}}],["的自定义界面",{"2":{"66":1}}],["的使用",{"0":{"17":1,"96":1},"1":{"97":1,"98":1,"99":1,"100":1}}],["的环境",{"2":{"14":1}}],["的",{"0":{"175":1},"2":{"1":1,"14":1,"31":1,"138":4,"161":2,"162":1,"195":1,"198":1,"213":1,"218":2,"227":1,"239":1,"244":1,"260":1}}],["full",{"2":{"273":1,"278":1}}],["fullscreensize",{"2":{"193":2}}],["fundation",{"2":{"186":1}}],["func来声明实例方法",{"2":{"232":1}}],["func",{"2":{"65":2,"142":6,"145":3,"151":1,"152":1,"154":1,"169":1,"175":4,"176":2,"183":2,"184":2,"185":2,"193":1,"198":1,"201":2,"208":1,"214":3,"217":1,"245":1,"250":2,"258":1}}],["function",{"2":{"46":1,"90":4,"92":1,"99":1,"120":1,"301":3,"302":1}}],["futuredate",{"2":{"140":1}}],["fm=26",{"2":{"86":2}}],["fmt",{"2":{"46":3}}],["f",{"2":{"67":2,"79":1,"95":2,"380":2,"391":1}}],["features",{"2":{"276":1}}],["fetching",{"2":{"391":4}}],["fetch",{"0":{"129":1},"2":{"389":1,"391":9}}],["feed",{"2":{"66":1}}],["feed==",{"2":{"66":1}}],["feipages",{"2":{"322":1}}],["fei",{"0":{"0":1},"1":{"1":1},"2":{"3":1,"4":1,"8":1,"9":1,"17":1,"21":1,"26":1,"27":1,"34":1,"36":1,"37":1,"40":1,"44":1,"53":1,"54":1,"57":1,"59":1,"61":1,"67":1,"78":1,"86":1,"88":1,"90":1,"95":1,"100":1,"372":1,"377":1,"390":1,"397":1}}],["fbsdkgraphrequestconnection",{"2":{"66":1}}],["fbsdkgraphrequest",{"2":{"66":1}}],["fbsdkaccesstoken",{"2":{"66":1}}],["fbsdkapplicationdelegate",{"2":{"65":3}}],["fbsdksharedialogmodebrowser",{"2":{"66":1}}],["fbsdksharedialog",{"2":{"66":2}}],["fbsdksharemediacontent",{"2":{"66":1}}],["fbsdksharevideocontent",{"2":{"66":1}}],["fbsdksharephotocontent",{"2":{"66":1}}],["fbsdksharelinkcontent",{"2":{"66":8}}],["fbsdksharebutton",{"2":{"66":2}}],["fbsdkcorekit",{"2":{"65":2}}],["fbdiskcache",{"2":{"44":2}}],["frontmatter",{"0":{"272":1,"286":1},"2":{"268":3,"272":1,"286":1}}],["from`",{"2":{"391":1}}],["fromurl",{"2":{"196":5}}],["fromviewcontroller",{"2":{"66":1}}],["from",{"0":{"59":1},"2":{"58":1,"59":1,"110":1,"113":2,"198":2,"200":2,"205":1,"214":2,"268":1,"293":1,"302":2,"306":3,"391":1,"395":1}}],["friend",{"2":{"175":2}}],["friends",{"2":{"156":5,"175":3}}],["frac",{"2":{"304":6}}],["frac1c",{"2":{"304":4}}],["frame",{"2":{"133":4,"154":1}}],["frameworkname",{"2":{"247":4}}],["frameworks",{"2":{"95":1}}],["framework框架",{"2":{"54":1}}],["framework",{"0":{"26":1},"2":{"26":3,"95":1}}],["fragment",{"2":{"86":1}}],["followed",{"2":{"392":2}}],["following",{"2":{"86":2}}],["focused",{"2":{"297":2}}],["focus",{"2":{"297":3}}],["four",{"2":{"283":3}}],["found",{"0":{"395":1},"2":{"141":1,"395":2}}],["foundation",{"0":{"178":1,"186":1},"1":{"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"187":1,"188":1,"189":1},"2":{"46":2,"90":2,"142":1,"161":4,"177":3,"178":1,"179":2,"180":3,"181":1,"182":1,"186":6,"187":2,"188":5,"189":5,"190":1,"191":1,"205":2,"207":1,"217":1,"221":1,"227":1}}],["foorc",{"2":{"303":4}}],["foo",{"2":{"245":4,"283":7,"301":3,"302":1,"306":1}}],["font",{"2":{"113":1}}],["forgetpwdvc",{"2":{"391":1}}],["force",{"2":{"389":1,"390":1}}],["foryou",{"2":{"326":1}}],["for=",{"2":{"295":2}}],["forlocalization",{"2":{"206":1}}],["forresource",{"2":{"194":1,"206":1}}],["forperson",{"2":{"176":3}}],["forhttpheaderfield",{"2":{"92":2}}],["forname",{"2":{"90":1}}],["forms",{"2":{"110":1}}],["formsmodule",{"2":{"110":2}}],["formssi",{"2":{"61":1}}],["form",{"2":{"92":8}}],["formode",{"2":{"90":1}}],["formatter",{"2":{"194":4}}],["format",{"2":{"36":1,"44":1,"95":2,"206":3,"215":3}}],["for",{"0":{"395":1},"2":{"2":1,"61":1,"64":2,"86":7,"92":1,"103":3,"144":1,"154":1,"189":1,"190":1,"197":1,"257":3,"268":1,"273":1,"278":1,"395":3}}],["forkeys",{"2":{"256":2}}],["forkeypath",{"2":{"156":4}}],["forkey",{"2":{"139":1,"156":2,"177":1}}],["fork",{"2":{"1":1}}],["ffd8ffe1",{"2":{"44":1}}],["failed",{"2":{"391":1,"395":1}}],["favicon",{"2":{"326":1}}],["favoritesplaylist",{"2":{"151":2}}],["fatalerror",{"2":{"164":1,"200":1}}],["fabric",{"2":{"69":2,"73":1}}],["facebooksharewithmessage",{"2":{"66":1}}],["facebook",{"0":{"62":1},"1":{"63":1,"64":1,"65":1,"66":1},"2":{"62":1,"63":6,"64":3,"66":10,"82":1}}],["fastimagecache",{"2":{"44":1}}],["false",{"2":{"42":1,"94":1,"220":3,"222":1}}],["flavored",{"2":{"307":1}}],["flag",{"2":{"111":1}}],["flipside",{"2":{"255":1}}],["flexiblebottommargin",{"2":{"219":1}}],["flexibleheight",{"2":{"219":1}}],["flexibletopmargin",{"2":{"219":1}}],["flexiblerightmargin",{"2":{"219":1}}],["flexiblewidth",{"2":{"219":1}}],["flexibleleftmargin",{"2":{"219":1}}],["flush",{"2":{"44":1}}],["flutter",{"0":{"22":1,"23":1,"24":1},"1":{"23":1,"24":1,"25":1},"2":{"23":9}}],["float>",{"2":{"224":1,"225":1}}],["floatliteral",{"2":{"182":1}}],["floatvalue",{"2":{"53":1}}],["float",{"2":{"42":1,"179":1,"211":2,"214":6,"216":7,"217":13,"224":3,"225":4}}],["fscompanyinfocontroller",{"2":{"391":1}}],["fsalerttools",{"2":{"391":4}}],["fsmobileassistant",{"2":{"391":17}}],["fsnetworkaccesser",{"2":{"26":5}}],["fstools",{"2":{"26":3}}],["fix",{"2":{"391":1}}],["fifthcharacter",{"2":{"141":2}}],["fir",{"2":{"95":2}}],["first",{"2":{"74":1}}],["firstobject",{"2":{"67":2,"79":1}}],["fi",{"2":{"95":4}}],["finished",{"2":{"61":1,"190":1}}],["finder",{"2":{"209":1}}],["find",{"2":{"59":1,"397":2}}],["findbestviewcontroller",{"2":{"59":6}}],["final",{"2":{"25":1}}],["file2",{"2":{"384":2,"385":2}}],["file1",{"2":{"384":2,"385":2}}],["filepath",{"2":{"301":2}}],["files",{"2":{"268":1}}],["filesize",{"2":{"190":2}}],["filesizesforurlswithsuffix",{"2":{"185":2}}],["file来手动创建",{"2":{"238":1}}],["file为对应的",{"2":{"231":1}}],["filewrapper",{"2":{"198":3}}],["filereadunsupportedscheme",{"2":{"196":1}}],["filenosuchfile",{"2":{"196":1}}],["filemanager",{"2":{"196":6,"197":5}}],["fileurlwithpath",{"2":{"67":2,"79":1,"196":4}}],["file",{"2":{"14":1,"67":1,"159":1,"190":1,"196":2,"231":1,"238":1,"301":2,"303":2,"384":3}}],["致谢",{"0":{"1":1}}]],"serializationVersion":2}';export{t as default}; diff --git a/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.D3VOKMMh.js b/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.D3VOKMMh.js new file mode 100644 index 0000000..2dae90e --- /dev/null +++ b/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.D3VOKMMh.js @@ -0,0 +1,8 @@ +var Nt=Object.defineProperty;var Ft=(a,e,t)=>e in a?Nt(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var Ce=(a,e,t)=>Ft(a,typeof e!="symbol"?e+"":e,t);import{V as Ot,D as le,h as ge,ah as et,ai as Rt,aj as Ct,ak as At,q as $e,al as Mt,d as Lt,am as tt,p as he,an as Dt,ao as Pt,s as zt,ap as Vt,v as Ae,P as fe,O as _e,aq as $t,ar as jt,W as Bt,R as Wt,$ as Kt,b as Jt,o as H,j as _,a0 as qt,as as Ut,k as L,at as Gt,au as Ht,c as Z,e as Se,n as st,B as nt,F as it,a as pe,t as ve,av as Qt,aw as rt,ax as Yt,a6 as Zt,ab as Xt,ay as es,_ as ts}from"./framework.BHpayLOB.js";import{u as ss,c as ns}from"./theme.Cwh4Yq8A.js";const is={root:()=>Ot(()=>import("./@localSearchIndexroot.BXBjdp4i.js"),[])};/*! +* tabbable 6.2.0 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/var vt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],ke=vt.join(","),mt=typeof Element>"u",re=mt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Ne=!mt&&Element.prototype.getRootNode?function(a){var e;return a==null||(e=a.getRootNode)===null||e===void 0?void 0:e.call(a)}:function(a){return a==null?void 0:a.ownerDocument},Fe=function a(e,t){var s;t===void 0&&(t=!0);var n=e==null||(s=e.getAttribute)===null||s===void 0?void 0:s.call(e,"inert"),r=n===""||n==="true",i=r||t&&e&&a(e.parentNode);return i},rs=function(e){var t,s=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return s===""||s==="true"},gt=function(e,t,s){if(Fe(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(ke));return t&&re.call(e,ke)&&n.unshift(e),n=n.filter(s),n},bt=function a(e,t,s){for(var n=[],r=Array.from(e);r.length;){var i=r.shift();if(!Fe(i,!1))if(i.tagName==="SLOT"){var o=i.assignedElements(),l=o.length?o:i.children,c=a(l,!0,s);s.flatten?n.push.apply(n,c):n.push({scopeParent:i,candidates:c})}else{var h=re.call(i,ke);h&&s.filter(i)&&(t||!e.includes(i))&&n.push(i);var m=i.shadowRoot||typeof s.getShadowRoot=="function"&&s.getShadowRoot(i),f=!Fe(m,!1)&&(!s.shadowRootFilter||s.shadowRootFilter(i));if(m&&f){var b=a(m===!0?i.children:m.children,!0,s);s.flatten?n.push.apply(n,b):n.push({scopeParent:i,candidates:b})}else r.unshift.apply(r,i.children)}}return n},yt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},ie=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||rs(e))&&!yt(e)?0:e.tabIndex},as=function(e,t){var s=ie(e);return s<0&&t&&!yt(e)?0:s},os=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},wt=function(e){return e.tagName==="INPUT"},ls=function(e){return wt(e)&&e.type==="hidden"},cs=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(s){return s.tagName==="SUMMARY"});return t},us=function(e,t){for(var s=0;ssummary:first-of-type"),i=r?e.parentElement:e;if(re.call(i,"details:not([open]) *"))return!0;if(!s||s==="full"||s==="legacy-full"){if(typeof n=="function"){for(var o=e;e;){var l=e.parentElement,c=Ne(e);if(l&&!l.shadowRoot&&n(l)===!0)return at(e);e.assignedSlot?e=e.assignedSlot:!l&&c!==e.ownerDocument?e=c.host:e=l}e=o}if(ps(e))return!e.getClientRects().length;if(s!=="legacy-full")return!0}else if(s==="non-zero-area")return at(e);return!1},ms=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var s=0;s=0)},bs=function a(e){var t=[],s=[];return e.forEach(function(n,r){var i=!!n.scopeParent,o=i?n.scopeParent:n,l=as(o,i),c=i?a(n.candidates):o;l===0?i?t.push.apply(t,c):t.push(o):s.push({documentOrder:r,tabIndex:l,item:n,isScope:i,content:c})}),s.sort(os).reduce(function(n,r){return r.isScope?n.push.apply(n,r.content):n.push(r.content),n},[]).concat(t)},ys=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:je.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:gs}):s=gt(e,t.includeContainer,je.bind(null,t)),bs(s)},ws=function(e,t){t=t||{};var s;return t.getShadowRoot?s=bt([e],t.includeContainer,{filter:Oe.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):s=gt(e,t.includeContainer,Oe.bind(null,t)),s},ae=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return re.call(e,ke)===!1?!1:je(t,e)},xs=vt.concat("iframe").join(","),Me=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return re.call(e,xs)===!1?!1:Oe(t,e)};/*! +* focus-trap 7.6.5 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/function Be(a,e){(e==null||e>a.length)&&(e=a.length);for(var t=0,s=Array(e);t0){var s=e[e.length-1];s!==t&&s._setPausedState(!0)}var n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap:function(e,t){var s=e.indexOf(t);s!==-1&&e.splice(s,1),e.length>0&&!e[e.length-1]._isManuallyPaused()&&e[e.length-1]._setPausedState(!1)}},Os=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Rs=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},be=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Cs=function(e){return be(e)&&!e.shiftKey},As=function(e){return be(e)&&e.shiftKey},ut=function(e){return setTimeout(e,0)},me=function(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1&&arguments[1]!==void 0?arguments[1]:{},g=d.hasFallback,E=g===void 0?!1:g,T=d.params,F=T===void 0?[]:T,S=r[u];if(typeof S=="function"&&(S=S.apply(void 0,Is(F))),S===!0&&(S=void 0),!S){if(S===void 0||S===!1)return S;throw new Error("`".concat(u,"` was specified but was not a node, or did not return a node"))}var R=S;if(typeof S=="string"){try{R=s.querySelector(S)}catch(v){throw new Error("`".concat(u,'` appears to be an invalid selector; error="').concat(v.message,'"'))}if(!R&&!E)throw new Error("`".concat(u,"` as selector refers to no known node"))}return R},m=function(){var u=h("initialFocus",{hasFallback:!0});if(u===!1)return!1;if(u===void 0||u&&!Me(u,r.tabbableOptions))if(c(s.activeElement)>=0)u=s.activeElement;else{var d=i.tabbableGroups[0],g=d&&d.firstTabbableNode;u=g||h("fallbackFocus")}else u===null&&(u=h("fallbackFocus"));if(!u)throw new Error("Your focus-trap needs to have at least one focusable element");return u},f=function(){if(i.containerGroups=i.containers.map(function(u){var d=ys(u,r.tabbableOptions),g=ws(u,r.tabbableOptions),E=d.length>0?d[0]:void 0,T=d.length>0?d[d.length-1]:void 0,F=g.find(function(v){return ae(v)}),S=g.slice().reverse().find(function(v){return ae(v)}),R=!!d.find(function(v){return ie(v)>0});return{container:u,tabbableNodes:d,focusableNodes:g,posTabIndexesFound:R,firstTabbableNode:E,lastTabbableNode:T,firstDomTabbableNode:F,lastDomTabbableNode:S,nextTabbableNode:function(p){var I=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,O=d.indexOf(p);return O<0?I?g.slice(g.indexOf(p)+1).find(function(P){return ae(P)}):g.slice(0,g.indexOf(p)).reverse().find(function(P){return ae(P)}):d[O+(I?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(u){return u.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!h("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(u){return u.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},b=function(u){var d=u.activeElement;if(d)return d.shadowRoot&&d.shadowRoot.activeElement!==null?b(d.shadowRoot):d},y=function(u){if(u!==!1&&u!==b(document)){if(!u||!u.focus){y(m());return}u.focus({preventScroll:!!r.preventScroll}),i.mostRecentlyFocusedNode=u,Os(u)&&u.select()}},x=function(u){var d=h("setReturnFocus",{params:[u]});return d||(d===!1?!1:u)},w=function(u){var d=u.target,g=u.event,E=u.isBackward,T=E===void 0?!1:E;d=d||Ee(g),f();var F=null;if(i.tabbableGroups.length>0){var S=c(d,g),R=S>=0?i.containerGroups[S]:void 0;if(S<0)T?F=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:F=i.tabbableGroups[0].firstTabbableNode;else if(T){var v=i.tabbableGroups.findIndex(function(V){var k=V.firstTabbableNode;return d===k});if(v<0&&(R.container===d||Me(d,r.tabbableOptions)&&!ae(d,r.tabbableOptions)&&!R.nextTabbableNode(d,!1))&&(v=S),v>=0){var p=v===0?i.tabbableGroups.length-1:v-1,I=i.tabbableGroups[p];F=ie(d)>=0?I.lastTabbableNode:I.lastDomTabbableNode}else be(g)||(F=R.nextTabbableNode(d,!1))}else{var O=i.tabbableGroups.findIndex(function(V){var k=V.lastTabbableNode;return d===k});if(O<0&&(R.container===d||Me(d,r.tabbableOptions)&&!ae(d,r.tabbableOptions)&&!R.nextTabbableNode(d))&&(O=S),O>=0){var P=O===i.tabbableGroups.length-1?0:O+1,z=i.tabbableGroups[P];F=ie(d)>=0?z.firstTabbableNode:z.firstDomTabbableNode}else be(g)||(F=R.nextTabbableNode(d))}}else F=h("fallbackFocus");return F},C=function(u){var d=Ee(u);if(!(c(d,u)>=0)){if(me(r.clickOutsideDeactivates,u)){o.deactivate({returnFocus:r.returnFocusOnDeactivate});return}me(r.allowOutsideClick,u)||u.preventDefault()}},A=function(u){var d=Ee(u),g=c(d,u)>=0;if(g||d instanceof Document)g&&(i.mostRecentlyFocusedNode=d);else{u.stopImmediatePropagation();var E,T=!0;if(i.mostRecentlyFocusedNode)if(ie(i.mostRecentlyFocusedNode)>0){var F=c(i.mostRecentlyFocusedNode),S=i.containerGroups[F].tabbableNodes;if(S.length>0){var R=S.findIndex(function(v){return v===i.mostRecentlyFocusedNode});R>=0&&(r.isKeyForward(i.recentNavEvent)?R+1=0&&(E=S[R-1],T=!1))}}else i.containerGroups.some(function(v){return v.tabbableNodes.some(function(p){return ie(p)>0})})||(T=!1);else T=!1;T&&(E=w({target:i.mostRecentlyFocusedNode,isBackward:r.isKeyBackward(i.recentNavEvent)})),y(E||i.mostRecentlyFocusedNode||m())}i.recentNavEvent=void 0},J=function(u){var d=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=u;var g=w({event:u,isBackward:d});g&&(be(u)&&u.preventDefault(),y(g))},Q=function(u){(r.isKeyForward(u)||r.isKeyBackward(u))&&J(u,r.isKeyBackward(u))},W=function(u){Rs(u)&&me(r.escapeDeactivates,u)!==!1&&(u.preventDefault(),o.deactivate())},$=function(u){var d=Ee(u);c(d,u)>=0||me(r.clickOutsideDeactivates,u)||me(r.allowOutsideClick,u)||(u.preventDefault(),u.stopImmediatePropagation())},j=function(){if(i.active)return ct.activateTrap(n,o),i.delayInitialFocusTimer=r.delayInitialFocus?ut(function(){y(m())}):y(m()),s.addEventListener("focusin",A,!0),s.addEventListener("mousedown",C,{capture:!0,passive:!1}),s.addEventListener("touchstart",C,{capture:!0,passive:!1}),s.addEventListener("click",$,{capture:!0,passive:!1}),s.addEventListener("keydown",Q,{capture:!0,passive:!1}),s.addEventListener("keydown",W),o},ye=function(){if(i.active)return s.removeEventListener("focusin",A,!0),s.removeEventListener("mousedown",C,!0),s.removeEventListener("touchstart",C,!0),s.removeEventListener("click",$,!0),s.removeEventListener("keydown",Q,!0),s.removeEventListener("keydown",W),o},M=function(u){var d=u.some(function(g){var E=Array.from(g.removedNodes);return E.some(function(T){return T===i.mostRecentlyFocusedNode})});d&&y(m())},q=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(M):void 0,U=function(){q&&(q.disconnect(),i.active&&!i.paused&&i.containers.map(function(u){q.observe(u,{subtree:!0,childList:!0})}))};return o={get active(){return i.active},get paused(){return i.paused},activate:function(u){if(i.active)return this;var d=l(u,"onActivate"),g=l(u,"onPostActivate"),E=l(u,"checkCanFocusTrap");E||f(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=b(s),d==null||d();var T=function(){E&&f(),j(),U(),g==null||g()};return E?(E(i.containers.concat()).then(T,T),this):(T(),this)},deactivate:function(u){if(!i.active)return this;var d=lt({onDeactivate:r.onDeactivate,onPostDeactivate:r.onPostDeactivate,checkCanReturnFocus:r.checkCanReturnFocus},u);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,ye(),i.active=!1,i.paused=!1,U(),ct.deactivateTrap(n,o);var g=l(d,"onDeactivate"),E=l(d,"onPostDeactivate"),T=l(d,"checkCanReturnFocus"),F=l(d,"returnFocus","returnFocusOnDeactivate");g==null||g();var S=function(){ut(function(){F&&y(x(i.nodeFocusedBeforeActivation)),E==null||E()})};return F&&T?(T(x(i.nodeFocusedBeforeActivation)).then(S,S),this):(S(),this)},pause:function(u){return i.active?(i.manuallyPaused=!0,this._setPausedState(!0,u)):this},unpause:function(u){return i.active?(i.manuallyPaused=!1,n[n.length-1]!==this?this:this._setPausedState(!1,u)):this},updateContainerElements:function(u){var d=[].concat(u).filter(Boolean);return i.containers=d.map(function(g){return typeof g=="string"?s.querySelector(g):g}),i.active&&f(),U(),this}},Object.defineProperties(o,{_isManuallyPaused:{value:function(){return i.manuallyPaused}},_setPausedState:{value:function(u,d){if(i.paused===u)return this;if(i.paused=u,u){var g=l(d,"onPause"),E=l(d,"onPostPause");g==null||g(),ye(),U(),E==null||E()}else{var T=l(d,"onUnpause"),F=l(d,"onPostUnpause");T==null||T(),f(),j(),U(),F==null||F()}return this}}}),o.updateContainerElements(e),o};function Ds(a,e={}){let t;const{immediate:s,...n}=e,r=le(!1),i=le(!1),o=f=>t&&t.activate(f),l=f=>t&&t.deactivate(f),c=()=>{t&&(t.pause(),i.value=!0)},h=()=>{t&&(t.unpause(),i.value=!1)},m=ge(()=>{const f=et(a);return Rt(f).map(b=>{const y=et(b);return typeof y=="string"?y:Ct(y)}).filter(At)});return $e(m,f=>{f.length&&(t=Ls(f,{...n,onActivate(){r.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){r.value=!1,e.onDeactivate&&e.onDeactivate()}}),s&&o())},{flush:"post"}),Mt(()=>l()),{hasFocus:r,isPaused:i,activate:o,deactivate:l,pause:c,unpause:h}}class ce{constructor(e,t=!0,s=[],n=5e3){this.ctx=e,this.iframes=t,this.exclude=s,this.iframesTimeout=n}static matches(e,t){const s=typeof t=="string"?[t]:t,n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(n){let r=!1;return s.every(i=>n.call(e,i)?(r=!0,!1):!0),r}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(s=>{const n=t.filter(r=>r.contains(s)).length>0;t.indexOf(s)===-1&&!n&&t.push(s)}),t}getIframeContents(e,t,s=()=>{}){let n;try{const r=e.contentWindow;if(n=r.document,!r||!n)throw new Error("iframe inaccessible")}catch{s()}n&&t(n)}isIframeBlank(e){const t="about:blank",s=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&s!==t&&s}observeIframeLoad(e,t,s){let n=!1,r=null;const i=()=>{if(!n){n=!0,clearTimeout(r);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,s))}catch{s()}}};e.addEventListener("load",i),r=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,s){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,s):this.getIframeContents(e,t,s):this.observeIframeLoad(e,t,s)}catch{s()}}waitForIframes(e,t){let s=0;this.forEachIframe(e,()=>!0,n=>{s++,this.waitForIframes(n.querySelector("html"),()=>{--s||t()})},n=>{n||t()})}forEachIframe(e,t,s,n=()=>{}){let r=e.querySelectorAll("iframe"),i=r.length,o=0;r=Array.prototype.slice.call(r);const l=()=>{--i<=0&&n(o)};i||l(),r.forEach(c=>{ce.matches(c,this.exclude)?l():this.onIframeReady(c,h=>{t(c)&&(o++,s(h)),l()},l)})}createIterator(e,t,s){return document.createNodeIterator(e,t,s,!1)}createInstanceOnIframe(e){return new ce(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,s){const n=e.compareDocumentPosition(s),r=Node.DOCUMENT_POSITION_PRECEDING;if(n&r)if(t!==null){const i=t.compareDocumentPosition(s),o=Node.DOCUMENT_POSITION_FOLLOWING;if(i&o)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let s;return t===null?s=e.nextNode():s=e.nextNode()&&e.nextNode(),{prevNode:t,node:s}}checkIframeFilter(e,t,s,n){let r=!1,i=!1;return n.forEach((o,l)=>{o.val===s&&(r=l,i=o.handled)}),this.compareNodeIframe(e,t,s)?(r===!1&&!i?n.push({val:s,handled:!0}):r!==!1&&!i&&(n[r].handled=!0),!0):(r===!1&&n.push({val:s,handled:!1}),!1)}handleOpenIframes(e,t,s,n){e.forEach(r=>{r.handled||this.getIframeContents(r.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,s,n)})})}iterateThroughNodes(e,t,s,n,r){const i=this.createIterator(t,e,n);let o=[],l=[],c,h,m=()=>({prevNode:h,node:c}=this.getIteratorNode(i),c);for(;m();)this.iframes&&this.forEachIframe(t,f=>this.checkIframeFilter(c,h,f,o),f=>{this.createInstanceOnIframe(f).forEachNode(e,b=>l.push(b),n)}),l.push(c);l.forEach(f=>{s(f)}),this.iframes&&this.handleOpenIframes(o,e,s,n),r()}forEachNode(e,t,s,n=()=>{}){const r=this.getContexts();let i=r.length;i||n(),r.forEach(o=>{const l=()=>{this.iterateThroughNodes(e,o,t,s,()=>{--i<=0&&n()})};this.iframes?this.waitForIframes(o,l):l()})}}let Ps=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new ce(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const s=this.opt.log;this.opt.debug&&typeof s=="object"&&typeof s[t]=="function"&&s[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,s=this.opt.caseSensitive?"":"i",n=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let r in t)if(t.hasOwnProperty(r)){const i=t[r],o=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(r):this.escapeStr(r),l=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);o!==""&&l!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(o)}|${this.escapeStr(l)})`,`gm${s}`),n+`(${this.processSynomyms(o)}|${this.processSynomyms(l)})`+n))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,s,n)=>{let r=n.charAt(s+1);return/[(|)\\]/.test(r)||r===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const s=this.opt.ignorePunctuation;return Array.isArray(s)&&s.length&&t.push(this.escapeStr(s.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",s=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let n=[];return e.split("").forEach(r=>{s.every(i=>{if(i.indexOf(r)!==-1){if(n.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),n.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let s=this.opt.accuracy,n=typeof s=="string"?s:s.value,r=typeof s=="string"?[]:s.limiters,i="";switch(r.forEach(o=>{i+=`|${this.escapeStr(o)}`}),n){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(s=>{this.opt.separateWordSearch?s.split(" ").forEach(n=>{n.trim()&&t.indexOf(n)===-1&&t.push(n)}):s.trim()&&t.indexOf(s)===-1&&t.push(s)}),{keywords:t.sort((s,n)=>n.length-s.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let s=0;return e.sort((n,r)=>n.start-r.start).forEach(n=>{let{start:r,end:i,valid:o}=this.callNoMatchOnInvalidRanges(n,s);o&&(n.start=r,n.length=i-r,t.push(n),s=i)}),t}callNoMatchOnInvalidRanges(e,t){let s,n,r=!1;return e&&typeof e.start<"u"?(s=parseInt(e.start,10),n=s+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&n-t>0&&n-s>0?r=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:s,end:n,valid:r}}checkWhitespaceRanges(e,t,s){let n,r=!0,i=s.length,o=t-i,l=parseInt(e.start,10)-o;return l=l>i?i:l,n=l+parseInt(e.length,10),n>i&&(n=i,this.log(`End range automatically set to the max value of ${i}`)),l<0||n-l<0||l>i||n>i?(r=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):s.substring(l,n).replace(/\s+/g,"")===""&&(r=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:l,end:n,valid:r}}getTextNodes(e){let t="",s=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,n=>{s.push({start:t.length,end:(t+=n.textContent).length,node:n})},n=>this.matchesExclude(n.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:s})})}matchesExclude(e){return ce.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,s){const n=this.opt.element?this.opt.element:"mark",r=e.splitText(t),i=r.splitText(s-t);let o=document.createElement(n);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=r.textContent,r.parentNode.replaceChild(o,r),i}wrapRangeInMappedTextNode(e,t,s,n,r){e.nodes.every((i,o)=>{const l=e.nodes[o+1];if(typeof l>"u"||l.start>t){if(!n(i.node))return!1;const c=t-i.start,h=(s>i.end?i.end:s)-i.start,m=e.value.substr(0,i.start),f=e.value.substr(h+i.start);if(i.node=this.wrapRangeInTextNode(i.node,c,h),e.value=m+f,e.nodes.forEach((b,y)=>{y>=o&&(e.nodes[y].start>0&&y!==o&&(e.nodes[y].start-=h),e.nodes[y].end-=h)}),s-=h,r(i.node.previousSibling,i.start),s>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,s,n,r){const i=t===0?0:t+1;this.getTextNodes(o=>{o.nodes.forEach(l=>{l=l.node;let c;for(;(c=e.exec(l.textContent))!==null&&c[i]!=="";){if(!s(c[i],l))continue;let h=c.index;if(i!==0)for(let m=1;m{let l;for(;(l=e.exec(o.value))!==null&&l[i]!=="";){let c=l.index;if(i!==0)for(let m=1;ms(l[i],m),(m,f)=>{e.lastIndex=f,n(m)})}r()})}wrapRangeFromIndex(e,t,s,n){this.getTextNodes(r=>{const i=r.value.length;e.forEach((o,l)=>{let{start:c,end:h,valid:m}=this.checkWhitespaceRanges(o,i,r.value);m&&this.wrapRangeInMappedTextNode(r,c,h,f=>t(f,o,r.value.substring(c,h),l),f=>{s(f,o)})}),n()})}unwrapMatches(e){const t=e.parentNode;let s=document.createDocumentFragment();for(;e.firstChild;)s.appendChild(e.removeChild(e.firstChild));t.replaceChild(s,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let s=0,n="wrapMatches";const r=i=>{s++,this.opt.each(i)};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),this[n](e,this.opt.ignoreGroups,(i,o)=>this.opt.filter(o,i,s),r,()=>{s===0&&this.opt.noMatch(e),this.opt.done(s)})}mark(e,t){this.opt=t;let s=0,n="wrapMatches";const{keywords:r,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),o=this.opt.caseSensitive?"":"i",l=c=>{let h=new RegExp(this.createRegExp(c),`gm${o}`),m=0;this.log(`Searching with expression "${h}"`),this[n](h,1,(f,b)=>this.opt.filter(b,c,s,m),f=>{m++,s++,this.opt.each(f)},()=>{m===0&&this.opt.noMatch(c),r[i-1]===c?this.opt.done(s):l(r[r.indexOf(c)+1])})};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),i===0?this.opt.done(s):l(r[0])}markRanges(e,t){this.opt=t;let s=0,n=this.checkRanges(e);n&&n.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(n)),this.wrapRangeFromIndex(n,(r,i,o,l)=>this.opt.filter(r,i,o,l),(r,i)=>{s++,this.opt.each(r,i)},()=>{this.opt.done(s)})):this.opt.done(s)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,s=>{this.unwrapMatches(s)},s=>{const n=ce.matches(s,t),r=this.matchesExclude(s);return!n||r?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function zs(a){const e=new Ps(a);return this.mark=(t,s)=>(e.mark(t,s),this),this.markRegExp=(t,s)=>(e.markRegExp(t,s),this),this.markRanges=(t,s)=>(e.markRanges(t,s),this),this.unmark=t=>(e.unmark(t),this),this}const Vs="ENTRIES",xt="KEYS",_t="VALUES",D="";class Le{constructor(e,t){const s=e._tree,n=Array.from(s.keys());this.set=e,this._type=t,this._path=n.length>0?[{node:s,keys:n}]:[]}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return{done:!0,value:void 0};const{node:e,keys:t}=oe(this._path);if(oe(t)===D)return{done:!1,value:this.result()};const s=e.get(oe(t));return this._path.push({node:s,keys:Array.from(s.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=oe(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:e})=>oe(e)).filter(e=>e!==D).join("")}value(){return oe(this._path).node.get(D)}result(){switch(this._type){case _t:return this.value();case xt:return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}const oe=a=>a[a.length-1],$s=(a,e,t)=>{const s=new Map;if(e===void 0)return s;const n=e.length+1,r=n+t,i=new Uint8Array(r*n).fill(t+1);for(let o=0;o{const l=r*i;e:for(const c of a.keys())if(c===D){const h=n[l-1];h<=t&&s.set(o,[a.get(c),h])}else{let h=r;for(let m=0;mt)continue e}St(a.get(c),e,t,s,n,h,i,o+c)}};class X{constructor(e=new Map,t=""){this._size=void 0,this._tree=e,this._prefix=t}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[t,s]=Re(this._tree,e.slice(this._prefix.length));if(t===void 0){const[n,r]=qe(s);for(const i of n.keys())if(i!==D&&i.startsWith(r)){const o=new Map;return o.set(i.slice(r.length),n.get(i)),new X(o,e)}}return new X(t,e)}clear(){this._size=void 0,this._tree.clear()}delete(e){return this._size=void 0,js(this._tree,e)}entries(){return new Le(this,Vs)}forEach(e){for(const[t,s]of this)e(t,s,this)}fuzzyGet(e,t){return $s(this._tree,e,t)}get(e){const t=We(this._tree,e);return t!==void 0?t.get(D):void 0}has(e){const t=We(this._tree,e);return t!==void 0&&t.has(D)}keys(){return new Le(this,xt)}set(e,t){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,De(this._tree,e).set(D,t),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=De(this._tree,e);return s.set(D,t(s.get(D))),this}fetch(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=De(this._tree,e);let n=s.get(D);return n===void 0&&s.set(D,n=t()),n}values(){return new Le(this,_t)}[Symbol.iterator](){return this.entries()}static from(e){const t=new X;for(const[s,n]of e)t.set(s,n);return t}static fromObject(e){return X.from(Object.entries(e))}}const Re=(a,e,t=[])=>{if(e.length===0||a==null)return[a,t];for(const s of a.keys())if(s!==D&&e.startsWith(s))return t.push([a,s]),Re(a.get(s),e.slice(s.length),t);return t.push([a,e]),Re(void 0,"",t)},We=(a,e)=>{if(e.length===0||a==null)return a;for(const t of a.keys())if(t!==D&&e.startsWith(t))return We(a.get(t),e.slice(t.length))},De=(a,e)=>{const t=e.length;e:for(let s=0;a&&s{const[t,s]=Re(a,e);if(t!==void 0){if(t.delete(D),t.size===0)Et(s);else if(t.size===1){const[n,r]=t.entries().next().value;Tt(s,n,r)}}},Et=a=>{if(a.length===0)return;const[e,t]=qe(a);if(e.delete(t),e.size===0)Et(a.slice(0,-1));else if(e.size===1){const[s,n]=e.entries().next().value;s!==D&&Tt(a.slice(0,-1),s,n)}},Tt=(a,e,t)=>{if(a.length===0)return;const[s,n]=qe(a);s.set(n+e,t),s.delete(n)},qe=a=>a[a.length-1],Ue="or",It="and",Bs="and_not";class ue{constructor(e){if((e==null?void 0:e.fields)==null)throw new Error('MiniSearch: option "fields" must be provided');const t=e.autoVacuum==null||e.autoVacuum===!0?Ve:e.autoVacuum;this._options={...ze,...e,autoVacuum:t,searchOptions:{...dt,...e.searchOptions||{}},autoSuggestOptions:{...Us,...e.autoSuggestOptions||{}}},this._index=new X,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=Je,this.addFields(this._options.fields)}add(e){const{extractField:t,tokenize:s,processTerm:n,fields:r,idField:i}=this._options,o=t(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);if(this._idToShortId.has(o))throw new Error(`MiniSearch: duplicate ID ${o}`);const l=this.addDocumentId(o);this.saveStoredFields(l,e);for(const c of r){const h=t(e,c);if(h==null)continue;const m=s(h.toString(),c),f=this._fieldIds[c],b=new Set(m).size;this.addFieldLength(l,f,this._documentCount-1,b);for(const y of m){const x=n(y,c);if(Array.isArray(x))for(const w of x)this.addTerm(f,l,w);else x&&this.addTerm(f,l,x)}}}addAll(e){for(const t of e)this.add(t)}addAllAsync(e,t={}){const{chunkSize:s=10}=t,n={chunk:[],promise:Promise.resolve()},{chunk:r,promise:i}=e.reduce(({chunk:o,promise:l},c,h)=>(o.push(c),(h+1)%s===0?{chunk:[],promise:l.then(()=>new Promise(m=>setTimeout(m,0))).then(()=>this.addAll(o))}:{chunk:o,promise:l}),n);return i.then(()=>this.addAll(r))}remove(e){const{tokenize:t,processTerm:s,extractField:n,fields:r,idField:i}=this._options,o=n(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);const l=this._idToShortId.get(o);if(l==null)throw new Error(`MiniSearch: cannot remove document with ID ${o}: it is not in the index`);for(const c of r){const h=n(e,c);if(h==null)continue;const m=t(h.toString(),c),f=this._fieldIds[c],b=new Set(m).size;this.removeFieldLength(l,f,this._documentCount,b);for(const y of m){const x=s(y,c);if(Array.isArray(x))for(const w of x)this.removeTerm(f,l,w);else x&&this.removeTerm(f,l,x)}}this._storedFields.delete(l),this._documentIds.delete(l),this._idToShortId.delete(o),this._fieldLength.delete(l),this._documentCount-=1}removeAll(e){if(e)for(const t of e)this.remove(t);else{if(arguments.length>0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new X,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}}discard(e){const t=this._idToShortId.get(e);if(t==null)throw new Error(`MiniSearch: cannot discard document with ID ${e}: it is not in the index`);this._idToShortId.delete(e),this._documentIds.delete(t),this._storedFields.delete(t),(this._fieldLength.get(t)||[]).forEach((s,n)=>{this.removeFieldLength(t,n,this._documentCount,s)}),this._fieldLength.delete(t),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()}maybeAutoVacuum(){if(this._options.autoVacuum===!1)return;const{minDirtFactor:e,minDirtCount:t,batchSize:s,batchWait:n}=this._options.autoVacuum;this.conditionalVacuum({batchSize:s,batchWait:n},{minDirtCount:t,minDirtFactor:e})}discardAll(e){const t=this._options.autoVacuum;try{this._options.autoVacuum=!1;for(const s of e)this.discard(s)}finally{this._options.autoVacuum=t}this.maybeAutoVacuum()}replace(e){const{idField:t,extractField:s}=this._options,n=s(e,t);this.discard(n),this.add(e)}vacuum(e={}){return this.conditionalVacuum(e)}conditionalVacuum(e,t){return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(()=>{const s=this._enqueuedVacuumConditions;return this._enqueuedVacuumConditions=Je,this.performVacuuming(e,s)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)}async performVacuuming(e,t){const s=this._dirtCount;if(this.vacuumConditionsMet(t)){const n=e.batchSize||Ke.batchSize,r=e.batchWait||Ke.batchWait;let i=1;for(const[o,l]of this._index){for(const[c,h]of l)for(const[m]of h)this._documentIds.has(m)||(h.size<=1?l.delete(c):h.delete(m));this._index.get(o).size===0&&this._index.delete(o),i%n===0&&await new Promise(c=>setTimeout(c,r)),i+=1}this._dirtCount-=s}await null,this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null}vacuumConditionsMet(e){if(e==null)return!0;let{minDirtCount:t,minDirtFactor:s}=e;return t=t||Ve.minDirtCount,s=s||Ve.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=s}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}has(e){return this._idToShortId.has(e)}getStoredFields(e){const t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)}search(e,t={}){const{searchOptions:s}=this._options,n={...s,...t},r=this.executeQuery(e,t),i=[];for(const[o,{score:l,terms:c,match:h}]of r){const m=c.length||1,f={id:this._documentIds.get(o),score:l*m,terms:Object.keys(h),queryTerms:c,match:h};Object.assign(f,this._storedFields.get(o)),(n.filter==null||n.filter(f))&&i.push(f)}return e===ue.wildcard&&n.boostDocument==null||i.sort(ft),i}autoSuggest(e,t={}){t={...this._options.autoSuggestOptions,...t};const s=new Map;for(const{score:r,terms:i}of this.search(e,t)){const o=i.join(" "),l=s.get(o);l!=null?(l.score+=r,l.count+=1):s.set(o,{score:r,terms:i,count:1})}const n=[];for(const[r,{score:i,terms:o,count:l}]of s)n.push({suggestion:r,terms:o,score:i/l});return n.sort(ft),n}get documentCount(){return this._documentCount}get termCount(){return this._index.size}static loadJSON(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)}static async loadJSONAsync(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJSAsync(JSON.parse(e),t)}static getDefault(e){if(ze.hasOwnProperty(e))return Pe(ze,e);throw new Error(`MiniSearch: unknown option "${e}"`)}static loadJS(e,t){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=Te(n),l._fieldLength=Te(r),l._storedFields=Te(i);for(const[c,h]of l._documentIds)l._idToShortId.set(h,c);for(const[c,h]of s){const m=new Map;for(const f of Object.keys(h)){let b=h[f];o===1&&(b=b.ds),m.set(parseInt(f,10),Te(b))}l._index.set(c,m)}return l}static async loadJSAsync(e,t){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=await Ie(n),l._fieldLength=await Ie(r),l._storedFields=await Ie(i);for(const[h,m]of l._documentIds)l._idToShortId.set(m,h);let c=0;for(const[h,m]of s){const f=new Map;for(const b of Object.keys(m)){let y=m[b];o===1&&(y=y.ds),f.set(parseInt(b,10),await Ie(y))}++c%1e3===0&&await kt(0),l._index.set(h,f)}return l}static instantiateMiniSearch(e,t){const{documentCount:s,nextId:n,fieldIds:r,averageFieldLength:i,dirtCount:o,serializationVersion:l}=e;if(l!==1&&l!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");const c=new ue(t);return c._documentCount=s,c._nextId=n,c._idToShortId=new Map,c._fieldIds=r,c._avgFieldLength=i,c._dirtCount=o||0,c._index=new X,c}executeQuery(e,t={}){if(e===ue.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){const f={...t,...e,queries:void 0},b=e.queries.map(y=>this.executeQuery(y,f));return this.combineResults(b,f.combineWith)}const{tokenize:s,processTerm:n,searchOptions:r}=this._options,i={tokenize:s,processTerm:n,...r,...t},{tokenize:o,processTerm:l}=i,m=o(e).flatMap(f=>l(f)).filter(f=>!!f).map(qs(i)).map(f=>this.executeQuerySpec(f,i));return this.combineResults(m,i.combineWith)}executeQuerySpec(e,t){const s={...this._options.searchOptions,...t},n=(s.fields||this._options.fields).reduce((x,w)=>({...x,[w]:Pe(s.boost,w)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:o,bm25:l}=s,{fuzzy:c,prefix:h}={...dt.weights,...i},m=this._index.get(e.term),f=this.termResults(e.term,e.term,1,e.termBoost,m,n,r,l);let b,y;if(e.prefix&&(b=this._index.atPrefix(e.term)),e.fuzzy){const x=e.fuzzy===!0?.2:e.fuzzy,w=x<1?Math.min(o,Math.round(e.term.length*x)):x;w&&(y=this._index.fuzzyGet(e.term,w))}if(b)for(const[x,w]of b){const C=x.length-e.term.length;if(!C)continue;y==null||y.delete(x);const A=h*x.length/(x.length+.3*C);this.termResults(e.term,x,A,e.termBoost,w,n,r,l,f)}if(y)for(const x of y.keys()){const[w,C]=y.get(x);if(!C)continue;const A=c*x.length/(x.length+C);this.termResults(e.term,x,A,e.termBoost,w,n,r,l,f)}return f}executeWildcardQuery(e){const t=new Map,s={...this._options.searchOptions,...e};for(const[n,r]of this._documentIds){const i=s.boostDocument?s.boostDocument(r,"",this._storedFields.get(n)):1;t.set(n,{score:i,terms:[],match:{}})}return t}combineResults(e,t=Ue){if(e.length===0)return new Map;const s=t.toLowerCase(),n=Ws[s];if(!n)throw new Error(`Invalid combination operator: ${t}`);return e.reduce(n)||new Map}toJSON(){const e=[];for(const[t,s]of this._index){const n={};for(const[r,i]of s)n[r]=Object.fromEntries(i);e.push([t,n])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,serializationVersion:2}}termResults(e,t,s,n,r,i,o,l,c=new Map){if(r==null)return c;for(const h of Object.keys(i)){const m=i[h],f=this._fieldIds[h],b=r.get(f);if(b==null)continue;let y=b.size;const x=this._avgFieldLength[f];for(const w of b.keys()){if(!this._documentIds.has(w)){this.removeTerm(f,w,t),y-=1;continue}const C=o?o(this._documentIds.get(w),t,this._storedFields.get(w)):1;if(!C)continue;const A=b.get(w),J=this._fieldLength.get(w)[f],Q=Js(A,y,this._documentCount,J,x,l),W=s*n*m*C*Q,$=c.get(w);if($){$.score+=W,Gs($.terms,e);const j=Pe($.match,t);j?j.push(h):$.match[t]=[h]}else c.set(w,{score:W,terms:[e],match:{[t]:[h]}})}}return c}addTerm(e,t,s){const n=this._index.fetch(s,pt);let r=n.get(e);if(r==null)r=new Map,r.set(t,1),n.set(e,r);else{const i=r.get(t);r.set(t,(i||0)+1)}}removeTerm(e,t,s){if(!this._index.has(s)){this.warnDocumentChanged(t,e,s);return}const n=this._index.fetch(s,pt),r=n.get(e);r==null||r.get(t)==null?this.warnDocumentChanged(t,e,s):r.get(t)<=1?r.size<=1?n.delete(e):r.delete(t):r.set(t,r.get(t)-1),this._index.get(s).size===0&&this._index.delete(s)}warnDocumentChanged(e,t,s){for(const n of Object.keys(this._fieldIds))if(this._fieldIds[n]===t){this._options.logger("warn",`MiniSearch: document with ID ${this._documentIds.get(e)} has changed before removal: term "${s}" was not present in field "${n}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}}addDocumentId(e){const t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t}addFields(e){for(let t=0;tObject.prototype.hasOwnProperty.call(a,e)?a[e]:void 0,Ws={[Ue]:(a,e)=>{for(const t of e.keys()){const s=a.get(t);if(s==null)a.set(t,e.get(t));else{const{score:n,terms:r,match:i}=e.get(t);s.score=s.score+n,s.match=Object.assign(s.match,i),ht(s.terms,r)}}return a},[It]:(a,e)=>{const t=new Map;for(const s of e.keys()){const n=a.get(s);if(n==null)continue;const{score:r,terms:i,match:o}=e.get(s);ht(n.terms,i),t.set(s,{score:n.score+r,terms:n.terms,match:Object.assign(n.match,o)})}return t},[Bs]:(a,e)=>{for(const t of e.keys())a.delete(t);return a}},Ks={k:1.2,b:.7,d:.5},Js=(a,e,t,s,n,r)=>{const{k:i,b:o,d:l}=r;return Math.log(1+(t-e+.5)/(e+.5))*(l+a*(i+1)/(a+i*(1-o+o*s/n)))},qs=a=>(e,t,s)=>{const n=typeof a.fuzzy=="function"?a.fuzzy(e,t,s):a.fuzzy||!1,r=typeof a.prefix=="function"?a.prefix(e,t,s):a.prefix===!0,i=typeof a.boostTerm=="function"?a.boostTerm(e,t,s):1;return{term:e,fuzzy:n,prefix:r,termBoost:i}},ze={idField:"id",extractField:(a,e)=>a[e],tokenize:a=>a.split(Hs),processTerm:a=>a.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(a,e)=>{typeof(console==null?void 0:console[a])=="function"&&console[a](e)},autoVacuum:!0},dt={combineWith:Ue,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Ks},Us={combineWith:It,prefix:(a,e,t)=>e===t.length-1},Ke={batchSize:1e3,batchWait:10},Je={minDirtFactor:.1,minDirtCount:20},Ve={...Ke,...Je},Gs=(a,e)=>{a.includes(e)||a.push(e)},ht=(a,e)=>{for(const t of e)a.includes(t)||a.push(t)},ft=({score:a},{score:e})=>e-a,pt=()=>new Map,Te=a=>{const e=new Map;for(const t of Object.keys(a))e.set(parseInt(t,10),a[t]);return e},Ie=async a=>{const e=new Map;let t=0;for(const s of Object.keys(a))e.set(parseInt(s,10),a[s]),++t%1e3===0&&await kt(0);return e},kt=a=>new Promise(e=>setTimeout(e,a)),Hs=/[\n\r\p{Z}\p{P}]+/u;class Qs{constructor(e=10){Ce(this,"max");Ce(this,"cache");this.max=e,this.cache=new Map}get(e){let t=this.cache.get(e);return t!==void 0&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){this.cache.has(e)?this.cache.delete(e):this.cache.size===this.max&&this.cache.delete(this.first()),this.cache.set(e,t)}first(){return this.cache.keys().next().value}clear(){this.cache.clear()}}const Ys=["aria-owns"],Zs={class:"shell"},Xs=["title"],en={class:"search-actions before"},tn=["title"],sn=["aria-activedescendant","aria-controls","placeholder"],nn={class:"search-actions"},rn=["title"],an=["disabled","title"],on=["id","role","aria-labelledby"],ln=["id","aria-selected"],cn=["href","aria-label","onMouseenter","onFocusin","data-index"],un={class:"titles"},dn=["innerHTML"],hn={class:"title main"},fn=["innerHTML"],pn={key:0,class:"excerpt-wrapper"},vn={key:0,class:"excerpt",inert:""},mn=["innerHTML"],gn={key:0,class:"no-results"},bn={class:"search-keyboard-shortcuts"},yn=["aria-label"],wn=["aria-label"],xn=["aria-label"],_n=["aria-label"],Sn=Lt({__name:"VPLocalSearchBox",emits:["close"],setup(a,{emit:e}){var S,R;const t=e,s=le(),n=le(),r=le(is),i=ss(),{activate:o}=Ds(s,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:l,theme:c}=i,h=tt(async()=>{var v,p,I,O,P,z,V,k,K;return rt(ue.loadJSON((I=await((p=(v=r.value)[l.value])==null?void 0:p.call(v)))==null?void 0:I.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1},...((O=c.value.search)==null?void 0:O.provider)==="local"&&((z=(P=c.value.search.options)==null?void 0:P.miniSearch)==null?void 0:z.searchOptions)},...((V=c.value.search)==null?void 0:V.provider)==="local"&&((K=(k=c.value.search.options)==null?void 0:k.miniSearch)==null?void 0:K.options)}))}),f=ge(()=>{var v,p;return((v=c.value.search)==null?void 0:v.provider)==="local"&&((p=c.value.search.options)==null?void 0:p.disableQueryPersistence)===!0}).value?he(""):Dt("vitepress:local-search-filter",""),b=Pt("vitepress:local-search-detailed-list",((S=c.value.search)==null?void 0:S.provider)==="local"&&((R=c.value.search.options)==null?void 0:R.detailedView)===!0),y=ge(()=>{var v,p,I;return((v=c.value.search)==null?void 0:v.provider)==="local"&&(((p=c.value.search.options)==null?void 0:p.disableDetailedView)===!0||((I=c.value.search.options)==null?void 0:I.detailedView)===!1)}),x=ge(()=>{var p,I,O,P,z,V,k;const v=((p=c.value.search)==null?void 0:p.options)??c.value.algolia;return((z=(P=(O=(I=v==null?void 0:v.locales)==null?void 0:I[l.value])==null?void 0:O.translations)==null?void 0:P.button)==null?void 0:z.buttonText)||((k=(V=v==null?void 0:v.translations)==null?void 0:V.button)==null?void 0:k.buttonText)||"Search"});zt(()=>{y.value&&(b.value=!1)});const w=le([]),C=he(!1);$e(f,()=>{C.value=!1});const A=tt(async()=>{if(n.value)return rt(new zs(n.value))},null),J=new Qs(16);Vt(()=>[h.value,f.value,b.value],async([v,p,I],O,P)=>{var ee,we,Ge,He;(O==null?void 0:O[0])!==v&&J.clear();let z=!1;if(P(()=>{z=!0}),!v)return;w.value=v.search(p).slice(0,16),C.value=!0;const V=I?await Promise.all(w.value.map(B=>Q(B.id))):[];if(z)return;for(const{id:B,mod:te}of V){const se=B.slice(0,B.indexOf("#"));let Y=J.get(se);if(Y)continue;Y=new Map,J.set(se,Y);const G=te.default??te;if(G!=null&&G.render||G!=null&&G.setup){const ne=Yt(G);ne.config.warnHandler=()=>{},ne.provide(Zt,i),Object.defineProperties(ne.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const Qe=document.createElement("div");ne.mount(Qe),Qe.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(de=>{var Xe;const xe=(Xe=de.querySelector("a"))==null?void 0:Xe.getAttribute("href"),Ye=(xe==null?void 0:xe.startsWith("#"))&&xe.slice(1);if(!Ye)return;let Ze="";for(;(de=de.nextElementSibling)&&!/^h[1-6]$/i.test(de.tagName);)Ze+=de.outerHTML;Y.set(Ye,Ze)}),ne.unmount()}if(z)return}const k=new Set;if(w.value=w.value.map(B=>{const[te,se]=B.id.split("#"),Y=J.get(te),G=(Y==null?void 0:Y.get(se))??"";for(const ne in B.match)k.add(ne);return{...B,text:G}}),await fe(),z)return;await new Promise(B=>{var te;(te=A.value)==null||te.unmark({done:()=>{var se;(se=A.value)==null||se.markRegExp(T(k),{done:B})}})});const K=((ee=s.value)==null?void 0:ee.querySelectorAll(".result .excerpt"))??[];for(const B of K)(we=B.querySelector('mark[data-markjs="true"]'))==null||we.scrollIntoView({block:"center"});(He=(Ge=n.value)==null?void 0:Ge.firstElementChild)==null||He.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function Q(v){const p=Xt(v.slice(0,v.indexOf("#")));try{if(!p)throw new Error(`Cannot find file for id: ${v}`);return{id:v,mod:await import(p)}}catch(I){return console.error(I),{id:v,mod:{}}}}const W=he(),$=ge(()=>{var v;return((v=f.value)==null?void 0:v.length)<=0});function j(v=!0){var p,I;(p=W.value)==null||p.focus(),v&&((I=W.value)==null||I.select())}Ae(()=>{j()});function ye(v){v.pointerType==="mouse"&&j()}const M=he(-1),q=he(!0);$e(w,v=>{M.value=v.length?0:-1,U()});function U(){fe(()=>{const v=document.querySelector(".result.selected");v==null||v.scrollIntoView({block:"nearest"})})}_e("ArrowUp",v=>{v.preventDefault(),M.value--,M.value<0&&(M.value=w.value.length-1),q.value=!0,U()}),_e("ArrowDown",v=>{v.preventDefault(),M.value++,M.value>=w.value.length&&(M.value=0),q.value=!0,U()});const N=$t();_e("Enter",v=>{if(v.isComposing||v.target instanceof HTMLButtonElement&&v.target.type!=="submit")return;const p=w.value[M.value];if(v.target instanceof HTMLInputElement&&!p){v.preventDefault();return}p&&(N.go(p.id),t("close"))}),_e("Escape",()=>{t("close")});const d=ns({modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}});Ae(()=>{window.history.pushState(null,"",null)}),jt("popstate",v=>{v.preventDefault(),t("close")});const g=Bt(Wt?document.body:null);Ae(()=>{fe(()=>{g.value=!0,fe().then(()=>o())})}),Kt(()=>{g.value=!1});function E(){f.value="",fe().then(()=>j(!1))}function T(v){return new RegExp([...v].sort((p,I)=>I.length-p.length).map(p=>`(${es(p)})`).join("|"),"gi")}function F(v){var O;if(!q.value)return;const p=(O=v.target)==null?void 0:O.closest(".result"),I=Number.parseInt(p==null?void 0:p.dataset.index);I>=0&&I!==M.value&&(M.value=I),q.value=!1}return(v,p)=>{var I,O,P,z,V;return H(),Jt(Qt,{to:"body"},[_("div",{ref_key:"el",ref:s,role:"button","aria-owns":(I=w.value)!=null&&I.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[_("div",{class:"backdrop",onClick:p[0]||(p[0]=k=>v.$emit("close"))}),_("div",Zs,[_("form",{class:"search-bar",onPointerup:p[4]||(p[4]=k=>ye(k)),onSubmit:p[5]||(p[5]=qt(()=>{},["prevent"]))},[_("label",{title:x.value,id:"localsearch-label",for:"localsearch-input"},p[7]||(p[7]=[_("span",{"aria-hidden":"true",class:"vpi-search search-icon local-search-icon"},null,-1)]),8,Xs),_("div",en,[_("button",{class:"back-button",title:L(d)("modal.backButtonTitle"),onClick:p[1]||(p[1]=k=>v.$emit("close"))},p[8]||(p[8]=[_("span",{class:"vpi-arrow-left local-search-icon"},null,-1)]),8,tn)]),Ut(_("input",{ref_key:"searchInput",ref:W,"onUpdate:modelValue":p[2]||(p[2]=k=>Ht(f)?f.value=k:null),"aria-activedescendant":M.value>-1?"localsearch-item-"+M.value:void 0,"aria-autocomplete":"both","aria-controls":(O=w.value)!=null&&O.length?"localsearch-list":void 0,"aria-labelledby":"localsearch-label",autocapitalize:"off",autocomplete:"off",autocorrect:"off",class:"search-input",id:"localsearch-input",enterkeyhint:"go",maxlength:"64",placeholder:x.value,spellcheck:"false",type:"search"},null,8,sn),[[Gt,L(f)]]),_("div",nn,[y.value?Se("",!0):(H(),Z("button",{key:0,class:st(["toggle-layout-button",{"detailed-list":L(b)}]),type:"button",title:L(d)("modal.displayDetails"),onClick:p[3]||(p[3]=k=>M.value>-1&&(b.value=!L(b)))},p[9]||(p[9]=[_("span",{class:"vpi-layout-list local-search-icon"},null,-1)]),10,rn)),_("button",{class:"clear-button",type:"reset",disabled:$.value,title:L(d)("modal.resetButtonTitle"),onClick:E},p[10]||(p[10]=[_("span",{class:"vpi-delete local-search-icon"},null,-1)]),8,an)])],32),_("ul",{ref_key:"resultsEl",ref:n,id:(P=w.value)!=null&&P.length?"localsearch-list":void 0,role:(z=w.value)!=null&&z.length?"listbox":void 0,"aria-labelledby":(V=w.value)!=null&&V.length?"localsearch-label":void 0,class:"results",onMousemove:F},[(H(!0),Z(it,null,nt(w.value,(k,K)=>(H(),Z("li",{key:k.id,id:"localsearch-item-"+K,"aria-selected":M.value===K?"true":"false",role:"option"},[_("a",{href:k.id,class:st(["result",{selected:M.value===K}]),"aria-label":[...k.titles,k.title].join(" > "),onMouseenter:ee=>!q.value&&(M.value=K),onFocusin:ee=>M.value=K,onClick:p[6]||(p[6]=ee=>v.$emit("close")),"data-index":K},[_("div",null,[_("div",un,[p[12]||(p[12]=_("span",{class:"title-icon"},"#",-1)),(H(!0),Z(it,null,nt(k.titles,(ee,we)=>(H(),Z("span",{key:we,class:"title"},[_("span",{class:"text",innerHTML:ee},null,8,dn),p[11]||(p[11]=_("span",{class:"vpi-chevron-right local-search-icon"},null,-1))]))),128)),_("span",hn,[_("span",{class:"text",innerHTML:k.title},null,8,fn)])]),L(b)?(H(),Z("div",pn,[k.text?(H(),Z("div",vn,[_("div",{class:"vp-doc",innerHTML:k.text},null,8,mn)])):Se("",!0),p[13]||(p[13]=_("div",{class:"excerpt-gradient-bottom"},null,-1)),p[14]||(p[14]=_("div",{class:"excerpt-gradient-top"},null,-1))])):Se("",!0)])],42,cn)],8,ln))),128)),L(f)&&!w.value.length&&C.value?(H(),Z("li",gn,[pe(ve(L(d)("modal.noResultsText"))+' "',1),_("strong",null,ve(L(f)),1),p[15]||(p[15]=pe('" '))])):Se("",!0)],40,on),_("div",bn,[_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.navigateUpKeyAriaLabel")},p[16]||(p[16]=[_("span",{class:"vpi-arrow-up navigate-icon"},null,-1)]),8,yn),_("kbd",{"aria-label":L(d)("modal.footer.navigateDownKeyAriaLabel")},p[17]||(p[17]=[_("span",{class:"vpi-arrow-down navigate-icon"},null,-1)]),8,wn),pe(" "+ve(L(d)("modal.footer.navigateText")),1)]),_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.selectKeyAriaLabel")},p[18]||(p[18]=[_("span",{class:"vpi-corner-down-left navigate-icon"},null,-1)]),8,xn),pe(" "+ve(L(d)("modal.footer.selectText")),1)]),_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.closeKeyAriaLabel")},"esc",8,_n),pe(" "+ve(L(d)("modal.footer.closeText")),1)])])])],8,Ys)])}}}),Fn=ts(Sn,[["__scopeId","data-v-ce626c7c"]]);export{Fn as default}; diff --git a/docs/.vitepress/dist/assets/chunks/framework.B8KKhRA6.js b/docs/.vitepress/dist/assets/chunks/framework.B8KKhRA6.js deleted file mode 100644 index b9ff519..0000000 --- a/docs/.vitepress/dist/assets/chunks/framework.B8KKhRA6.js +++ /dev/null @@ -1,18 +0,0 @@ -/** -* @vue/shared v3.5.17 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**//*! #__NO_SIDE_EFFECTS__ */function Ms(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ne={},At=[],ke=()=>{},Ao=()=>!1,Qt=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Is=e=>e.startsWith("onUpdate:"),ue=Object.assign,Ps=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Ro=Object.prototype.hasOwnProperty,Q=(e,t)=>Ro.call(e,t),B=Array.isArray,Rt=e=>On(e)==="[object Map]",qr=e=>On(e)==="[object Set]",G=e=>typeof e=="function",le=e=>typeof e=="string",Je=e=>typeof e=="symbol",se=e=>e!==null&&typeof e=="object",Gr=e=>(se(e)||G(e))&&G(e.then)&&G(e.catch),Xr=Object.prototype.toString,On=e=>Xr.call(e),Oo=e=>On(e).slice(8,-1),Yr=e=>On(e)==="[object Object]",Ls=e=>le(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ot=Ms(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Mn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Mo=/-(\w)/g,Ne=Mn(e=>e.replace(Mo,(t,n)=>n?n.toUpperCase():"")),Io=/\B([A-Z])/g,lt=Mn(e=>e.replace(Io,"-$1").toLowerCase()),In=Mn(e=>e.charAt(0).toUpperCase()+e.slice(1)),mn=Mn(e=>e?`on${In(e)}`:""),rt=(e,t)=>!Object.is(e,t),Gn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},Po=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Lo=e=>{const t=le(e)?Number(e):NaN;return isNaN(t)?e:t};let tr;const Pn=()=>tr||(tr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Ns(e){if(B(e)){const t={};for(let n=0;n{if(n){const s=n.split(Fo);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Fs(e){let t="";if(le(e))t=e;else if(B(e))for(let n=0;n!!(e&&e.__v_isRef===!0),Vo=e=>le(e)?e:e==null?"":B(e)||se(e)&&(e.toString===Xr||!G(e.toString))?Jr(e)?Vo(e.value):JSON.stringify(e,Qr,2):String(e),Qr=(e,t)=>Jr(t)?Qr(e,t.value):Rt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],i)=>(n[Xn(s,i)+" =>"]=r,n),{})}:qr(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Xn(n))}:Je(t)?Xn(t):se(t)&&!B(t)&&!Yr(t)?String(t):t,Xn=(e,t="")=>{var n;return Je(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.5.17 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let ve;class Wo{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=ve,!t&&ve&&(this.index=(ve.scopes||(ve.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0&&--this._on===0&&(ve=this.prevScope,this.prevScope=void 0)}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(Vt){let t=Vt;for(Vt=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;jt;){let t=jt;for(jt=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function si(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function ri(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),$s(s),Uo(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function vs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(ii(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function ii(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Bt)||(e.globalVersion=Bt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!vs(e))))return;e.flags|=2;const t=e.dep,n=te,s=He;te=e,He=!0;try{si(e);const r=e.fn(e._value);(t.version===0||rt(r,e._value))&&(e.flags|=128,e._value=r,t.version++)}catch(r){throw t.version++,r}finally{te=n,He=s,ri(e),e.flags&=-3}}function $s(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)$s(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function Uo(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let He=!0;const oi=[];function Ge(){oi.push(He),He=!1}function Xe(){const e=oi.pop();He=e===void 0?!0:e}function nr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=te;te=void 0;try{t()}finally{te=n}}}let Bt=0;class Bo{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ln{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!te||!He||te===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==te)n=this.activeLink=new Bo(te,this),te.deps?(n.prevDep=te.depsTail,te.depsTail.nextDep=n,te.depsTail=n):te.deps=te.depsTail=n,li(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=te.depsTail,n.nextDep=void 0,te.depsTail.nextDep=n,te.depsTail=n,te.deps===n&&(te.deps=s)}return n}trigger(t){this.version++,Bt++,this.notify(t)}notify(t){Hs();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Ds()}}}function li(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)li(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const wn=new WeakMap,pt=Symbol(""),ys=Symbol(""),Kt=Symbol("");function _e(e,t,n){if(He&&te){let s=wn.get(e);s||wn.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new Ln),r.map=s,r.key=n),r.track()}}function qe(e,t,n,s,r,i){const o=wn.get(e);if(!o){Bt++;return}const l=c=>{c&&c.trigger()};if(Hs(),t==="clear")o.forEach(l);else{const c=B(e),u=c&&Ls(n);if(c&&n==="length"){const a=Number(s);o.forEach((h,v)=>{(v==="length"||v===Kt||!Je(v)&&v>=a)&&l(h)})}else switch((n!==void 0||o.has(void 0))&&l(o.get(n)),u&&l(o.get(Kt)),t){case"add":c?u&&l(o.get("length")):(l(o.get(pt)),Rt(e)&&l(o.get(ys)));break;case"delete":c||(l(o.get(pt)),Rt(e)&&l(o.get(ys)));break;case"set":Rt(e)&&l(o.get(pt));break}}Ds()}function Ko(e,t){const n=wn.get(e);return n&&n.get(t)}function Tt(e){const t=J(e);return t===e?t:(_e(t,"iterate",Kt),Ie(e)?t:t.map(de))}function Nn(e){return _e(e=J(e),"iterate",Kt),e}const qo={__proto__:null,[Symbol.iterator](){return zn(this,Symbol.iterator,de)},concat(...e){return Tt(this).concat(...e.map(t=>B(t)?Tt(t):t))},entries(){return zn(this,"entries",e=>(e[1]=de(e[1]),e))},every(e,t){return Ue(this,"every",e,t,void 0,arguments)},filter(e,t){return Ue(this,"filter",e,t,n=>n.map(de),arguments)},find(e,t){return Ue(this,"find",e,t,de,arguments)},findIndex(e,t){return Ue(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ue(this,"findLast",e,t,de,arguments)},findLastIndex(e,t){return Ue(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ue(this,"forEach",e,t,void 0,arguments)},includes(...e){return Jn(this,"includes",e)},indexOf(...e){return Jn(this,"indexOf",e)},join(e){return Tt(this).join(e)},lastIndexOf(...e){return Jn(this,"lastIndexOf",e)},map(e,t){return Ue(this,"map",e,t,void 0,arguments)},pop(){return Ht(this,"pop")},push(...e){return Ht(this,"push",e)},reduce(e,...t){return sr(this,"reduce",e,t)},reduceRight(e,...t){return sr(this,"reduceRight",e,t)},shift(){return Ht(this,"shift")},some(e,t){return Ue(this,"some",e,t,void 0,arguments)},splice(...e){return Ht(this,"splice",e)},toReversed(){return Tt(this).toReversed()},toSorted(e){return Tt(this).toSorted(e)},toSpliced(...e){return Tt(this).toSpliced(...e)},unshift(...e){return Ht(this,"unshift",e)},values(){return zn(this,"values",de)}};function zn(e,t,n){const s=Nn(e),r=s[t]();return s!==e&&!Ie(e)&&(r._next=r.next,r.next=()=>{const i=r._next();return i.value&&(i.value=n(i.value)),i}),r}const Go=Array.prototype;function Ue(e,t,n,s,r,i){const o=Nn(e),l=o!==e&&!Ie(e),c=o[t];if(c!==Go[t]){const h=c.apply(e,i);return l?de(h):h}let u=n;o!==e&&(l?u=function(h,v){return n.call(this,de(h),v,e)}:n.length>2&&(u=function(h,v){return n.call(this,h,v,e)}));const a=c.call(o,u,s);return l&&r?r(a):a}function sr(e,t,n,s){const r=Nn(e);let i=n;return r!==e&&(Ie(e)?n.length>3&&(i=function(o,l,c){return n.call(this,o,l,c,e)}):i=function(o,l,c){return n.call(this,o,de(l),c,e)}),r[t](i,...s)}function Jn(e,t,n){const s=J(e);_e(s,"iterate",Kt);const r=s[t](...n);return(r===-1||r===!1)&&Ws(n[0])?(n[0]=J(n[0]),s[t](...n)):r}function Ht(e,t,n=[]){Ge(),Hs();const s=J(e)[t].apply(e,n);return Ds(),Xe(),s}const Xo=Ms("__proto__,__v_isRef,__isVue"),ci=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Je));function Yo(e){Je(e)||(e=String(e));const t=J(this);return _e(t,"has",e),t.hasOwnProperty(e)}class ai{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return i;if(n==="__v_raw")return s===(r?i?il:hi:i?di:ui).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=B(t);if(!r){let c;if(o&&(c=qo[n]))return c;if(n==="hasOwnProperty")return Yo}const l=Reflect.get(t,n,ae(t)?t:s);return(Je(n)?ci.has(n):Xo(n))||(r||_e(t,"get",n),i)?l:ae(l)?o&&Ls(n)?l:l.value:se(l)?r?Fn(l):Pt(l):l}}class fi extends ai{constructor(t=!1){super(!1,t)}set(t,n,s,r){let i=t[n];if(!this._isShallow){const c=it(i);if(!Ie(s)&&!it(s)&&(i=J(i),s=J(s)),!B(t)&&ae(i)&&!ae(s))return c?!1:(i.value=s,!0)}const o=B(t)&&Ls(n)?Number(n)e,rn=e=>Reflect.getPrototypeOf(e);function el(e,t,n){return function(...s){const r=this.__v_raw,i=J(r),o=Rt(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,u=r[e](...s),a=n?_s:t?Sn:de;return!t&&_e(i,"iterate",c?ys:pt),{next(){const{value:h,done:v}=u.next();return v?{value:h,done:v}:{value:l?[a(h[0]),a(h[1])]:a(h),done:v}},[Symbol.iterator](){return this}}}}function on(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function tl(e,t){const n={get(r){const i=this.__v_raw,o=J(i),l=J(r);e||(rt(r,l)&&_e(o,"get",r),_e(o,"get",l));const{has:c}=rn(o),u=t?_s:e?Sn:de;if(c.call(o,r))return u(i.get(r));if(c.call(o,l))return u(i.get(l));i!==o&&i.get(r)},get size(){const r=this.__v_raw;return!e&&_e(J(r),"iterate",pt),Reflect.get(r,"size",r)},has(r){const i=this.__v_raw,o=J(i),l=J(r);return e||(rt(r,l)&&_e(o,"has",r),_e(o,"has",l)),r===l?i.has(r):i.has(r)||i.has(l)},forEach(r,i){const o=this,l=o.__v_raw,c=J(l),u=t?_s:e?Sn:de;return!e&&_e(c,"iterate",pt),l.forEach((a,h)=>r.call(i,u(a),u(h),o))}};return ue(n,e?{add:on("add"),set:on("set"),delete:on("delete"),clear:on("clear")}:{add(r){!t&&!Ie(r)&&!it(r)&&(r=J(r));const i=J(this);return rn(i).has.call(i,r)||(i.add(r),qe(i,"add",r,r)),this},set(r,i){!t&&!Ie(i)&&!it(i)&&(i=J(i));const o=J(this),{has:l,get:c}=rn(o);let u=l.call(o,r);u||(r=J(r),u=l.call(o,r));const a=c.call(o,r);return o.set(r,i),u?rt(i,a)&&qe(o,"set",r,i):qe(o,"add",r,i),this},delete(r){const i=J(this),{has:o,get:l}=rn(i);let c=o.call(i,r);c||(r=J(r),c=o.call(i,r)),l&&l.call(i,r);const u=i.delete(r);return c&&qe(i,"delete",r,void 0),u},clear(){const r=J(this),i=r.size!==0,o=r.clear();return i&&qe(r,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=el(r,e,t)}),n}function js(e,t){const n=tl(e,t);return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(Q(n,r)&&r in s?n:s,r,i)}const nl={get:js(!1,!1)},sl={get:js(!1,!0)},rl={get:js(!0,!1)};const ui=new WeakMap,di=new WeakMap,hi=new WeakMap,il=new WeakMap;function ol(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function ll(e){return e.__v_skip||!Object.isExtensible(e)?0:ol(Oo(e))}function Pt(e){return it(e)?e:Vs(e,!1,Jo,nl,ui)}function cl(e){return Vs(e,!1,Zo,sl,di)}function Fn(e){return Vs(e,!0,Qo,rl,hi)}function Vs(e,t,n,s,r){if(!se(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=ll(e);if(i===0)return e;const o=r.get(e);if(o)return o;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function gt(e){return it(e)?gt(e.__v_raw):!!(e&&e.__v_isReactive)}function it(e){return!!(e&&e.__v_isReadonly)}function Ie(e){return!!(e&&e.__v_isShallow)}function Ws(e){return e?!!e.__v_raw:!1}function J(e){const t=e&&e.__v_raw;return t?J(t):e}function vn(e){return!Q(e,"__v_skip")&&Object.isExtensible(e)&&ms(e,"__v_skip",!0),e}const de=e=>se(e)?Pt(e):e,Sn=e=>se(e)?Fn(e):e;function ae(e){return e?e.__v_isRef===!0:!1}function mt(e){return pi(e,!1)}function Pe(e){return pi(e,!0)}function pi(e,t){return ae(e)?e:new al(e,t)}class al{constructor(t,n){this.dep=new Ln,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:J(t),this._value=n?t:de(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||Ie(t)||it(t);t=s?t:J(t),rt(t,n)&&(this._rawValue=t,this._value=s?t:de(t),this.dep.trigger())}}function ks(e){return ae(e)?e.value:e}function ce(e){return G(e)?e():ks(e)}const fl={get:(e,t,n)=>t==="__v_raw"?e:ks(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return ae(r)&&!ae(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function gi(e){return gt(e)?e:new Proxy(e,fl)}class ul{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Ln,{get:s,set:r}=t(n.track.bind(n),n.trigger.bind(n));this._get=s,this._set=r}get value(){return this._value=this._get()}set value(t){this._set(t)}}function dl(e){return new ul(e)}class hl{constructor(t,n,s){this._object=t,this._key=n,this._defaultValue=s,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return Ko(J(this._object),this._key)}}class pl{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function gl(e,t,n){return ae(e)?e:G(e)?new pl(e):se(e)&&arguments.length>1?ml(e,t,n):mt(e)}function ml(e,t,n){const s=e[t];return ae(s)?s:new hl(e,t,n)}class vl{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Ln(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Bt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&te!==this)return ni(this,!0),!0}get value(){const t=this.dep.track();return ii(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function yl(e,t,n=!1){let s,r;return G(e)?s=e:(s=e.get,r=e.set),new vl(s,r,n)}const ln={},xn=new WeakMap;let dt;function _l(e,t=!1,n=dt){if(n){let s=xn.get(n);s||xn.set(n,s=[]),s.push(e)}}function bl(e,t,n=ne){const{immediate:s,deep:r,once:i,scheduler:o,augmentJob:l,call:c}=n,u=g=>r?g:Ie(g)||r===!1||r===0?st(g,1):st(g);let a,h,v,y,A=!1,P=!1;if(ae(e)?(h=()=>e.value,A=Ie(e)):gt(e)?(h=()=>u(e),A=!0):B(e)?(P=!0,A=e.some(g=>gt(g)||Ie(g)),h=()=>e.map(g=>{if(ae(g))return g.value;if(gt(g))return u(g);if(G(g))return c?c(g,2):g()})):G(e)?t?h=c?()=>c(e,2):e:h=()=>{if(v){Ge();try{v()}finally{Xe()}}const g=dt;dt=a;try{return c?c(e,3,[y]):e(y)}finally{dt=g}}:h=ke,t&&r){const g=h,M=r===!0?1/0:r;h=()=>st(g(),M)}const K=Zr(),H=()=>{a.stop(),K&&K.active&&Ps(K.effects,a)};if(i&&t){const g=t;t=(...M)=>{g(...M),H()}}let k=P?new Array(e.length).fill(ln):ln;const p=g=>{if(!(!(a.flags&1)||!a.dirty&&!g))if(t){const M=a.run();if(r||A||(P?M.some((W,R)=>rt(W,k[R])):rt(M,k))){v&&v();const W=dt;dt=a;try{const R=[M,k===ln?void 0:P&&k[0]===ln?[]:k,y];k=M,c?c(t,3,R):t(...R)}finally{dt=W}}}else a.run()};return l&&l(p),a=new ei(h),a.scheduler=o?()=>o(p,!1):p,y=g=>_l(g,!1,a),v=a.onStop=()=>{const g=xn.get(a);if(g){if(c)c(g,4);else for(const M of g)M();xn.delete(a)}},t?s?p(!0):k=a.run():o?o(p.bind(null,!0),!0):a.run(),H.pause=a.pause.bind(a),H.resume=a.resume.bind(a),H.stop=H,H}function st(e,t=1/0,n){if(t<=0||!se(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,ae(e))st(e.value,t,n);else if(B(e))for(let s=0;s{st(s,t,n)});else if(Yr(e)){for(const s in e)st(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&st(e[s],t,n)}return e}/** -* @vue/runtime-core v3.5.17 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Zt(e,t,n,s){try{return s?e(...s):e()}catch(r){Hn(r,t,n)}}function De(e,t,n,s){if(G(e)){const r=Zt(e,t,n,s);return r&&Gr(r)&&r.catch(i=>{Hn(i,t,n)}),r}if(B(e)){const r=[];for(let i=0;i>>1,r=we[s],i=qt(r);i=qt(n)?we.push(e):we.splice(Sl(t),0,e),e.flags|=1,vi()}}function vi(){Tn||(Tn=mi.then(yi))}function xl(e){B(e)?Mt.push(...e):et&&e.id===-1?et.splice(Ct+1,0,e):e.flags&1||(Mt.push(e),e.flags|=1),vi()}function rr(e,t,n=Ve+1){for(;nqt(n)-qt(s));if(Mt.length=0,et){et.push(...t);return}for(et=t,Ct=0;Cte.id==null?e.flags&2?-1:1/0:e.id;function yi(e){try{for(Ve=0;Ve{s._d&&mr(-1);const i=Cn(t);let o;try{o=e(...r)}finally{Cn(i),s._d&&mr(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function We(e,t,n,s){const r=e.dirs,i=t&&t.dirs;for(let o=0;oe.__isTeleport,tt=Symbol("_leaveCb"),cn=Symbol("_enterCb");function Cl(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Lt(()=>{e.isMounted=!0}),Oi(()=>{e.isUnmounting=!0}),e}const Re=[Function,Array],wi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Re,onEnter:Re,onAfterEnter:Re,onEnterCancelled:Re,onBeforeLeave:Re,onLeave:Re,onAfterLeave:Re,onLeaveCancelled:Re,onBeforeAppear:Re,onAppear:Re,onAfterAppear:Re,onAppearCancelled:Re},Si=e=>{const t=e.subTree;return t.component?Si(t.component):t},Al={name:"BaseTransition",props:wi,setup(e,{slots:t}){const n=en(),s=Cl();return()=>{const r=t.default&&Ei(t.default(),!0);if(!r||!r.length)return;const i=xi(r),o=J(e),{mode:l}=o;if(s.isLeaving)return Qn(i);const c=ir(i);if(!c)return Qn(i);let u=bs(c,o,s,n,h=>u=h);c.type!==he&&Gt(c,u);let a=n.subTree&&ir(n.subTree);if(a&&a.type!==he&&!ht(c,a)&&Si(n).type!==he){let h=bs(a,o,s,n);if(Gt(a,h),l==="out-in"&&c.type!==he)return s.isLeaving=!0,h.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete h.afterLeave,a=void 0},Qn(i);l==="in-out"&&c.type!==he?h.delayLeave=(v,y,A)=>{const P=Ti(s,a);P[String(a.key)]=a,v[tt]=()=>{y(),v[tt]=void 0,delete u.delayedLeave,a=void 0},u.delayedLeave=()=>{A(),delete u.delayedLeave,a=void 0}}:a=void 0}else a&&(a=void 0);return i}}};function xi(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==he){t=n;break}}return t}const Rl=Al;function Ti(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function bs(e,t,n,s,r){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:u,onAfterEnter:a,onEnterCancelled:h,onBeforeLeave:v,onLeave:y,onAfterLeave:A,onLeaveCancelled:P,onBeforeAppear:K,onAppear:H,onAfterAppear:k,onAppearCancelled:p}=t,g=String(e.key),M=Ti(n,e),W=(T,I)=>{T&&De(T,s,9,I)},R=(T,I)=>{const E=I[1];W(T,I),B(T)?T.every(_=>_.length<=1)&&E():T.length<=1&&E()},U={mode:o,persisted:l,beforeEnter(T){let I=c;if(!n.isMounted)if(i)I=K||c;else return;T[tt]&&T[tt](!0);const E=M[g];E&&ht(e,E)&&E.el[tt]&&E.el[tt](),W(I,[T])},enter(T){let I=u,E=a,_=h;if(!n.isMounted)if(i)I=H||u,E=k||a,_=p||h;else return;let N=!1;const Y=T[cn]=re=>{N||(N=!0,re?W(_,[T]):W(E,[T]),U.delayedLeave&&U.delayedLeave(),T[cn]=void 0)};I?R(I,[T,Y]):Y()},leave(T,I){const E=String(e.key);if(T[cn]&&T[cn](!0),n.isUnmounting)return I();W(v,[T]);let _=!1;const N=T[tt]=Y=>{_||(_=!0,I(),Y?W(P,[T]):W(A,[T]),T[tt]=void 0,M[E]===e&&delete M[E])};M[E]=e,y?R(y,[T,N]):N()},clone(T){const I=bs(T,t,n,s,r);return r&&r(I),I}};return U}function Qn(e){if($n(e))return e=ot(e),e.children=null,e}function ir(e){if(!$n(e))return bi(e.type)&&e.children?xi(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&G(n.default))return n.default()}}function Gt(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Gt(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Ei(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;iIt(A,t&&(B(t)?t[P]:t),n,s,r));return}if(vt(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&It(e,t,n,s.component.subTree);return}const i=s.shapeFlag&4?Gs(s.component):s.el,o=r?null:i,{i:l,r:c}=e,u=t&&t.r,a=l.refs===ne?l.refs={}:l.refs,h=l.setupState,v=J(h),y=h===ne?()=>!1:A=>Q(v,A);if(u!=null&&u!==c&&(le(u)?(a[u]=null,y(u)&&(h[u]=null)):ae(u)&&(u.value=null)),G(c))Zt(c,l,12,[o,a]);else{const A=le(c),P=ae(c);if(A||P){const K=()=>{if(e.f){const H=A?y(c)?h[c]:a[c]:c.value;r?B(H)&&Ps(H,i):B(H)?H.includes(i)||H.push(i):A?(a[c]=[i],y(c)&&(h[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else A?(a[c]=o,y(c)&&(h[c]=o)):P&&(c.value=o,e.k&&(a[e.k]=o))};o?(K.id=-1,Ce(K,n)):K()}}}let or=!1;const Et=()=>{or||(console.error("Hydration completed but contains mismatches."),or=!0)},Ol=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Ml=e=>e.namespaceURI.includes("MathML"),an=e=>{if(e.nodeType===1){if(Ol(e))return"svg";if(Ml(e))return"mathml"}},fn=e=>e.nodeType===8;function Il(e){const{mt:t,p:n,o:{patchProp:s,createText:r,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:u}}=e,a=(p,g)=>{if(!g.hasChildNodes()){n(null,p,g),En(),g._vnode=p;return}h(g.firstChild,p,null,null,null),En(),g._vnode=p},h=(p,g,M,W,R,U=!1)=>{U=U||!!g.dynamicChildren;const T=fn(p)&&p.data==="[",I=()=>P(p,g,M,W,R,T),{type:E,ref:_,shapeFlag:N,patchFlag:Y}=g;let re=p.nodeType;g.el=p,Y===-2&&(U=!1,g.dynamicChildren=null);let j=null;switch(E){case bt:re!==3?g.children===""?(c(g.el=r(""),o(p),p),j=p):j=I():(p.data!==g.children&&(Et(),p.data=g.children),j=i(p));break;case he:k(p)?(j=i(p),H(g.el=p.content.firstChild,p,M)):re!==8||T?j=I():j=i(p);break;case kt:if(T&&(p=i(p),re=p.nodeType),re===1||re===3){j=p;const X=!g.children.length;for(let D=0;D{U=U||!!g.dynamicChildren;const{type:T,props:I,patchFlag:E,shapeFlag:_,dirs:N,transition:Y}=g,re=T==="input"||T==="option";if(re||E!==-1){N&&We(g,null,M,"created");let j=!1;if(k(p)){j=qi(null,Y)&&M&&M.vnode.props&&M.vnode.props.appear;const D=p.content.firstChild;if(j){const oe=D.getAttribute("class");oe&&(D.$cls=oe),Y.beforeEnter(D)}H(D,p,M),g.el=p=D}if(_&16&&!(I&&(I.innerHTML||I.textContent))){let D=y(p.firstChild,g,p,M,W,R,U);for(;D;){un(p,1)||Et();const oe=D;D=D.nextSibling,l(oe)}}else if(_&8){let D=g.children;D[0]===` -`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&(D=D.slice(1)),p.textContent!==D&&(un(p,0)||Et(),p.textContent=g.children)}if(I){if(re||!U||E&48){const D=p.tagName.includes("-");for(const oe in I)(re&&(oe.endsWith("value")||oe==="indeterminate")||Qt(oe)&&!Ot(oe)||oe[0]==="."||D)&&s(p,oe,null,I[oe],void 0,M)}else if(I.onClick)s(p,"onClick",null,I.onClick,void 0,M);else if(E&4&>(I.style))for(const D in I.style)I.style[D]}let X;(X=I&&I.onVnodeBeforeMount)&&Oe(X,M,g),N&&We(g,null,M,"beforeMount"),((X=I&&I.onVnodeMounted)||N||j)&&eo(()=>{X&&Oe(X,M,g),j&&Y.enter(p),N&&We(g,null,M,"mounted")},W)}return p.nextSibling},y=(p,g,M,W,R,U,T)=>{T=T||!!g.dynamicChildren;const I=g.children,E=I.length;for(let _=0;_{const{slotScopeIds:T}=g;T&&(R=R?R.concat(T):T);const I=o(p),E=y(i(p),g,I,M,W,R,U);return E&&fn(E)&&E.data==="]"?i(g.anchor=E):(Et(),c(g.anchor=u("]"),I,E),E)},P=(p,g,M,W,R,U)=>{if(un(p.parentElement,1)||Et(),g.el=null,U){const E=K(p);for(;;){const _=i(p);if(_&&_!==E)l(_);else break}}const T=i(p),I=o(p);return l(p),n(null,g,I,T,M,W,an(I),R),M&&(M.vnode.el=g.el,Qi(M,g.el)),T},K=(p,g="[",M="]")=>{let W=0;for(;p;)if(p=i(p),p&&fn(p)&&(p.data===g&&W++,p.data===M)){if(W===0)return i(p);W--}return p},H=(p,g,M)=>{const W=g.parentNode;W&&W.replaceChild(p,g);let R=M;for(;R;)R.vnode.el===g&&(R.vnode.el=R.subTree.el=p),R=R.parent},k=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,h]}const lr="data-allow-mismatch",Pl={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function un(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(lr);)e=e.parentElement;const n=e&&e.getAttribute(lr);if(n==null)return!1;if(n==="")return!0;{const s=n.split(",");return t===0&&s.includes("children")?!0:s.includes(Pl[t])}}Pn().requestIdleCallback;Pn().cancelIdleCallback;const vt=e=>!!e.type.__asyncLoader,$n=e=>e.type.__isKeepAlive;function Ll(e,t){Ri(e,"a",t)}function Nl(e,t){Ri(e,"da",t)}function Ri(e,t,n=fe){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(jn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)$n(r.parent.vnode)&&Fl(s,t,n,r),r=r.parent}}function Fl(e,t,n,s){const r=jn(t,e,s,!0);Vn(()=>{Ps(s[t],r)},n)}function jn(e,t,n=fe,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{Ge();const l=tn(n),c=De(t,n,e,o);return l(),Xe(),c});return s?r.unshift(i):r.push(i),i}}const Qe=e=>(t,n=fe)=>{(!zt||e==="sp")&&jn(e,(...s)=>t(...s),n)},Hl=Qe("bm"),Lt=Qe("m"),Dl=Qe("bu"),$l=Qe("u"),Oi=Qe("bum"),Vn=Qe("um"),jl=Qe("sp"),Vl=Qe("rtg"),Wl=Qe("rtc");function kl(e,t=fe){jn("ec",e,t)}const Mi="components";function ff(e,t){return Pi(Mi,e,!0,t)||e}const Ii=Symbol.for("v-ndc");function uf(e){return le(e)?Pi(Mi,e,!1)||e:e||Ii}function Pi(e,t,n=!0,s=!1){const r=pe||fe;if(r){const i=r.type;{const l=Cc(i,!1);if(l&&(l===t||l===Ne(t)||l===In(Ne(t))))return i}const o=cr(r[e]||i[e],t)||cr(r.appContext[e],t);return!o&&s?i:o}}function cr(e,t){return e&&(e[t]||e[Ne(t)]||e[In(Ne(t))])}function df(e,t,n,s){let r;const i=n,o=B(e);if(o||le(e)){const l=o&>(e);let c=!1,u=!1;l&&(c=!Ie(e),u=it(e),e=Nn(e)),r=new Array(e.length);for(let a=0,h=e.length;at(l,c,void 0,i));else{const l=Object.keys(e);r=new Array(l.length);for(let c=0,u=l.length;cYt(t)?!(t.type===he||t.type===Se&&!Li(t.children)):!0)?e:null}function pf(e,t){const n={};for(const s in e)n[/[A-Z]/.test(s)?`on:${s}`:mn(s)]=e[s];return n}const ws=e=>e?io(e)?Gs(e):ws(e.parent):null,Wt=ue(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ws(e.parent),$root:e=>ws(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Fi(e),$forceUpdate:e=>e.f||(e.f=()=>{Us(e.update)}),$nextTick:e=>e.n||(e.n=Dn.bind(e.proxy)),$watch:e=>fc.bind(e)}),Zn=(e,t)=>e!==ne&&!e.__isScriptSetup&&Q(e,t),Ul={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:c}=e;let u;if(t[0]!=="$"){const y=o[t];if(y!==void 0)switch(y){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(Zn(s,t))return o[t]=1,s[t];if(r!==ne&&Q(r,t))return o[t]=2,r[t];if((u=e.propsOptions[0])&&Q(u,t))return o[t]=3,i[t];if(n!==ne&&Q(n,t))return o[t]=4,n[t];Ss&&(o[t]=0)}}const a=Wt[t];let h,v;if(a)return t==="$attrs"&&_e(e.attrs,"get",""),a(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==ne&&Q(n,t))return o[t]=4,n[t];if(v=c.config.globalProperties,Q(v,t))return v[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return Zn(r,t)?(r[t]=n,!0):s!==ne&&Q(s,t)?(s[t]=n,!0):Q(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==ne&&Q(e,o)||Zn(t,o)||(l=i[0])&&Q(l,o)||Q(s,o)||Q(Wt,o)||Q(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Q(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function gf(){return Bl().slots}function Bl(){const e=en();return e.setupContext||(e.setupContext=lo(e))}function ar(e){return B(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ss=!0;function Kl(e){const t=Fi(e),n=e.proxy,s=e.ctx;Ss=!1,t.beforeCreate&&fr(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:c,inject:u,created:a,beforeMount:h,mounted:v,beforeUpdate:y,updated:A,activated:P,deactivated:K,beforeDestroy:H,beforeUnmount:k,destroyed:p,unmounted:g,render:M,renderTracked:W,renderTriggered:R,errorCaptured:U,serverPrefetch:T,expose:I,inheritAttrs:E,components:_,directives:N,filters:Y}=t;if(u&&ql(u,s,null),o)for(const X in o){const D=o[X];G(D)&&(s[X]=D.bind(n))}if(r){const X=r.call(n,n);se(X)&&(e.data=Pt(X))}if(Ss=!0,i)for(const X in i){const D=i[X],oe=G(D)?D.bind(n,n):G(D.get)?D.get.bind(n,n):ke,nn=!G(D)&&G(D.set)?D.set.bind(n):ke,ct=ie({get:oe,set:nn});Object.defineProperty(s,X,{enumerable:!0,configurable:!0,get:()=>ct.value,set:$e=>ct.value=$e})}if(l)for(const X in l)Ni(l[X],s,n,X);if(c){const X=G(c)?c.call(n):c;Reflect.ownKeys(X).forEach(D=>{Ql(D,X[D])})}a&&fr(a,e,"c");function j(X,D){B(D)?D.forEach(oe=>X(oe.bind(n))):D&&X(D.bind(n))}if(j(Hl,h),j(Lt,v),j(Dl,y),j($l,A),j(Ll,P),j(Nl,K),j(kl,U),j(Wl,W),j(Vl,R),j(Oi,k),j(Vn,g),j(jl,T),B(I))if(I.length){const X=e.exposed||(e.exposed={});I.forEach(D=>{Object.defineProperty(X,D,{get:()=>n[D],set:oe=>n[D]=oe})})}else e.exposed||(e.exposed={});M&&e.render===ke&&(e.render=M),E!=null&&(e.inheritAttrs=E),_&&(e.components=_),N&&(e.directives=N),T&&Ai(e)}function ql(e,t,n=ke){B(e)&&(e=xs(e));for(const s in e){const r=e[s];let i;se(r)?"default"in r?i=_t(r.from||s,r.default,!0):i=_t(r.from||s):i=_t(r),ae(i)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[s]=i}}function fr(e,t,n){De(B(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ni(e,t,n,s){let r=s.includes(".")?zi(n,s):()=>n[s];if(le(e)){const i=t[e];G(i)&&Le(r,i)}else if(G(e))Le(r,e.bind(n));else if(se(e))if(B(e))e.forEach(i=>Ni(i,t,n,s));else{const i=G(e.handler)?e.handler.bind(n):t[e.handler];G(i)&&Le(r,i,e)}}function Fi(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(u=>An(c,u,o,!0)),An(c,t,o)),se(t)&&i.set(t,c),c}function An(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&An(e,i,n,!0),r&&r.forEach(o=>An(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=Gl[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const Gl={data:ur,props:dr,emits:dr,methods:$t,computed:$t,beforeCreate:be,created:be,beforeMount:be,mounted:be,beforeUpdate:be,updated:be,beforeDestroy:be,beforeUnmount:be,destroyed:be,unmounted:be,activated:be,deactivated:be,errorCaptured:be,serverPrefetch:be,components:$t,directives:$t,watch:Yl,provide:ur,inject:Xl};function ur(e,t){return t?e?function(){return ue(G(e)?e.call(this,this):e,G(t)?t.call(this,this):t)}:t:e}function Xl(e,t){return $t(xs(e),xs(t))}function xs(e){if(B(e)){const t={};for(let n=0;n1)return n&&G(t)?t.call(s&&s.proxy):t}}function Di(){return!!(fe||pe||yt)}const $i={},ji=()=>Object.create($i),Vi=e=>Object.getPrototypeOf(e)===$i;function Zl(e,t,n,s=!1){const r={},i=ji();e.propsDefaults=Object.create(null),Wi(e,t,r,i);for(const o in e.propsOptions[0])o in r||(r[o]=void 0);n?e.props=s?r:cl(r):e.type.props?e.props=r:e.props=i,e.attrs=i}function ec(e,t,n,s){const{props:r,attrs:i,vnode:{patchFlag:o}}=e,l=J(r),[c]=e.propsOptions;let u=!1;if((s||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[v,y]=ki(h,t,!0);ue(o,v),y&&l.push(...y)};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!i&&!c)return se(e)&&s.set(e,At),At;if(B(i))for(let a=0;ae[0]==="_"||e==="$stable",Ks=e=>B(e)?e.map(Me):[Me(e)],nc=(e,t,n)=>{if(t._n)return t;const s=Tl((...r)=>Ks(t(...r)),n);return s._c=!1,s},Ui=(e,t,n)=>{const s=e._ctx;for(const r in e){if(Bs(r))continue;const i=e[r];if(G(i))t[r]=nc(r,i,s);else if(i!=null){const o=Ks(i);t[r]=()=>o}}},Bi=(e,t)=>{const n=Ks(t);e.slots.default=()=>n},Ki=(e,t,n)=>{for(const s in t)(n||!Bs(s))&&(e[s]=t[s])},sc=(e,t,n)=>{const s=e.slots=ji();if(e.vnode.shapeFlag&32){const r=t.__;r&&ms(s,"__",r,!0);const i=t._;i?(Ki(s,t,n),n&&ms(s,"_",i,!0)):Ui(t,s)}else t&&Bi(e,t)},rc=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=ne;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:Ki(r,t,n):(i=!t.$stable,Ui(t,r)),o=t}else t&&(Bi(e,t),o={default:1});if(i)for(const l in r)!Bs(l)&&o[l]==null&&delete r[l]},Ce=eo;function ic(e){return oc(e,Il)}function oc(e,t){const n=Pn();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:c,setText:u,setElementText:a,parentNode:h,nextSibling:v,setScopeId:y=ke,insertStaticContent:A}=e,P=(f,d,m,S=null,b=null,w=null,L=void 0,O=null,C=!!d.dynamicChildren)=>{if(f===d)return;f&&!ht(f,d)&&(S=sn(f),$e(f,b,w,!0),f=null),d.patchFlag===-2&&(C=!1,d.dynamicChildren=null);const{type:x,ref:V,shapeFlag:F}=d;switch(x){case bt:K(f,d,m,S);break;case he:H(f,d,m,S);break;case kt:f==null&&k(d,m,S,L);break;case Se:_(f,d,m,S,b,w,L,O,C);break;default:F&1?M(f,d,m,S,b,w,L,O,C):F&6?N(f,d,m,S,b,w,L,O,C):(F&64||F&128)&&x.process(f,d,m,S,b,w,L,O,C,xt)}V!=null&&b?It(V,f&&f.ref,w,d||f,!d):V==null&&f&&f.ref!=null&&It(f.ref,null,w,f,!0)},K=(f,d,m,S)=>{if(f==null)s(d.el=l(d.children),m,S);else{const b=d.el=f.el;d.children!==f.children&&u(b,d.children)}},H=(f,d,m,S)=>{f==null?s(d.el=c(d.children||""),m,S):d.el=f.el},k=(f,d,m,S)=>{[f.el,f.anchor]=A(f.children,d,m,S,f.el,f.anchor)},p=({el:f,anchor:d},m,S)=>{let b;for(;f&&f!==d;)b=v(f),s(f,m,S),f=b;s(d,m,S)},g=({el:f,anchor:d})=>{let m;for(;f&&f!==d;)m=v(f),r(f),f=m;r(d)},M=(f,d,m,S,b,w,L,O,C)=>{d.type==="svg"?L="svg":d.type==="math"&&(L="mathml"),f==null?W(d,m,S,b,w,L,O,C):T(f,d,b,w,L,O,C)},W=(f,d,m,S,b,w,L,O)=>{let C,x;const{props:V,shapeFlag:F,transition:$,dirs:q}=f;if(C=f.el=o(f.type,w,V&&V.is,V),F&8?a(C,f.children):F&16&&U(f.children,C,null,S,b,es(f,w),L,O),q&&We(f,null,S,"created"),R(C,f,f.scopeId,L,S),V){for(const ee in V)ee!=="value"&&!Ot(ee)&&i(C,ee,null,V[ee],w,S);"value"in V&&i(C,"value",null,V.value,w),(x=V.onVnodeBeforeMount)&&Oe(x,S,f)}q&&We(f,null,S,"beforeMount");const z=qi(b,$);z&&$.beforeEnter(C),s(C,d,m),((x=V&&V.onVnodeMounted)||z||q)&&Ce(()=>{x&&Oe(x,S,f),z&&$.enter(C),q&&We(f,null,S,"mounted")},b)},R=(f,d,m,S,b)=>{if(m&&y(f,m),S)for(let w=0;w{for(let x=C;x{const O=d.el=f.el;let{patchFlag:C,dynamicChildren:x,dirs:V}=d;C|=f.patchFlag&16;const F=f.props||ne,$=d.props||ne;let q;if(m&&at(m,!1),(q=$.onVnodeBeforeUpdate)&&Oe(q,m,d,f),V&&We(d,f,m,"beforeUpdate"),m&&at(m,!0),(F.innerHTML&&$.innerHTML==null||F.textContent&&$.textContent==null)&&a(O,""),x?I(f.dynamicChildren,x,O,m,S,es(d,b),w):L||D(f,d,O,null,m,S,es(d,b),w,!1),C>0){if(C&16)E(O,F,$,m,b);else if(C&2&&F.class!==$.class&&i(O,"class",null,$.class,b),C&4&&i(O,"style",F.style,$.style,b),C&8){const z=d.dynamicProps;for(let ee=0;ee{q&&Oe(q,m,d,f),V&&We(d,f,m,"updated")},S)},I=(f,d,m,S,b,w,L)=>{for(let O=0;O{if(d!==m){if(d!==ne)for(const w in d)!Ot(w)&&!(w in m)&&i(f,w,d[w],null,b,S);for(const w in m){if(Ot(w))continue;const L=m[w],O=d[w];L!==O&&w!=="value"&&i(f,w,O,L,b,S)}"value"in m&&i(f,"value",d.value,m.value,b)}},_=(f,d,m,S,b,w,L,O,C)=>{const x=d.el=f?f.el:l(""),V=d.anchor=f?f.anchor:l("");let{patchFlag:F,dynamicChildren:$,slotScopeIds:q}=d;q&&(O=O?O.concat(q):q),f==null?(s(x,m,S),s(V,m,S),U(d.children||[],m,V,b,w,L,O,C)):F>0&&F&64&&$&&f.dynamicChildren?(I(f.dynamicChildren,$,m,b,w,L,O),(d.key!=null||b&&d===b.subTree)&&Gi(f,d,!0)):D(f,d,m,V,b,w,L,O,C)},N=(f,d,m,S,b,w,L,O,C)=>{d.slotScopeIds=O,f==null?d.shapeFlag&512?b.ctx.activate(d,m,S,L,C):Y(d,m,S,b,w,L,C):re(f,d,C)},Y=(f,d,m,S,b,w,L)=>{const O=f.component=Sc(f,S,b);if($n(f)&&(O.ctx.renderer=xt),xc(O,!1,L),O.asyncDep){if(b&&b.registerDep(O,j,L),!f.el){const C=O.subTree=ge(he);H(null,C,d,m)}}else j(O,f,d,m,b,w,L)},re=(f,d,m)=>{const S=d.component=f.component;if(gc(f,d,m))if(S.asyncDep&&!S.asyncResolved){X(S,d,m);return}else S.next=d,S.update();else d.el=f.el,S.vnode=d},j=(f,d,m,S,b,w,L)=>{const O=()=>{if(f.isMounted){let{next:F,bu:$,u:q,parent:z,vnode:ee}=f;{const Te=Xi(f);if(Te){F&&(F.el=ee.el,X(f,F,L)),Te.asyncDep.then(()=>{f.isUnmounted||O()});return}}let Z=F,xe;at(f,!1),F?(F.el=ee.el,X(f,F,L)):F=ee,$&&Gn($),(xe=F.props&&F.props.onVnodeBeforeUpdate)&&Oe(xe,z,F,ee),at(f,!0);const me=ts(f),Fe=f.subTree;f.subTree=me,P(Fe,me,h(Fe.el),sn(Fe),f,b,w),F.el=me.el,Z===null&&Qi(f,me.el),q&&Ce(q,b),(xe=F.props&&F.props.onVnodeUpdated)&&Ce(()=>Oe(xe,z,F,ee),b)}else{let F;const{el:$,props:q}=d,{bm:z,m:ee,parent:Z,root:xe,type:me}=f,Fe=vt(d);if(at(f,!1),z&&Gn(z),!Fe&&(F=q&&q.onVnodeBeforeMount)&&Oe(F,Z,d),at(f,!0),$&&qn){const Te=()=>{f.subTree=ts(f),qn($,f.subTree,f,b,null)};Fe&&me.__asyncHydrate?me.__asyncHydrate($,f,Te):Te()}else{xe.ce&&xe.ce._def.shadowRoot!==!1&&xe.ce._injectChildStyle(me);const Te=f.subTree=ts(f);P(null,Te,m,S,f,b,w),d.el=Te.el}if(ee&&Ce(ee,b),!Fe&&(F=q&&q.onVnodeMounted)){const Te=d;Ce(()=>Oe(F,Z,Te),b)}(d.shapeFlag&256||Z&&vt(Z.vnode)&&Z.vnode.shapeFlag&256)&&f.a&&Ce(f.a,b),f.isMounted=!0,d=m=S=null}};f.scope.on();const C=f.effect=new ei(O);f.scope.off();const x=f.update=C.run.bind(C),V=f.job=C.runIfDirty.bind(C);V.i=f,V.id=f.uid,C.scheduler=()=>Us(V),at(f,!0),x()},X=(f,d,m)=>{d.component=f;const S=f.vnode.props;f.vnode=d,f.next=null,ec(f,d.props,S,m),rc(f,d.children,m),Ge(),rr(f),Xe()},D=(f,d,m,S,b,w,L,O,C=!1)=>{const x=f&&f.children,V=f?f.shapeFlag:0,F=d.children,{patchFlag:$,shapeFlag:q}=d;if($>0){if($&128){nn(x,F,m,S,b,w,L,O,C);return}else if($&256){oe(x,F,m,S,b,w,L,O,C);return}}q&8?(V&16&&Nt(x,b,w),F!==x&&a(m,F)):V&16?q&16?nn(x,F,m,S,b,w,L,O,C):Nt(x,b,w,!0):(V&8&&a(m,""),q&16&&U(F,m,S,b,w,L,O,C))},oe=(f,d,m,S,b,w,L,O,C)=>{f=f||At,d=d||At;const x=f.length,V=d.length,F=Math.min(x,V);let $;for($=0;$V?Nt(f,b,w,!0,!1,F):U(d,m,S,b,w,L,O,C,F)},nn=(f,d,m,S,b,w,L,O,C)=>{let x=0;const V=d.length;let F=f.length-1,$=V-1;for(;x<=F&&x<=$;){const q=f[x],z=d[x]=C?nt(d[x]):Me(d[x]);if(ht(q,z))P(q,z,m,null,b,w,L,O,C);else break;x++}for(;x<=F&&x<=$;){const q=f[F],z=d[$]=C?nt(d[$]):Me(d[$]);if(ht(q,z))P(q,z,m,null,b,w,L,O,C);else break;F--,$--}if(x>F){if(x<=$){const q=$+1,z=q$)for(;x<=F;)$e(f[x],b,w,!0),x++;else{const q=x,z=x,ee=new Map;for(x=z;x<=$;x++){const Ee=d[x]=C?nt(d[x]):Me(d[x]);Ee.key!=null&&ee.set(Ee.key,x)}let Z,xe=0;const me=$-z+1;let Fe=!1,Te=0;const Ft=new Array(me);for(x=0;x=me){$e(Ee,b,w,!0);continue}let je;if(Ee.key!=null)je=ee.get(Ee.key);else for(Z=z;Z<=$;Z++)if(Ft[Z-z]===0&&ht(Ee,d[Z])){je=Z;break}je===void 0?$e(Ee,b,w,!0):(Ft[je-z]=x+1,je>=Te?Te=je:Fe=!0,P(Ee,d[je],m,null,b,w,L,O,C),xe++)}const Zs=Fe?lc(Ft):At;for(Z=Zs.length-1,x=me-1;x>=0;x--){const Ee=z+x,je=d[Ee],er=Ee+1{const{el:w,type:L,transition:O,children:C,shapeFlag:x}=f;if(x&6){ct(f.component.subTree,d,m,S);return}if(x&128){f.suspense.move(d,m,S);return}if(x&64){L.move(f,d,m,xt);return}if(L===Se){s(w,d,m);for(let F=0;FO.enter(w),b);else{const{leave:F,delayLeave:$,afterLeave:q}=O,z=()=>{f.ctx.isUnmounted?r(w):s(w,d,m)},ee=()=>{F(w,()=>{z(),q&&q()})};$?$(w,z,ee):ee()}else s(w,d,m)},$e=(f,d,m,S=!1,b=!1)=>{const{type:w,props:L,ref:O,children:C,dynamicChildren:x,shapeFlag:V,patchFlag:F,dirs:$,cacheIndex:q}=f;if(F===-2&&(b=!1),O!=null&&(Ge(),It(O,null,m,f,!0),Xe()),q!=null&&(d.renderCache[q]=void 0),V&256){d.ctx.deactivate(f);return}const z=V&1&&$,ee=!vt(f);let Z;if(ee&&(Z=L&&L.onVnodeBeforeUnmount)&&Oe(Z,d,f),V&6)Co(f.component,m,S);else{if(V&128){f.suspense.unmount(m,S);return}z&&We(f,null,d,"beforeUnmount"),V&64?f.type.remove(f,d,m,xt,S):x&&!x.hasOnce&&(w!==Se||F>0&&F&64)?Nt(x,d,m,!1,!0):(w===Se&&F&384||!b&&V&16)&&Nt(C,d,m),S&&Js(f)}(ee&&(Z=L&&L.onVnodeUnmounted)||z)&&Ce(()=>{Z&&Oe(Z,d,f),z&&We(f,null,d,"unmounted")},m)},Js=f=>{const{type:d,el:m,anchor:S,transition:b}=f;if(d===Se){Eo(m,S);return}if(d===kt){g(f);return}const w=()=>{r(m),b&&!b.persisted&&b.afterLeave&&b.afterLeave()};if(f.shapeFlag&1&&b&&!b.persisted){const{leave:L,delayLeave:O}=b,C=()=>L(m,w);O?O(f.el,w,C):C()}else w()},Eo=(f,d)=>{let m;for(;f!==d;)m=v(f),r(f),f=m;r(d)},Co=(f,d,m)=>{const{bum:S,scope:b,job:w,subTree:L,um:O,m:C,a:x,parent:V,slots:{__:F}}=f;pr(C),pr(x),S&&Gn(S),V&&B(F)&&F.forEach($=>{V.renderCache[$]=void 0}),b.stop(),w&&(w.flags|=8,$e(L,f,d,m)),O&&Ce(O,d),Ce(()=>{f.isUnmounted=!0},d),d&&d.pendingBranch&&!d.isUnmounted&&f.asyncDep&&!f.asyncResolved&&f.suspenseId===d.pendingId&&(d.deps--,d.deps===0&&d.resolve())},Nt=(f,d,m,S=!1,b=!1,w=0)=>{for(let L=w;L{if(f.shapeFlag&6)return sn(f.component.subTree);if(f.shapeFlag&128)return f.suspense.next();const d=v(f.anchor||f.el),m=d&&d[El];return m?v(m):d};let Bn=!1;const Qs=(f,d,m)=>{f==null?d._vnode&&$e(d._vnode,null,null,!0):P(d._vnode||null,f,d,null,null,null,m),d._vnode=f,Bn||(Bn=!0,rr(),En(),Bn=!1)},xt={p:P,um:$e,m:ct,r:Js,mt:Y,mc:U,pc:D,pbc:I,n:sn,o:e};let Kn,qn;return t&&([Kn,qn]=t(xt)),{render:Qs,hydrate:Kn,createApp:Jl(Qs,Kn)}}function es({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function at({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function qi(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Gi(e,t,n=!1){const s=e.children,r=t.children;if(B(s)&&B(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function Xi(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Xi(t)}function pr(e){if(e)for(let t=0;t_t(cc);function Yi(e,t){return Wn(e,null,t)}function mf(e,t){return Wn(e,null,{flush:"post"})}function Le(e,t,n){return Wn(e,t,n)}function Wn(e,t,n=ne){const{immediate:s,deep:r,flush:i,once:o}=n,l=ue({},n),c=t&&s||!t&&i!=="post";let u;if(zt){if(i==="sync"){const y=ac();u=y.__watcherHandles||(y.__watcherHandles=[])}else if(!c){const y=()=>{};return y.stop=ke,y.resume=ke,y.pause=ke,y}}const a=fe;l.call=(y,A,P)=>De(y,a,A,P);let h=!1;i==="post"?l.scheduler=y=>{Ce(y,a&&a.suspense)}:i!=="sync"&&(h=!0,l.scheduler=(y,A)=>{A?y():Us(y)}),l.augmentJob=y=>{t&&(y.flags|=4),h&&(y.flags|=2,a&&(y.id=a.uid,y.i=a))};const v=bl(e,t,l);return zt&&(u?u.push(v):c&&v()),v}function fc(e,t,n){const s=this.proxy,r=le(e)?e.includes(".")?zi(s,e):()=>s[e]:e.bind(s,s);let i;G(t)?i=t:(i=t.handler,n=t);const o=tn(this),l=Wn(r,i.bind(s),n);return o(),l}function zi(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;rt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ne(t)}Modifiers`]||e[`${lt(t)}Modifiers`];function dc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||ne;let r=n;const i=t.startsWith("update:"),o=i&&uc(s,t.slice(7));o&&(o.trim&&(r=n.map(a=>le(a)?a.trim():a)),o.number&&(r=n.map(Po)));let l,c=s[l=mn(t)]||s[l=mn(Ne(t))];!c&&i&&(c=s[l=mn(lt(t))]),c&&De(c,e,6,r);const u=s[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,De(u,e,6,r)}}function Ji(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!G(e)){const c=u=>{const a=Ji(u,t,!0);a&&(l=!0,ue(o,a))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(se(e)&&s.set(e,null),null):(B(i)?i.forEach(c=>o[c]=null):ue(o,i),se(e)&&s.set(e,o),o)}function kn(e,t){return!e||!Qt(t)?!1:(t=t.slice(2).replace(/Once$/,""),Q(e,t[0].toLowerCase()+t.slice(1))||Q(e,lt(t))||Q(e,t))}function ts(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[i],slots:o,attrs:l,emit:c,render:u,renderCache:a,props:h,data:v,setupState:y,ctx:A,inheritAttrs:P}=e,K=Cn(e);let H,k;try{if(n.shapeFlag&4){const g=r||s,M=g;H=Me(u.call(M,g,a,h,y,v,A)),k=l}else{const g=t;H=Me(g.length>1?g(h,{attrs:l,slots:o,emit:c}):g(h,null)),k=t.props?l:hc(l)}}catch(g){Ut.length=0,Hn(g,e,1),H=ge(he)}let p=H;if(k&&P!==!1){const g=Object.keys(k),{shapeFlag:M}=p;g.length&&M&7&&(i&&g.some(Is)&&(k=pc(k,i)),p=ot(p,k,!1,!0))}return n.dirs&&(p=ot(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(n.dirs):n.dirs),n.transition&&Gt(p,n.transition),H=p,Cn(K),H}const hc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Qt(n))&&((t||(t={}))[n]=e[n]);return t},pc=(e,t)=>{const n={};for(const s in e)(!Is(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function gc(e,t,n){const{props:s,children:r,component:i}=e,{props:o,children:l,patchFlag:c}=t,u=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?gr(s,o,u):!!o;if(c&8){const a=t.dynamicProps;for(let h=0;he.__isSuspense;function eo(e,t){t&&t.pendingBranch?B(e)?t.effects.push(...e):t.effects.push(e):xl(e)}const Se=Symbol.for("v-fgt"),bt=Symbol.for("v-txt"),he=Symbol.for("v-cmt"),kt=Symbol.for("v-stc"),Ut=[];let Ae=null;function Es(e=!1){Ut.push(Ae=e?null:[])}function mc(){Ut.pop(),Ae=Ut[Ut.length-1]||null}let Xt=1;function mr(e,t=!1){Xt+=e,e<0&&Ae&&t&&(Ae.hasOnce=!0)}function to(e){return e.dynamicChildren=Xt>0?Ae||At:null,mc(),Xt>0&&Ae&&Ae.push(e),e}function vf(e,t,n,s,r,i){return to(so(e,t,n,s,r,i,!0))}function Cs(e,t,n,s,r){return to(ge(e,t,n,s,r,!0))}function Yt(e){return e?e.__v_isVNode===!0:!1}function ht(e,t){return e.type===t.type&&e.key===t.key}const no=({key:e})=>e??null,yn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?le(e)||ae(e)||G(e)?{i:pe,r:e,k:t,f:!!n}:e:null);function so(e,t=null,n=null,s=0,r=null,i=e===Se?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&no(t),ref:t&&yn(t),scopeId:_i,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:pe};return l?(qs(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=le(n)?8:16),Xt>0&&!o&&Ae&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Ae.push(c),c}const ge=vc;function vc(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===Ii)&&(e=he),Yt(e)){const l=ot(e,t,!0);return n&&qs(l,n),Xt>0&&!i&&Ae&&(l.shapeFlag&6?Ae[Ae.indexOf(e)]=l:Ae.push(l)),l.patchFlag=-2,l}if(Ac(e)&&(e=e.__vccOpts),t){t=yc(t);let{class:l,style:c}=t;l&&!le(l)&&(t.class=Fs(l)),se(c)&&(Ws(c)&&!B(c)&&(c=ue({},c)),t.style=Ns(c))}const o=le(e)?1:Zi(e)?128:bi(e)?64:se(e)?4:G(e)?2:0;return so(e,t,n,s,r,o,i,!0)}function yc(e){return e?Ws(e)||Vi(e)?ue({},e):e:null}function ot(e,t,n=!1,s=!1){const{props:r,ref:i,patchFlag:o,children:l,transition:c}=e,u=t?_c(r||{},t):r,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&no(u),ref:t&&t.ref?n&&i?B(i)?i.concat(yn(t)):[i,yn(t)]:yn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Se?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&ot(e.ssContent),ssFallback:e.ssFallback&&ot(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&s&&Gt(a,c.clone(a)),a}function ro(e=" ",t=0){return ge(bt,null,e,t)}function yf(e,t){const n=ge(kt,null,e);return n.staticCount=t,n}function _f(e="",t=!1){return t?(Es(),Cs(he,null,e)):ge(he,null,e)}function Me(e){return e==null||typeof e=="boolean"?ge(he):B(e)?ge(Se,null,e.slice()):Yt(e)?nt(e):ge(bt,null,String(e))}function nt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:ot(e)}function qs(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(B(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),qs(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!Vi(t)?t._ctx=pe:r===3&&pe&&(pe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else G(t)?(t={default:t,_ctx:pe},n=32):(t=String(t),s&64?(n=16,t=[ro(t)]):n=8);e.children=t,e.shapeFlag|=n}function _c(...e){const t={};for(let n=0;nfe||pe;let Rn,As;{const e=Pn(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),i=>{r.length>1?r.forEach(o=>o(i)):r[0](i)}};Rn=t("__VUE_INSTANCE_SETTERS__",n=>fe=n),As=t("__VUE_SSR_SETTERS__",n=>zt=n)}const tn=e=>{const t=fe;return Rn(e),e.scope.on(),()=>{e.scope.off(),Rn(t)}},vr=()=>{fe&&fe.scope.off(),Rn(null)};function io(e){return e.vnode.shapeFlag&4}let zt=!1;function xc(e,t=!1,n=!1){t&&As(t);const{props:s,children:r}=e.vnode,i=io(e);Zl(e,s,i,t),sc(e,r,n||t);const o=i?Tc(e,t):void 0;return t&&As(!1),o}function Tc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ul);const{setup:s}=n;if(s){Ge();const r=e.setupContext=s.length>1?lo(e):null,i=tn(e),o=Zt(s,e,0,[e.props,r]),l=Gr(o);if(Xe(),i(),(l||e.sp)&&!vt(e)&&Ai(e),l){if(o.then(vr,vr),t)return o.then(c=>{yr(e,c)}).catch(c=>{Hn(c,e,0)});e.asyncDep=o}else yr(e,o)}else oo(e)}function yr(e,t,n){G(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:se(t)&&(e.setupState=gi(t)),oo(e)}function oo(e,t,n){const s=e.type;e.render||(e.render=s.render||ke);{const r=tn(e);Ge();try{Kl(e)}finally{Xe(),r()}}}const Ec={get(e,t){return _e(e,"get",""),e[t]}};function lo(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Ec),slots:e.slots,emit:e.emit,expose:t}}function Gs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(gi(vn(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Wt)return Wt[n](e)},has(t,n){return n in t||n in Wt}})):e.proxy}function Cc(e,t=!0){return G(e)?e.displayName||e.name:e.name||t&&e.__name}function Ac(e){return G(e)&&"__vccOpts"in e}const ie=(e,t)=>yl(e,t,zt);function Rs(e,t,n){const s=arguments.length;return s===2?se(t)&&!B(t)?Yt(t)?ge(e,null,[t]):ge(e,t):ge(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Yt(n)&&(n=[n]),ge(e,t,n))}const Rc="3.5.17";/** -* @vue/runtime-dom v3.5.17 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Os;const _r=typeof window<"u"&&window.trustedTypes;if(_r)try{Os=_r.createPolicy("vue",{createHTML:e=>e})}catch{}const co=Os?e=>Os.createHTML(e):e=>e,Oc="http://www.w3.org/2000/svg",Mc="http://www.w3.org/1998/Math/MathML",Ke=typeof document<"u"?document:null,br=Ke&&Ke.createElement("template"),Ic={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Ke.createElementNS(Oc,e):t==="mathml"?Ke.createElementNS(Mc,e):n?Ke.createElement(e,{is:n}):Ke.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Ke.createTextNode(e),createComment:e=>Ke.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ke.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{br.innerHTML=co(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=br.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Ze="transition",Dt="animation",Jt=Symbol("_vtc"),ao={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Pc=ue({},wi,ao),Lc=e=>(e.displayName="Transition",e.props=Pc,e),bf=Lc((e,{slots:t})=>Rs(Rl,Nc(e),t)),ft=(e,t=[])=>{B(e)?e.forEach(n=>n(...t)):e&&e(...t)},wr=e=>e?B(e)?e.some(t=>t.length>1):e.length>1:!1;function Nc(e){const t={};for(const _ in e)_ in ao||(t[_]=e[_]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:u=o,appearToClass:a=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:v=`${n}-leave-active`,leaveToClass:y=`${n}-leave-to`}=e,A=Fc(r),P=A&&A[0],K=A&&A[1],{onBeforeEnter:H,onEnter:k,onEnterCancelled:p,onLeave:g,onLeaveCancelled:M,onBeforeAppear:W=H,onAppear:R=k,onAppearCancelled:U=p}=t,T=(_,N,Y,re)=>{_._enterCancelled=re,ut(_,N?a:l),ut(_,N?u:o),Y&&Y()},I=(_,N)=>{_._isLeaving=!1,ut(_,h),ut(_,y),ut(_,v),N&&N()},E=_=>(N,Y)=>{const re=_?R:k,j=()=>T(N,_,Y);ft(re,[N,j]),Sr(()=>{ut(N,_?c:i),Be(N,_?a:l),wr(re)||xr(N,s,P,j)})};return ue(t,{onBeforeEnter(_){ft(H,[_]),Be(_,i),Be(_,o)},onBeforeAppear(_){ft(W,[_]),Be(_,c),Be(_,u)},onEnter:E(!1),onAppear:E(!0),onLeave(_,N){_._isLeaving=!0;const Y=()=>I(_,N);Be(_,h),_._enterCancelled?(Be(_,v),Cr()):(Cr(),Be(_,v)),Sr(()=>{_._isLeaving&&(ut(_,h),Be(_,y),wr(g)||xr(_,s,K,Y))}),ft(g,[_,Y])},onEnterCancelled(_){T(_,!1,void 0,!0),ft(p,[_])},onAppearCancelled(_){T(_,!0,void 0,!0),ft(U,[_])},onLeaveCancelled(_){I(_),ft(M,[_])}})}function Fc(e){if(e==null)return null;if(se(e))return[ns(e.enter),ns(e.leave)];{const t=ns(e);return[t,t]}}function ns(e){return Lo(e)}function Be(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Jt]||(e[Jt]=new Set)).add(t)}function ut(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[Jt];n&&(n.delete(t),n.size||(e[Jt]=void 0))}function Sr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Hc=0;function xr(e,t,n,s){const r=e._endId=++Hc,i=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=Dc(e,t);if(!o)return s();const u=o+"end";let a=0;const h=()=>{e.removeEventListener(u,v),i()},v=y=>{y.target===e&&++a>=c&&h()};setTimeout(()=>{a(n[A]||"").split(", "),r=s(`${Ze}Delay`),i=s(`${Ze}Duration`),o=Tr(r,i),l=s(`${Dt}Delay`),c=s(`${Dt}Duration`),u=Tr(l,c);let a=null,h=0,v=0;t===Ze?o>0&&(a=Ze,h=o,v=i.length):t===Dt?u>0&&(a=Dt,h=u,v=c.length):(h=Math.max(o,u),a=h>0?o>u?Ze:Dt:null,v=a?a===Ze?i.length:c.length:0);const y=a===Ze&&/\b(transform|all)(,|$)/.test(s(`${Ze}Property`).toString());return{type:a,timeout:h,propCount:v,hasTransform:y}}function Tr(e,t){for(;e.lengthEr(n)+Er(e[s])))}function Er(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Cr(){return document.body.offsetHeight}function $c(e,t,n){const s=e[Jt];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Ar=Symbol("_vod"),jc=Symbol("_vsh"),Vc=Symbol(""),Wc=/(^|;)\s*display\s*:/;function kc(e,t,n){const s=e.style,r=le(n);let i=!1;if(n&&!r){if(t)if(le(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&_n(s,l,"")}else for(const o in t)n[o]==null&&_n(s,o,"");for(const o in n)o==="display"&&(i=!0),_n(s,o,n[o])}else if(r){if(t!==n){const o=s[Vc];o&&(n+=";"+o),s.cssText=n,i=Wc.test(n)}}else t&&e.removeAttribute("style");Ar in e&&(e[Ar]=i?s.display:"",e[jc]&&(s.display="none"))}const Rr=/\s*!important$/;function _n(e,t,n){if(B(n))n.forEach(s=>_n(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=Uc(e,t);Rr.test(n)?e.setProperty(lt(s),n.replace(Rr,""),"important"):e[s]=n}}const Or=["Webkit","Moz","ms"],ss={};function Uc(e,t){const n=ss[t];if(n)return n;let s=Ne(t);if(s!=="filter"&&s in e)return ss[t]=s;s=In(s);for(let r=0;rrs||(Xc.then(()=>rs=0),rs=Date.now());function zc(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;De(Jc(s,n.value),t,5,[s])};return n.value=e,n.attached=Yc(),n}function Jc(e,t){if(B(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Fr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Qc=(e,t,n,s,r,i)=>{const o=r==="svg";t==="class"?$c(e,s,o):t==="style"?kc(e,n,s):Qt(t)?Is(t)||qc(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Zc(e,t,s,o))?(Pr(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Ir(e,t,s,o,i,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!le(s))?Pr(e,Ne(t),s,i,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Ir(e,t,s,o))};function Zc(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&Fr(t)&&G(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return Fr(t)&&le(n)?!1:t in e}const ea=["ctrl","shift","alt","meta"],ta={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>ea.some(n=>e[`${n}Key`]&&!t.includes(n))},wf=(e,t)=>{const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(r,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=r=>{if(!("key"in r))return;const i=lt(r.key);if(t.some(o=>o===i||na[o]===i))return e(r)})},sa=ue({patchProp:Qc},Ic);let is,Hr=!1;function ra(){return is=Hr?is:ic(sa),Hr=!0,is}const xf=(...e)=>{const t=ra().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=oa(s);if(r)return n(r,!0,ia(r))},t};function ia(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function oa(e){return le(e)?document.querySelector(e):e}const la=window.__VP_SITE_DATA__;function fo(e){return Zr()?(ko(e),!0):!1}const os=new WeakMap,ca=(...e)=>{var t;const n=e[0],s=(t=en())==null?void 0:t.proxy;if(s==null&&!Di())throw new Error("injectLocal must be called in setup");return s&&os.has(s)&&n in os.get(s)?os.get(s)[n]:_t(...e)},uo=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const aa=Object.prototype.toString,fa=e=>aa.call(e)==="[object Object]",St=()=>{},Dr=ua();function ua(){var e,t;return uo&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Xs(e,t){function n(...s){return new Promise((r,i)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(r).catch(i)})}return n}const ho=e=>e();function da(e,t={}){let n,s,r=St;const i=c=>{clearTimeout(c),r(),r=St};let o;return c=>{const u=ce(e),a=ce(t.maxWait);return n&&i(n),u<=0||a!==void 0&&a<=0?(s&&(i(s),s=null),Promise.resolve(c())):new Promise((h,v)=>{r=t.rejectOnCancel?v:h,o=c,a&&!s&&(s=setTimeout(()=>{n&&i(n),s=null,h(o())},a)),n=setTimeout(()=>{s&&i(s),s=null,h(c())},u)})}}function ha(...e){let t=0,n,s=!0,r=St,i,o,l,c,u;!ae(e[0])&&typeof e[0]=="object"?{delay:o,trailing:l=!0,leading:c=!0,rejectOnCancel:u=!1}=e[0]:[o,l=!0,c=!0,u=!1]=e;const a=()=>{n&&(clearTimeout(n),n=void 0,r(),r=St)};return v=>{const y=ce(o),A=Date.now()-t,P=()=>i=v();return a(),y<=0?(t=Date.now(),P()):(A>y&&(c||!s)?(t=Date.now(),P()):l&&(i=new Promise((K,H)=>{r=u?H:K,n=setTimeout(()=>{t=Date.now(),s=!0,K(P()),a()},Math.max(0,y-A))})),!c&&!n&&(n=setTimeout(()=>s=!0,y)),s=!1,i)}}function pa(e=ho,t={}){const{initialState:n="active"}=t,s=Ys(n==="active");function r(){s.value=!1}function i(){s.value=!0}const o=(...l)=>{s.value&&e(...l)};return{isActive:Fn(s),pause:r,resume:i,eventFilter:o}}function $r(e){return e.endsWith("rem")?Number.parseFloat(e)*16:Number.parseFloat(e)}function ga(e){return en()}function ls(e){return Array.isArray(e)?e:[e]}function Ys(...e){if(e.length!==1)return gl(...e);const t=e[0];return typeof t=="function"?Fn(dl(()=>({get:t,set:St}))):mt(t)}function ma(e,t=200,n={}){return Xs(da(t,n),e)}function va(e,t=200,n=!1,s=!0,r=!1){return Xs(ha(t,n,s,r),e)}function ya(e,t,n={}){const{eventFilter:s=ho,...r}=n;return Le(e,Xs(s,t),r)}function _a(e,t,n={}){const{eventFilter:s,initialState:r="active",...i}=n,{eventFilter:o,pause:l,resume:c,isActive:u}=pa(s,{initialState:r});return{stop:ya(e,t,{...i,eventFilter:o}),pause:l,resume:c,isActive:u}}function Un(e,t=!0,n){ga()?Lt(e,n):t?e():Dn(e)}function ba(e,t,n){return Le(e,t,{...n,immediate:!0})}const Ye=uo?window:void 0;function zs(e){var t;const n=ce(e);return(t=n==null?void 0:n.$el)!=null?t:n}function ze(...e){const t=[],n=()=>{t.forEach(l=>l()),t.length=0},s=(l,c,u,a)=>(l.addEventListener(c,u,a),()=>l.removeEventListener(c,u,a)),r=ie(()=>{const l=ls(ce(e[0])).filter(c=>c!=null);return l.every(c=>typeof c!="string")?l:void 0}),i=ba(()=>{var l,c;return[(c=(l=r.value)==null?void 0:l.map(u=>zs(u)))!=null?c:[Ye].filter(u=>u!=null),ls(ce(r.value?e[1]:e[0])),ls(ks(r.value?e[2]:e[1])),ce(r.value?e[3]:e[2])]},([l,c,u,a])=>{if(n(),!(l!=null&&l.length)||!(c!=null&&c.length)||!(u!=null&&u.length))return;const h=fa(a)?{...a}:a;t.push(...l.flatMap(v=>c.flatMap(y=>u.map(A=>s(v,y,A,h)))))},{flush:"post"}),o=()=>{i(),n()};return fo(n),o}function wa(){const e=Pe(!1),t=en();return t&&Lt(()=>{e.value=!0},t),e}function Sa(e){const t=wa();return ie(()=>(t.value,!!e()))}function xa(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function Tf(...e){let t,n,s={};e.length===3?(t=e[0],n=e[1],s=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],s=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:r=Ye,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=s,c=xa(t);return ze(r,i,a=>{a.repeat&&ce(l)||c(a)&&n(a)},o)}const Ta=Symbol("vueuse-ssr-width");function Ea(){const e=Di()?ca(Ta,null):null;return typeof e=="number"?e:void 0}function po(e,t={}){const{window:n=Ye,ssrWidth:s=Ea()}=t,r=Sa(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function"),i=Pe(typeof s=="number"),o=Pe(),l=Pe(!1),c=u=>{l.value=u.matches};return Yi(()=>{if(i.value){i.value=!r.value;const u=ce(e).split(",");l.value=u.some(a=>{const h=a.includes("not all"),v=a.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/),y=a.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/);let A=!!(v||y);return v&&A&&(A=s>=$r(v[1])),y&&A&&(A=s<=$r(y[1])),h?!A:A});return}r.value&&(o.value=n.matchMedia(ce(e)),l.value=o.value.matches)}),ze(o,"change",c,{passive:!0}),ie(()=>l.value)}const dn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},hn="__vueuse_ssr_handlers__",Ca=Aa();function Aa(){return hn in dn||(dn[hn]=dn[hn]||{}),dn[hn]}function go(e,t){return Ca[e]||t}function mo(e){return po("(prefers-color-scheme: dark)",e)}function Ra(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Oa={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},jr="vueuse-storage";function Ma(e,t,n,s={}){var r;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:u=!1,shallow:a,window:h=Ye,eventFilter:v,onError:y=E=>{console.error(E)},initOnMounted:A}=s,P=(a?Pe:mt)(typeof t=="function"?t():t),K=ie(()=>ce(e));if(!n)try{n=go("getDefaultStorage",()=>{var E;return(E=Ye)==null?void 0:E.localStorage})()}catch(E){y(E)}if(!n)return P;const H=ce(t),k=Ra(H),p=(r=s.serializer)!=null?r:Oa[k],{pause:g,resume:M}=_a(P,()=>R(P.value),{flush:i,deep:o,eventFilter:v});Le(K,()=>T(),{flush:i}),h&&l&&Un(()=>{n instanceof Storage?ze(h,"storage",T,{passive:!0}):ze(h,jr,I),A&&T()}),A||T();function W(E,_){if(h){const N={key:K.value,oldValue:E,newValue:_,storageArea:n};h.dispatchEvent(n instanceof Storage?new StorageEvent("storage",N):new CustomEvent(jr,{detail:N}))}}function R(E){try{const _=n.getItem(K.value);if(E==null)W(_,null),n.removeItem(K.value);else{const N=p.write(E);_!==N&&(n.setItem(K.value,N),W(_,N))}}catch(_){y(_)}}function U(E){const _=E?E.newValue:n.getItem(K.value);if(_==null)return c&&H!=null&&n.setItem(K.value,p.write(H)),H;if(!E&&u){const N=p.read(_);return typeof u=="function"?u(N,H):k==="object"&&!Array.isArray(N)?{...H,...N}:N}else return typeof _!="string"?_:p.read(_)}function T(E){if(!(E&&E.storageArea!==n)){if(E&&E.key==null){P.value=H;return}if(!(E&&E.key!==K.value)){g();try{(E==null?void 0:E.newValue)!==p.write(P.value)&&(P.value=U(E))}catch(_){y(_)}finally{E?Dn(M):M()}}}}function I(E){T(E.detail)}return P}const Ia="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Pa(e={}){const{selector:t="html",attribute:n="class",initialValue:s="auto",window:r=Ye,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:u,disableTransition:a=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},v=mo({window:r}),y=ie(()=>v.value?"dark":"light"),A=c||(o==null?Ys(s):Ma(o,s,i,{window:r,listenToStorageChanges:l})),P=ie(()=>A.value==="auto"?y.value:A.value),K=go("updateHTMLAttrs",(g,M,W)=>{const R=typeof g=="string"?r==null?void 0:r.document.querySelector(g):zs(g);if(!R)return;const U=new Set,T=new Set;let I=null;if(M==="class"){const _=W.split(/\s/g);Object.values(h).flatMap(N=>(N||"").split(/\s/g)).filter(Boolean).forEach(N=>{_.includes(N)?U.add(N):T.add(N)})}else I={key:M,value:W};if(U.size===0&&T.size===0&&I===null)return;let E;a&&(E=r.document.createElement("style"),E.appendChild(document.createTextNode(Ia)),r.document.head.appendChild(E));for(const _ of U)R.classList.add(_);for(const _ of T)R.classList.remove(_);I&&R.setAttribute(I.key,I.value),a&&(r.getComputedStyle(E).opacity,document.head.removeChild(E))});function H(g){var M;K(t,n,(M=h[g])!=null?M:g)}function k(g){e.onChanged?e.onChanged(g,H):H(g)}Le(P,k,{flush:"post",immediate:!0}),Un(()=>k(P.value));const p=ie({get(){return u?A.value:P.value},set(g){A.value=g}});return Object.assign(p,{store:A,system:y,state:P})}function La(e={}){const{valueDark:t="dark",valueLight:n=""}=e,s=Pa({...e,onChanged:(o,l)=>{var c;e.onChanged?(c=e.onChanged)==null||c.call(e,o==="dark",l,o):l(o)},modes:{dark:t,light:n}}),r=ie(()=>s.system.value);return ie({get(){return s.value==="dark"},set(o){const l=o?"dark":"light";r.value===l?s.value="auto":s.value=l}})}function cs(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}const Vr=1;function Na(e,t={}){const{throttle:n=0,idle:s=200,onStop:r=St,onScroll:i=St,offset:o={left:0,right:0,top:0,bottom:0},eventListenerOptions:l={capture:!1,passive:!0},behavior:c="auto",window:u=Ye,onError:a=R=>{console.error(R)}}=t,h=Pe(0),v=Pe(0),y=ie({get(){return h.value},set(R){P(R,void 0)}}),A=ie({get(){return v.value},set(R){P(void 0,R)}});function P(R,U){var T,I,E,_;if(!u)return;const N=ce(e);if(!N)return;(E=N instanceof Document?u.document.body:N)==null||E.scrollTo({top:(T=ce(U))!=null?T:A.value,left:(I=ce(R))!=null?I:y.value,behavior:ce(c)});const Y=((_=N==null?void 0:N.document)==null?void 0:_.documentElement)||(N==null?void 0:N.documentElement)||N;y!=null&&(h.value=Y.scrollLeft),A!=null&&(v.value=Y.scrollTop)}const K=Pe(!1),H=Pt({left:!0,right:!1,top:!0,bottom:!1}),k=Pt({left:!1,right:!1,top:!1,bottom:!1}),p=R=>{K.value&&(K.value=!1,k.left=!1,k.right=!1,k.top=!1,k.bottom=!1,r(R))},g=ma(p,n+s),M=R=>{var U;if(!u)return;const T=((U=R==null?void 0:R.document)==null?void 0:U.documentElement)||(R==null?void 0:R.documentElement)||zs(R),{display:I,flexDirection:E,direction:_}=getComputedStyle(T),N=_==="rtl"?-1:1,Y=T.scrollLeft;k.left=Yh.value;const re=Math.abs(Y*N)<=(o.left||0),j=Math.abs(Y*N)+T.clientWidth>=T.scrollWidth-(o.right||0)-Vr;I==="flex"&&E==="row-reverse"?(H.left=j,H.right=re):(H.left=re,H.right=j),h.value=Y;let X=T.scrollTop;R===u.document&&!X&&(X=u.document.body.scrollTop),k.top=Xv.value;const D=Math.abs(X)<=(o.top||0),oe=Math.abs(X)+T.clientHeight>=T.scrollHeight-(o.bottom||0)-Vr;I==="flex"&&E==="column-reverse"?(H.top=oe,H.bottom=D):(H.top=D,H.bottom=oe),v.value=X},W=R=>{var U;if(!u)return;const T=(U=R.target.documentElement)!=null?U:R.target;M(T),K.value=!0,g(R),i(R)};return ze(e,"scroll",n?va(W,n,!0,!1):W,l),Un(()=>{try{const R=ce(e);if(!R)return;M(R)}catch(R){a(R)}}),ze(e,"scrollend",p,l),{x:y,y:A,isScrolling:K,arrivedState:H,directions:k,measure(){const R=ce(e);u&&R&&M(R)}}}function vo(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const as=new WeakMap;function Ef(e,t=!1){const n=Pe(t);let s=null,r="";Le(Ys(e),l=>{const c=cs(ce(l));if(c){const u=c;if(as.get(u)||as.set(u,u.style.overflow),u.style.overflow!=="hidden"&&(r=u.style.overflow),u.style.overflow==="hidden")return n.value=!0;if(n.value)return u.style.overflow="hidden"}},{immediate:!0});const i=()=>{const l=cs(ce(e));!l||n.value||(Dr&&(s=ze(l,"touchmove",c=>{Fa(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=cs(ce(e));!l||!n.value||(Dr&&(s==null||s()),l.style.overflow=r,as.delete(l),n.value=!1)};return fo(o),ie({get(){return n.value},set(l){l?i():o()}})}function Cf(e={}){const{window:t=Ye,...n}=e;return Na(t,n)}function Af(e={}){const{window:t=Ye,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:s=Number.POSITIVE_INFINITY,listenOrientation:r=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=Pe(n),c=Pe(s),u=()=>{if(t)if(o==="outer")l.value=t.outerWidth,c.value=t.outerHeight;else if(o==="visual"&&t.visualViewport){const{width:h,height:v,scale:y}=t.visualViewport;l.value=Math.round(h*y),c.value=Math.round(v*y)}else i?(l.value=t.innerWidth,c.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,c.value=t.document.documentElement.clientHeight)};u(),Un(u);const a={passive:!0};if(ze("resize",u,a),t&&o==="visual"&&t.visualViewport&&ze(t.visualViewport,"resize",u,a),r){const h=po("(orientation: portrait)");Le(h,()=>u())}return{width:l,height:c}}const fs={};var us={};const yo=/^(?:[a-z]+:|\/\/)/i,Ha="vitepress-theme-appearance",Da=/#.*$/,$a=/[?#].*$/,ja=/(?:(^|\/)index)?\.(?:md|html)$/,ye=typeof document<"u",_o={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function Va(e,t,n=!1){if(t===void 0)return!1;if(e=Wr(`/${e}`),n)return new RegExp(t).test(e);if(Wr(t)!==e)return!1;const s=t.match(Da);return s?(ye?location.hash:"")===s[0]:!0}function Wr(e){return decodeURI(e).replace($a,"").replace(ja,"$1")}function Wa(e){return yo.test(e)}function ka(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!Wa(n)&&Va(t,`/${n}/`,!0))||"root"}function Ua(e,t){var s,r,i,o,l,c,u;const n=ka(e,t);return Object.assign({},e,{localeIndex:n,lang:((s=e.locales[n])==null?void 0:s.lang)??e.lang,dir:((r=e.locales[n])==null?void 0:r.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:wo(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(u=e.locales[n])==null?void 0:u.themeConfig}})}function bo(e,t){const n=t.title||e.title,s=t.titleTemplate??e.titleTemplate;if(typeof s=="string"&&s.includes(":title"))return s.replace(/:title/g,n);const r=Ba(e.title,s);return n===r.slice(3)?n:`${n}${r}`}function Ba(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function Ka(e,t){const[n,s]=t;if(n!=="meta")return!1;const r=Object.entries(s)[0];return r==null?!1:e.some(([i,o])=>i===n&&o[r[0]]===r[1])}function wo(e,t){return[...e.filter(n=>!Ka(t,n)),...t]}const qa=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,Ga=/^[a-z]:/i;function kr(e){const t=Ga.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(qa,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const ds=new Set;function Xa(e){if(ds.size===0){const n=typeof process=="object"&&(us==null?void 0:us.VITE_EXTRA_EXTENSIONS)||(fs==null?void 0:fs.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(s=>ds.add(s))}const t=e.split(".").pop();return t==null||!ds.has(t.toLowerCase())}const Ya=Symbol(),wt=Pe(la);function Rf(e){const t=ie(()=>Ua(wt.value,e.data.relativePath)),n=t.value.appearance,s=n==="force-dark"?mt(!0):n==="force-auto"?mo():n?La({storageKey:Ha,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):mt(!1),r=mt(ye?location.hash:"");return ye&&window.addEventListener("hashchange",()=>{r.value=location.hash}),Le(()=>e.data,()=>{r.value=ye?location.hash:""}),{site:t,theme:ie(()=>t.value.themeConfig),page:ie(()=>e.data),frontmatter:ie(()=>e.data.frontmatter),params:ie(()=>e.data.params),lang:ie(()=>t.value.lang),dir:ie(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:ie(()=>t.value.localeIndex||"root"),title:ie(()=>bo(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:s,hash:ie(()=>r.value)}}function za(){const e=_t(Ya);if(!e)throw new Error("vitepress data not properly injected in app");return e}function Ja(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function Ur(e){return yo.test(e)||!e.startsWith("/")?e:Ja(wt.value.base,e)}function Qa(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ye){const n="/";t=kr(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let s=__VP_HASH_MAP__[t.toLowerCase()];if(s||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",s=__VP_HASH_MAP__[t.toLowerCase()]),!s)return null;t=`${n}assets/${t}.${s}.js`}else t=`./${kr(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let bn=[];function Of(e){bn.push(e),Vn(()=>{bn=bn.filter(t=>t!==e)})}function Za(){let e=wt.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=Br(e,n);else if(Array.isArray(e))for(const s of e){const r=Br(s,n);if(r){t=r;break}}return t}function Br(e,t){const n=document.querySelector(e);if(!n)return 0;const s=n.getBoundingClientRect().bottom;return s<0?0:s+t}const ef=Symbol(),So="http://a.com",tf=()=>({path:"/",component:null,data:_o});function Mf(e,t){const n=Pt(tf()),s={route:n,go:r};async function r(l=ye?location.href:"/"){var c,u;l=hs(l),await((c=s.onBeforeRouteChange)==null?void 0:c.call(s,l))!==!1&&(ye&&l!==hs(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((u=s.onAfterRouteChange??s.onAfterRouteChanged)==null?void 0:u(l)))}let i=null;async function o(l,c=0,u=!1){var v,y;if(await((v=s.onBeforePageLoad)==null?void 0:v.call(s,l))===!1)return;const a=new URL(l,So),h=i=a.pathname;try{let A=await e(h);if(!A)throw new Error(`Page not found: ${h}`);if(i===h){i=null;const{default:P,__pageData:K}=A;if(!P)throw new Error(`Invalid route component: ${P}`);await((y=s.onAfterPageLoad)==null?void 0:y.call(s,l)),n.path=ye?h:Ur(h),n.component=vn(P),n.data=vn(K),ye&&Dn(()=>{let H=wt.value.base+K.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!wt.value.cleanUrls&&!H.endsWith("/")&&(H+=".html"),H!==a.pathname&&(a.pathname=H,l=H+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let k=null;try{k=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(p){console.warn(p)}if(k){Kr(k,a.hash);return}}window.scrollTo(0,c)})}}catch(A){if(!/fetch|Page not found/.test(A.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(A),!u)try{const P=await fetch(wt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await P.json(),await o(l,c,!0);return}catch{}if(i===h){i=null,n.path=ye?h:Ur(h),n.component=t?vn(t):null;const P=ye?h.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={..._o,relativePath:P}}}}return ye&&(history.state===null&&history.replaceState({},""),window.addEventListener("click",l=>{if(l.defaultPrevented||!(l.target instanceof Element)||l.target.closest("button")||l.button!==0||l.ctrlKey||l.shiftKey||l.altKey||l.metaKey)return;const c=l.target.closest("a");if(!c||c.closest(".vp-raw")||c.hasAttribute("download")||c.hasAttribute("target"))return;const u=c.getAttribute("href")??(c instanceof SVGAElement?c.getAttribute("xlink:href"):null);if(u==null)return;const{href:a,origin:h,pathname:v,hash:y,search:A}=new URL(u,c.baseURI),P=new URL(location.href);h===P.origin&&Xa(v)&&(l.preventDefault(),v===P.pathname&&A===P.search?(y!==P.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:P.href,newURL:a}))),y?Kr(c,y,c.classList.contains("header-anchor")):window.scrollTo(0,0)):r(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var u;if(l.state===null)return;const c=hs(location.href);await o(c,l.state&&l.state.scrollPosition||0),await((u=s.onAfterRouteChange??s.onAfterRouteChanged)==null?void 0:u(c))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),s}function nf(){const e=_t(ef);if(!e)throw new Error("useRouter() is called without provider.");return e}function xo(){return nf().route}function Kr(e,t,n=!1){let s=null;try{s=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(r){console.warn(r)}if(s){let r=function(){!n||Math.abs(o-window.scrollY)>window.innerHeight?window.scrollTo(0,o):window.scrollTo({left:0,top:o,behavior:"smooth"})};const i=parseInt(window.getComputedStyle(s).paddingTop,10),o=window.scrollY+s.getBoundingClientRect().top-Za()+i;requestAnimationFrame(r)}}function hs(e){const t=new URL(e,So);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),wt.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const pn=()=>bn.forEach(e=>e()),If=Ci({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=xo(),{frontmatter:n,site:s}=za();return Le(n,pn,{deep:!0,flush:"post"}),()=>Rs(e.as,s.value.contentProps??{style:{position:"relative"}},[t.component?Rs(t.component,{onVnodeMounted:pn,onVnodeUpdated:pn,onVnodeUnmounted:pn}):"404 Page Not Found"])}}),Pf=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Lf=Ci({setup(e,{slots:t}){const n=mt(!1);return Lt(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function Nf(){ye&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const s=(n=t.parentElement)==null?void 0:n.parentElement;if(!s)return;const r=Array.from(s.querySelectorAll("input")).indexOf(t);if(r<0)return;const i=s.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(u=>u.classList.contains("active"));if(!o)return;const l=i.children[r];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=s==null?void 0:s.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function Ff(){if(ye){const e=new WeakMap;window.addEventListener("click",t=>{var s;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const r=n.parentElement,i=(s=n.nextElementSibling)==null?void 0:s.nextElementSibling;if(!r||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(r.className),l=[".vp-copy-ignore",".diff.remove"],c=i.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(a=>a.remove());let u=c.textContent||"";o&&(u=u.replace(/^ *(\$|>) /gm,"").trim()),sf(u).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const a=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,a)})}})}}async function sf(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const s=document.getSelection(),r=s?s.rangeCount>0&&s.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),r&&(s.removeAllRanges(),s.addRange(r)),n&&n.focus()}}function Hf(e,t){let n=!0,s=[];const r=i=>{if(n){n=!1,i.forEach(l=>{const c=ps(l);for(const u of document.head.children)if(u.isEqualNode(c)){s.push(u);return}});return}const o=i.map(ps);s.forEach((l,c)=>{const u=o.findIndex(a=>a==null?void 0:a.isEqualNode(l??null));u!==-1?delete o[u]:(l==null||l.remove(),delete s[c])}),o.forEach(l=>l&&document.head.appendChild(l)),s=[...s,...o].filter(Boolean)};Yi(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],u=bo(o,i);u!==document.title&&(document.title=u);const a=l||o.description;let h=document.querySelector("meta[name=description]");h?h.getAttribute("content")!==a&&h.setAttribute("content",a):ps(["meta",{name:"description",content:a}]),r(wo(o.head,of(c)))})}function ps([e,t,n]){const s=document.createElement(e);for(const r in t)s.setAttribute(r,t[r]);return n&&(s.innerHTML=n),e==="script"&&t.async==null&&(s.async=!1),s}function rf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function of(e){return e.filter(t=>!rf(t))}const gs=new Set,To=()=>document.createElement("link"),lf=e=>{const t=To();t.rel="prefetch",t.href=e,document.head.appendChild(t)},cf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let gn;const af=ye&&(gn=To())&&gn.relList&&gn.relList.supports&&gn.relList.supports("prefetch")?lf:cf;function Df(){if(!ye||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const s=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!gs.has(c)){gs.add(c);const u=Qa(c);u&&af(u)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{hostname:o,pathname:l}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||i.target!=="_blank"&&o===location.hostname&&(l!==location.pathname?n.observe(i):gs.add(l))})})};Lt(s);const r=xo();Le(()=>r.path,s),Vn(()=>{n&&n.disconnect()})}export{gf as $,Za as A,df as B,ff as C,Pe as D,Of as E,Se as F,ge as G,uf as H,yo as I,xo as J,_c as K,_t as L,Af as M,Ns as N,Tf as O,Dn as P,Cf as Q,ye as R,Fn as S,bf as T,Ef as U,Ql as V,pf as W,Sf as X,Oi as Y,wf as Z,Pf as _,ro as a,Rs as a0,Hf as a1,ef as a2,Rf as a3,Ya as a4,If as a5,Lf as a6,wt as a7,Mf as a8,Qa as a9,xf as aa,Df as ab,Ff as ac,Nf as ad,yf as ae,Cs as b,vf as c,Ci as d,_f as e,Xa as f,Ur as g,ie as h,Wa as i,so as j,ks as k,Va as l,po as m,Fs as n,Es as o,mt as p,Le as q,hf as r,Yi as s,Vo as t,za as u,Lt as v,Tl as w,Vn as x,mf as y,$l as z}; diff --git a/docs/.vitepress/dist/assets/chunks/framework.BHpayLOB.js b/docs/.vitepress/dist/assets/chunks/framework.BHpayLOB.js new file mode 100644 index 0000000..30b7907 --- /dev/null +++ b/docs/.vitepress/dist/assets/chunks/framework.BHpayLOB.js @@ -0,0 +1,18 @@ +/** +* @vue/shared v3.5.17 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function js(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ee={},Mt=[],Be=()=>{},zo=()=>!1,nn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Vs=e=>e.startsWith("onUpdate:"),he=Object.assign,ks=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Qo=Object.prototype.hasOwnProperty,Q=(e,t)=>Qo.call(e,t),K=Array.isArray,Ot=e=>Dn(e)==="[object Map]",ui=e=>Dn(e)==="[object Set]",q=e=>typeof e=="function",le=e=>typeof e=="string",Ze=e=>typeof e=="symbol",se=e=>e!==null&&typeof e=="object",di=e=>(se(e)||q(e))&&q(e.then)&&q(e.catch),hi=Object.prototype.toString,Dn=e=>hi.call(e),Zo=e=>Dn(e).slice(8,-1),pi=e=>Dn(e)==="[object Object]",Us=e=>le(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Pt=js(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),$n=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},el=/-(\w)/g,Ne=$n(e=>e.replace(el,(t,n)=>n?n.toUpperCase():"")),tl=/\B([A-Z])/g,at=$n(e=>e.replace(tl,"-$1").toLowerCase()),jn=$n(e=>e.charAt(0).toUpperCase()+e.slice(1)),Sn=$n(e=>e?`on${jn(e)}`:""),it=(e,t)=>!Object.is(e,t),Tn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},xs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},nl=e=>{const t=le(e)?Number(e):NaN;return isNaN(t)?e:t};let pr;const Vn=()=>pr||(pr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Ws(e){if(K(e)){const t={};for(let n=0;n{if(n){const s=n.split(rl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Bs(e){let t="";if(le(e))t=e;else if(K(e))for(let n=0;n!!(e&&e.__v_isRef===!0),al=e=>le(e)?e:e==null?"":K(e)||se(e)&&(e.toString===hi||!q(e.toString))?mi(e)?al(e.value):JSON.stringify(e,vi,2):String(e),vi=(e,t)=>mi(t)?vi(e,t.value):Ot(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],i)=>(n[es(s,i)+" =>"]=r,n),{})}:ui(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>es(n))}:Ze(t)?es(t):se(t)&&!K(t)&&!pi(t)?String(t):t,es=(e,t="")=>{var n;return Ze(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.17 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ve;class fl{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=ve,!t&&ve&&(this.index=(ve.scopes||(ve.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0&&--this._on===0&&(ve=this.prevScope,this.prevScope=void 0)}stop(t){if(this._active){this._active=!1;let n,s;for(n=0,s=this.effects.length;n0)return;if(Wt){let t=Wt;for(Wt=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Ut;){let t=Ut;for(Ut=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function Si(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Ti(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),Gs(s),dl(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function Es(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(xi(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function xi(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Yt)||(e.globalVersion=Yt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Es(e))))return;e.flags|=2;const t=e.dep,n=ne,s=He;ne=e,He=!0;try{Si(e);const r=e.fn(e._value);(t.version===0||it(r,e._value))&&(e.flags|=128,e._value=r,t.version++)}catch(r){throw t.version++,r}finally{ne=n,He=s,Ti(e),e.flags&=-3}}function Gs(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)Gs(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function dl(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let He=!0;const Ei=[];function Je(){Ei.push(He),He=!1}function ze(){const e=Ei.pop();He=e===void 0?!0:e}function gr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ne;ne=void 0;try{t()}finally{ne=n}}}let Yt=0;class hl{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class kn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ne||!He||ne===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ne)n=this.activeLink=new hl(ne,this),ne.deps?(n.prevDep=ne.depsTail,ne.depsTail.nextDep=n,ne.depsTail=n):ne.deps=ne.depsTail=n,Ci(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=ne.depsTail,n.nextDep=void 0,ne.depsTail.nextDep=n,ne.depsTail=n,ne.deps===n&&(ne.deps=s)}return n}trigger(t){this.version++,Yt++,this.notify(t)}notify(t){Ks();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{qs()}}}function Ci(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)Ci(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Mn=new WeakMap,mt=Symbol(""),Cs=Symbol(""),Jt=Symbol("");function _e(e,t,n){if(He&&ne){let s=Mn.get(e);s||Mn.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new kn),r.map=s,r.key=n),r.track()}}function Xe(e,t,n,s,r,i){const o=Mn.get(e);if(!o){Yt++;return}const l=c=>{c&&c.trigger()};if(Ks(),t==="clear")o.forEach(l);else{const c=K(e),f=c&&Us(n);if(c&&n==="length"){const a=Number(s);o.forEach((d,m)=>{(m==="length"||m===Jt||!Ze(m)&&m>=a)&&l(d)})}else switch((n!==void 0||o.has(void 0))&&l(o.get(n)),f&&l(o.get(Jt)),t){case"add":c?f&&l(o.get("length")):(l(o.get(mt)),Ot(e)&&l(o.get(Cs)));break;case"delete":c||(l(o.get(mt)),Ot(e)&&l(o.get(Cs)));break;case"set":Ot(e)&&l(o.get(mt));break}}qs()}function pl(e,t){const n=Mn.get(e);return n&&n.get(t)}function xt(e){const t=z(e);return t===e?t:(_e(t,"iterate",Jt),Le(e)?t:t.map(pe))}function Un(e){return _e(e=z(e),"iterate",Jt),e}const gl={__proto__:null,[Symbol.iterator](){return ns(this,Symbol.iterator,pe)},concat(...e){return xt(this).concat(...e.map(t=>K(t)?xt(t):t))},entries(){return ns(this,"entries",e=>(e[1]=pe(e[1]),e))},every(e,t){return Ke(this,"every",e,t,void 0,arguments)},filter(e,t){return Ke(this,"filter",e,t,n=>n.map(pe),arguments)},find(e,t){return Ke(this,"find",e,t,pe,arguments)},findIndex(e,t){return Ke(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ke(this,"findLast",e,t,pe,arguments)},findLastIndex(e,t){return Ke(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ke(this,"forEach",e,t,void 0,arguments)},includes(...e){return ss(this,"includes",e)},indexOf(...e){return ss(this,"indexOf",e)},join(e){return xt(this).join(e)},lastIndexOf(...e){return ss(this,"lastIndexOf",e)},map(e,t){return Ke(this,"map",e,t,void 0,arguments)},pop(){return jt(this,"pop")},push(...e){return jt(this,"push",e)},reduce(e,...t){return mr(this,"reduce",e,t)},reduceRight(e,...t){return mr(this,"reduceRight",e,t)},shift(){return jt(this,"shift")},some(e,t){return Ke(this,"some",e,t,void 0,arguments)},splice(...e){return jt(this,"splice",e)},toReversed(){return xt(this).toReversed()},toSorted(e){return xt(this).toSorted(e)},toSpliced(...e){return xt(this).toSpliced(...e)},unshift(...e){return jt(this,"unshift",e)},values(){return ns(this,"values",pe)}};function ns(e,t,n){const s=Un(e),r=s[t]();return s!==e&&!Le(e)&&(r._next=r.next,r.next=()=>{const i=r._next();return i.value&&(i.value=n(i.value)),i}),r}const ml=Array.prototype;function Ke(e,t,n,s,r,i){const o=Un(e),l=o!==e&&!Le(e),c=o[t];if(c!==ml[t]){const d=c.apply(e,i);return l?pe(d):d}let f=n;o!==e&&(l?f=function(d,m){return n.call(this,pe(d),m,e)}:n.length>2&&(f=function(d,m){return n.call(this,d,m,e)}));const a=c.call(o,f,s);return l&&r?r(a):a}function mr(e,t,n,s){const r=Un(e);let i=n;return r!==e&&(Le(e)?n.length>3&&(i=function(o,l,c){return n.call(this,o,l,c,e)}):i=function(o,l,c){return n.call(this,o,pe(l),c,e)}),r[t](i,...s)}function ss(e,t,n){const s=z(e);_e(s,"iterate",Jt);const r=s[t](...n);return(r===-1||r===!1)&&Js(n[0])?(n[0]=z(n[0]),s[t](...n)):r}function jt(e,t,n=[]){Je(),Ks();const s=z(e)[t].apply(e,n);return qs(),ze(),s}const vl=js("__proto__,__v_isRef,__isVue"),Ai=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ze));function yl(e){Ze(e)||(e=String(e));const t=z(this);return _e(t,"has",e),t.hasOwnProperty(e)}class Ri{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return i;if(n==="__v_raw")return s===(r?i?Rl:Li:i?Pi:Oi).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=K(t);if(!r){let c;if(o&&(c=gl[n]))return c;if(n==="hasOwnProperty")return yl}const l=Reflect.get(t,n,fe(t)?t:s);return(Ze(n)?Ai.has(n):vl(n))||(r||_e(t,"get",n),i)?l:fe(l)?o&&Us(n)?l:l.value:se(l)?r?Wn(l):Nt(l):l}}class Mi extends Ri{constructor(t=!1){super(!1,t)}set(t,n,s,r){let i=t[n];if(!this._isShallow){const c=ot(i);if(!Le(s)&&!ot(s)&&(i=z(i),s=z(s)),!K(t)&&fe(i)&&!fe(s))return c?!1:(i.value=s,!0)}const o=K(t)&&Us(n)?Number(n)e,un=e=>Reflect.getPrototypeOf(e);function Tl(e,t,n){return function(...s){const r=this.__v_raw,i=z(r),o=Ot(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,f=r[e](...s),a=n?As:t?On:pe;return!t&&_e(i,"iterate",c?Cs:mt),{next(){const{value:d,done:m}=f.next();return m?{value:d,done:m}:{value:l?[a(d[0]),a(d[1])]:a(d),done:m}},[Symbol.iterator](){return this}}}}function dn(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function xl(e,t){const n={get(r){const i=this.__v_raw,o=z(i),l=z(r);e||(it(r,l)&&_e(o,"get",r),_e(o,"get",l));const{has:c}=un(o),f=t?As:e?On:pe;if(c.call(o,r))return f(i.get(r));if(c.call(o,l))return f(i.get(l));i!==o&&i.get(r)},get size(){const r=this.__v_raw;return!e&&_e(z(r),"iterate",mt),Reflect.get(r,"size",r)},has(r){const i=this.__v_raw,o=z(i),l=z(r);return e||(it(r,l)&&_e(o,"has",r),_e(o,"has",l)),r===l?i.has(r):i.has(r)||i.has(l)},forEach(r,i){const o=this,l=o.__v_raw,c=z(l),f=t?As:e?On:pe;return!e&&_e(c,"iterate",mt),l.forEach((a,d)=>r.call(i,f(a),f(d),o))}};return he(n,e?{add:dn("add"),set:dn("set"),delete:dn("delete"),clear:dn("clear")}:{add(r){!t&&!Le(r)&&!ot(r)&&(r=z(r));const i=z(this);return un(i).has.call(i,r)||(i.add(r),Xe(i,"add",r,r)),this},set(r,i){!t&&!Le(i)&&!ot(i)&&(i=z(i));const o=z(this),{has:l,get:c}=un(o);let f=l.call(o,r);f||(r=z(r),f=l.call(o,r));const a=c.call(o,r);return o.set(r,i),f?it(i,a)&&Xe(o,"set",r,i):Xe(o,"add",r,i),this},delete(r){const i=z(this),{has:o,get:l}=un(i);let c=o.call(i,r);c||(r=z(r),c=o.call(i,r)),l&&l.call(i,r);const f=i.delete(r);return c&&Xe(i,"delete",r,void 0),f},clear(){const r=z(this),i=r.size!==0,o=r.clear();return i&&Xe(r,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=Tl(r,e,t)}),n}function Xs(e,t){const n=xl(e,t);return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(Q(n,r)&&r in s?n:s,r,i)}const El={get:Xs(!1,!1)},Cl={get:Xs(!1,!0)},Al={get:Xs(!0,!1)};const Oi=new WeakMap,Pi=new WeakMap,Li=new WeakMap,Rl=new WeakMap;function Ml(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Ol(e){return e.__v_skip||!Object.isExtensible(e)?0:Ml(Zo(e))}function Nt(e){return ot(e)?e:Ys(e,!1,bl,El,Oi)}function Pl(e){return Ys(e,!1,Sl,Cl,Pi)}function Wn(e){return Ys(e,!0,wl,Al,Li)}function Ys(e,t,n,s,r){if(!se(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=Ol(e);if(i===0)return e;const o=r.get(e);if(o)return o;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function vt(e){return ot(e)?vt(e.__v_raw):!!(e&&e.__v_isReactive)}function ot(e){return!!(e&&e.__v_isReadonly)}function Le(e){return!!(e&&e.__v_isShallow)}function Js(e){return e?!!e.__v_raw:!1}function z(e){const t=e&&e.__v_raw;return t?z(t):e}function xn(e){return!Q(e,"__v_skip")&&Object.isExtensible(e)&&Ts(e,"__v_skip",!0),e}const pe=e=>se(e)?Nt(e):e,On=e=>se(e)?Wn(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function De(e){return Ii(e,!1)}function Ee(e){return Ii(e,!0)}function Ii(e,t){return fe(e)?e:new Ll(e,t)}class Ll{constructor(t,n){this.dep=new kn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:z(t),this._value=n?t:pe(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||Le(t)||ot(t);t=s?t:z(t),it(t,n)&&(this._rawValue=t,this._value=s?t:pe(t),this.dep.trigger())}}function zs(e){return fe(e)?e.value:e}function ce(e){return q(e)?e():zs(e)}const Il={get:(e,t,n)=>t==="__v_raw"?e:zs(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return fe(r)&&!fe(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Ni(e){return vt(e)?e:new Proxy(e,Il)}class Nl{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new kn,{get:s,set:r}=t(n.track.bind(n),n.trigger.bind(n));this._get=s,this._set=r}get value(){return this._value=this._get()}set value(t){this._set(t)}}function Fl(e){return new Nl(e)}class Hl{constructor(t,n,s){this._object=t,this._key=n,this._defaultValue=s,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return pl(z(this._object),this._key)}}class Dl{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function $l(e,t,n){return fe(e)?e:q(e)?new Dl(e):se(e)&&arguments.length>1?jl(e,t,n):De(e)}function jl(e,t,n){const s=e[t];return fe(s)?s:new Hl(e,t,n)}class Vl{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new kn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Yt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&ne!==this)return wi(this,!0),!0}get value(){const t=this.dep.track();return xi(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function kl(e,t,n=!1){let s,r;return q(e)?s=e:(s=e.get,r=e.set),new Vl(s,r,n)}const hn={},Pn=new WeakMap;let pt;function Ul(e,t=!1,n=pt){if(n){let s=Pn.get(n);s||Pn.set(n,s=[]),s.push(e)}}function Wl(e,t,n=ee){const{immediate:s,deep:r,once:i,scheduler:o,augmentJob:l,call:c}=n,f=g=>r?g:Le(g)||r===!1||r===0?Ye(g,1):Ye(g);let a,d,m,v,b=!1,_=!1;if(fe(e)?(d=()=>e.value,b=Le(e)):vt(e)?(d=()=>f(e),b=!0):K(e)?(_=!0,b=e.some(g=>vt(g)||Le(g)),d=()=>e.map(g=>{if(fe(g))return g.value;if(vt(g))return f(g);if(q(g))return c?c(g,2):g()})):q(e)?t?d=c?()=>c(e,2):e:d=()=>{if(m){Je();try{m()}finally{ze()}}const g=pt;pt=a;try{return c?c(e,3,[v]):e(v)}finally{pt=g}}:d=Be,t&&r){const g=d,O=r===!0?1/0:r;d=()=>Ye(g(),O)}const U=yi(),P=()=>{a.stop(),U&&U.active&&ks(U.effects,a)};if(i&&t){const g=t;t=(...O)=>{g(...O),P()}}let j=_?new Array(e.length).fill(hn):hn;const p=g=>{if(!(!(a.flags&1)||!a.dirty&&!g))if(t){const O=a.run();if(r||b||(_?O.some((D,R)=>it(D,j[R])):it(O,j))){m&&m();const D=pt;pt=a;try{const R=[O,j===hn?void 0:_&&j[0]===hn?[]:j,v];j=O,c?c(t,3,R):t(...R)}finally{pt=D}}}else a.run()};return l&&l(p),a=new _i(d),a.scheduler=o?()=>o(p,!1):p,v=g=>Ul(g,!1,a),m=a.onStop=()=>{const g=Pn.get(a);if(g){if(c)c(g,4);else for(const O of g)O();Pn.delete(a)}},t?s?p(!0):j=a.run():o?o(p.bind(null,!0),!0):a.run(),P.pause=a.pause.bind(a),P.resume=a.resume.bind(a),P.stop=P,P}function Ye(e,t=1/0,n){if(t<=0||!se(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,fe(e))Ye(e.value,t,n);else if(K(e))for(let s=0;s{Ye(s,t,n)});else if(pi(e)){for(const s in e)Ye(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Ye(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.17 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function sn(e,t,n,s){try{return s?e(...s):e()}catch(r){rn(r,t,n)}}function $e(e,t,n,s){if(q(e)){const r=sn(e,t,n,s);return r&&di(r)&&r.catch(i=>{rn(i,t,n)}),r}if(K(e)){const r=[];for(let i=0;i>>1,r=Se[s],i=zt(r);i=zt(n)?Se.push(e):Se.splice(Kl(t),0,e),e.flags|=1,Hi()}}function Hi(){Ln||(Ln=Fi.then(Di))}function ql(e){K(e)?Lt.push(...e):nt&&e.id===-1?nt.splice(Ct+1,0,e):e.flags&1||(Lt.push(e),e.flags|=1),Hi()}function vr(e,t,n=Ue+1){for(;nzt(n)-zt(s));if(Lt.length=0,nt){nt.push(...t);return}for(nt=t,Ct=0;Cte.id==null?e.flags&2?-1:1/0:e.id;function Di(e){try{for(Ue=0;Ue{s._d&&Lr(-1);const i=Nn(t);let o;try{o=e(...r)}finally{Nn(i),s._d&&Lr(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function Pf(e,t){if(de===null)return e;const n=Yn(de),s=e.dirs||(e.dirs=[]);for(let r=0;re.__isTeleport,Bt=e=>e&&(e.disabled||e.disabled===""),yr=e=>e&&(e.defer||e.defer===""),_r=e=>typeof SVGElement<"u"&&e instanceof SVGElement,br=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Rs=(e,t)=>{const n=e&&e.to;return le(n)?t?t(n):null:n},ki={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,i,o,l,c,f){const{mc:a,pc:d,pbc:m,o:{insert:v,querySelector:b,createText:_,createComment:U}}=f,P=Bt(t.props);let{shapeFlag:j,children:p,dynamicChildren:g}=t;if(e==null){const O=t.el=_(""),D=t.anchor=_("");v(O,n,s),v(D,n,s);const R=(T,M)=>{j&16&&(r&&r.isCE&&(r.ce._teleportTarget=T),a(p,T,M,r,i,o,l,c))},V=()=>{const T=t.target=Rs(t.props,b),M=Ui(T,t,_,v);T&&(o!=="svg"&&_r(T)?o="svg":o!=="mathml"&&br(T)&&(o="mathml"),P||(R(T,M),En(t,!1)))};P&&(R(n,D),En(t,!0)),yr(t.props)?(t.el.__isMounted=!1,we(()=>{V(),delete t.el.__isMounted},i)):V()}else{if(yr(t.props)&&e.el.__isMounted===!1){we(()=>{ki.process(e,t,n,s,r,i,o,l,c,f)},i);return}t.el=e.el,t.targetStart=e.targetStart;const O=t.anchor=e.anchor,D=t.target=e.target,R=t.targetAnchor=e.targetAnchor,V=Bt(e.props),T=V?n:D,M=V?O:R;if(o==="svg"||_r(D)?o="svg":(o==="mathml"||br(D))&&(o="mathml"),g?(m(e.dynamicChildren,g,T,r,i,o,l),sr(e,t,!0)):c||d(e,t,T,M,r,i,o,l,!1),P)V?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):pn(t,n,O,f,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const A=t.target=Rs(t.props,b);A&&pn(t,A,null,f,0)}else V&&pn(t,D,R,f,1);En(t,P)}},remove(e,t,n,{um:s,o:{remove:r}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:f,targetAnchor:a,target:d,props:m}=e;if(d&&(r(f),r(a)),i&&r(c),o&16){const v=i||!Bt(m);for(let b=0;b{e.isMounted=!0}),Yi(()=>{e.isUnmounting=!0}),e}const Me=[Function,Array],Wi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Me,onEnter:Me,onAfterEnter:Me,onEnterCancelled:Me,onBeforeLeave:Me,onLeave:Me,onAfterLeave:Me,onLeaveCancelled:Me,onBeforeAppear:Me,onAppear:Me,onAfterAppear:Me,onAppearCancelled:Me},Bi=e=>{const t=e.subTree;return t.component?Bi(t.component):t},Jl={name:"BaseTransition",props:Wi,setup(e,{slots:t}){const n=ln(),s=Yl();return()=>{const r=t.default&&Gi(t.default(),!0);if(!r||!r.length)return;const i=Ki(r),o=z(e),{mode:l}=o;if(s.isLeaving)return rs(i);const c=wr(i);if(!c)return rs(i);let f=Ms(c,o,s,n,d=>f=d);c.type!==ge&&Qt(c,f);let a=n.subTree&&wr(n.subTree);if(a&&a.type!==ge&&!gt(c,a)&&Bi(n).type!==ge){let d=Ms(a,o,s,n);if(Qt(a,d),l==="out-in"&&c.type!==ge)return s.isLeaving=!0,d.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete d.afterLeave,a=void 0},rs(i);l==="in-out"&&c.type!==ge?d.delayLeave=(m,v,b)=>{const _=qi(s,a);_[String(a.key)]=a,m[st]=()=>{v(),m[st]=void 0,delete f.delayedLeave,a=void 0},f.delayedLeave=()=>{b(),delete f.delayedLeave,a=void 0}}:a=void 0}else a&&(a=void 0);return i}}};function Ki(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ge){t=n;break}}return t}const zl=Jl;function qi(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Ms(e,t,n,s,r){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:f,onAfterEnter:a,onEnterCancelled:d,onBeforeLeave:m,onLeave:v,onAfterLeave:b,onLeaveCancelled:_,onBeforeAppear:U,onAppear:P,onAfterAppear:j,onAppearCancelled:p}=t,g=String(e.key),O=qi(n,e),D=(T,M)=>{T&&$e(T,s,9,M)},R=(T,M)=>{const A=M[1];D(T,M),K(T)?T.every(w=>w.length<=1)&&A():T.length<=1&&A()},V={mode:o,persisted:l,beforeEnter(T){let M=c;if(!n.isMounted)if(i)M=U||c;else return;T[st]&&T[st](!0);const A=O[g];A&>(e,A)&&A.el[st]&&A.el[st](),D(M,[T])},enter(T){let M=f,A=a,w=d;if(!n.isMounted)if(i)M=P||f,A=j||a,w=p||d;else return;let F=!1;const Y=T[gn]=ie=>{F||(F=!0,ie?D(w,[T]):D(A,[T]),V.delayedLeave&&V.delayedLeave(),T[gn]=void 0)};M?R(M,[T,Y]):Y()},leave(T,M){const A=String(e.key);if(T[gn]&&T[gn](!0),n.isUnmounting)return M();D(m,[T]);let w=!1;const F=T[st]=Y=>{w||(w=!0,M(),Y?D(_,[T]):D(b,[T]),T[st]=void 0,O[A]===e&&delete O[A])};O[A]=e,v?R(v,[T,F]):F()},clone(T){const M=Ms(T,t,n,s,r);return r&&r(M),M}};return V}function rs(e){if(on(e))return e=lt(e),e.children=null,e}function wr(e){if(!on(e))return Vi(e.type)&&e.children?Ki(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&q(n.default))return n.default()}}function Qt(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Qt(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Gi(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;iIt(b,t&&(K(t)?t[_]:t),n,s,r));return}if(yt(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&It(e,t,n,s.component.subTree);return}const i=s.shapeFlag&4?Yn(s.component):s.el,o=r?null:i,{i:l,r:c}=e,f=t&&t.r,a=l.refs===ee?l.refs={}:l.refs,d=l.setupState,m=z(d),v=d===ee?()=>!1:b=>Q(m,b);if(f!=null&&f!==c&&(le(f)?(a[f]=null,v(f)&&(d[f]=null)):fe(f)&&(f.value=null)),q(c))sn(c,l,12,[o,a]);else{const b=le(c),_=fe(c);if(b||_){const U=()=>{if(e.f){const P=b?v(c)?d[c]:a[c]:c.value;r?K(P)&&ks(P,i):K(P)?P.includes(i)||P.push(i):b?(a[c]=[i],v(c)&&(d[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else b?(a[c]=o,v(c)&&(d[c]=o)):_&&(c.value=o,e.k&&(a[e.k]=o))};o?(U.id=-1,we(U,n)):U()}}}let Sr=!1;const Et=()=>{Sr||(console.error("Hydration completed but contains mismatches."),Sr=!0)},Ql=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Zl=e=>e.namespaceURI.includes("MathML"),mn=e=>{if(e.nodeType===1){if(Ql(e))return"svg";if(Zl(e))return"mathml"}},Rt=e=>e.nodeType===8;function ec(e){const{mt:t,p:n,o:{patchProp:s,createText:r,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:f}}=e,a=(p,g)=>{if(!g.hasChildNodes()){n(null,p,g),In(),g._vnode=p;return}d(g.firstChild,p,null,null,null),In(),g._vnode=p},d=(p,g,O,D,R,V=!1)=>{V=V||!!g.dynamicChildren;const T=Rt(p)&&p.data==="[",M=()=>_(p,g,O,D,R,T),{type:A,ref:w,shapeFlag:F,patchFlag:Y}=g;let ie=p.nodeType;g.el=p,Y===-2&&(V=!1,g.dynamicChildren=null);let W=null;switch(A){case wt:ie!==3?g.children===""?(c(g.el=r(""),o(p),p),W=p):W=M():(p.data!==g.children&&(Et(),p.data=g.children),W=i(p));break;case ge:j(p)?(W=i(p),P(g.el=p.content.firstChild,p,O)):ie!==8||T?W=M():W=i(p);break;case qt:if(T&&(p=i(p),ie=p.nodeType),ie===1||ie===3){W=p;const X=!g.children.length;for(let $=0;${V=V||!!g.dynamicChildren;const{type:T,props:M,patchFlag:A,shapeFlag:w,dirs:F,transition:Y}=g,ie=T==="input"||T==="option";if(ie||A!==-1){F&&We(g,null,O,"created");let W=!1;if(j(p)){W=po(null,Y)&&O&&O.vnode.props&&O.vnode.props.appear;const $=p.content.firstChild;if(W){const oe=$.getAttribute("class");oe&&($.$cls=oe),Y.beforeEnter($)}P($,p,O),g.el=p=$}if(w&16&&!(M&&(M.innerHTML||M.textContent))){let $=v(p.firstChild,g,p,O,D,R,V);for(;$;){vn(p,1)||Et();const oe=$;$=$.nextSibling,l(oe)}}else if(w&8){let $=g.children;$[0]===` +`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&($=$.slice(1)),p.textContent!==$&&(vn(p,0)||Et(),p.textContent=g.children)}if(M){if(ie||!V||A&48){const $=p.tagName.includes("-");for(const oe in M)(ie&&(oe.endsWith("value")||oe==="indeterminate")||nn(oe)&&!Pt(oe)||oe[0]==="."||$)&&s(p,oe,null,M[oe],void 0,O)}else if(M.onClick)s(p,"onClick",null,M.onClick,void 0,O);else if(A&4&&vt(M.style))for(const $ in M.style)M.style[$]}let X;(X=M&&M.onVnodeBeforeMount)&&Oe(X,O,g),F&&We(g,null,O,"beforeMount"),((X=M&&M.onVnodeMounted)||F||W)&&bo(()=>{X&&Oe(X,O,g),W&&Y.enter(p),F&&We(g,null,O,"mounted")},D)}return p.nextSibling},v=(p,g,O,D,R,V,T)=>{T=T||!!g.dynamicChildren;const M=g.children,A=M.length;for(let w=0;w{const{slotScopeIds:T}=g;T&&(R=R?R.concat(T):T);const M=o(p),A=v(i(p),g,M,O,D,R,V);return A&&Rt(A)&&A.data==="]"?i(g.anchor=A):(Et(),c(g.anchor=f("]"),M,A),A)},_=(p,g,O,D,R,V)=>{if(vn(p.parentElement,1)||Et(),g.el=null,V){const A=U(p);for(;;){const w=i(p);if(w&&w!==A)l(w);else break}}const T=i(p),M=o(p);return l(p),n(null,g,M,T,O,D,mn(M),R),O&&(O.vnode.el=g.el,yo(O,g.el)),T},U=(p,g="[",O="]")=>{let D=0;for(;p;)if(p=i(p),p&&Rt(p)&&(p.data===g&&D++,p.data===O)){if(D===0)return i(p);D--}return p},P=(p,g,O)=>{const D=g.parentNode;D&&D.replaceChild(p,g);let R=O;for(;R;)R.vnode.el===g&&(R.vnode.el=R.subTree.el=p),R=R.parent},j=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,d]}const Tr="data-allow-mismatch",tc={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function vn(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(Tr);)e=e.parentElement;const n=e&&e.getAttribute(Tr);if(n==null)return!1;if(n==="")return!0;{const s=n.split(",");return t===0&&s.includes("children")?!0:s.includes(tc[t])}}Vn().requestIdleCallback;Vn().cancelIdleCallback;function nc(e,t){if(Rt(e)&&e.data==="["){let n=1,s=e.nextSibling;for(;s;){if(s.nodeType===1){if(t(s)===!1)break}else if(Rt(s))if(s.data==="]"){if(--n===0)break}else s.data==="["&&n++;s=s.nextSibling}}else t(e)}const yt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function If(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:s,delay:r=200,hydrate:i,timeout:o,suspensible:l=!0,onError:c}=e;let f=null,a,d=0;const m=()=>(d++,f=null,v()),v=()=>{let b;return f||(b=f=t().catch(_=>{if(_=_ instanceof Error?_:new Error(String(_)),c)return new Promise((U,P)=>{c(_,()=>U(m()),()=>P(_),d+1)});throw _}).then(_=>b!==f&&f?f:(_&&(_.__esModule||_[Symbol.toStringTag]==="Module")&&(_=_.default),a=_,_)))};return Zs({name:"AsyncComponentWrapper",__asyncLoader:v,__asyncHydrate(b,_,U){const P=i?()=>{const p=i(()=>{U()},g=>nc(b,g));p&&(_.bum||(_.bum=[])).push(p),(_.u||(_.u=[])).push(()=>!0)}:U;a?P():v().then(()=>!_.isUnmounted&&P())},get __asyncResolved(){return a},setup(){const b=ue;if(er(b),a)return()=>is(a,b);const _=p=>{f=null,rn(p,b,13,!s)};if(l&&b.suspense||Ft)return v().then(p=>()=>is(p,b)).catch(p=>(_(p),()=>s?ae(s,{error:p}):null));const U=De(!1),P=De(),j=De(!!r);return r&&setTimeout(()=>{j.value=!1},r),o!=null&&setTimeout(()=>{if(!U.value&&!P.value){const p=new Error(`Async component timed out after ${o}ms.`);_(p),P.value=p}},o),v().then(()=>{U.value=!0,b.parent&&on(b.parent.vnode)&&b.parent.update()}).catch(p=>{_(p),P.value=p}),()=>{if(U.value&&a)return is(a,b);if(P.value&&s)return ae(s,{error:P.value});if(n&&!j.value)return ae(n)}}})}function is(e,t){const{ref:n,props:s,children:r,ce:i}=t.vnode,o=ae(e,s,r);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const on=e=>e.type.__isKeepAlive;function sc(e,t){Xi(e,"a",t)}function rc(e,t){Xi(e,"da",t)}function Xi(e,t,n=ue){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Kn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)on(r.parent.vnode)&&ic(s,t,n,r),r=r.parent}}function ic(e,t,n,s){const r=Kn(t,e,s,!0);qn(()=>{ks(s[t],r)},n)}function Kn(e,t,n=ue,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{Je();const l=cn(n),c=$e(t,n,e,o);return l(),ze(),c});return s?r.unshift(i):r.push(i),i}}const et=e=>(t,n=ue)=>{(!Ft||e==="sp")&&Kn(e,(...s)=>t(...s),n)},oc=et("bm"),Ht=et("m"),lc=et("bu"),cc=et("u"),Yi=et("bum"),qn=et("um"),ac=et("sp"),fc=et("rtg"),uc=et("rtc");function dc(e,t=ue){Kn("ec",e,t)}const Ji="components";function Nf(e,t){return Qi(Ji,e,!0,t)||e}const zi=Symbol.for("v-ndc");function Ff(e){return le(e)?Qi(Ji,e,!1)||e:e||zi}function Qi(e,t,n=!0,s=!1){const r=de||ue;if(r){const i=r.type;{const l=Jc(i,!1);if(l&&(l===t||l===Ne(t)||l===jn(Ne(t))))return i}const o=xr(r[e]||i[e],t)||xr(r.appContext[e],t);return!o&&s?i:o}}function xr(e,t){return e&&(e[t]||e[Ne(t)]||e[jn(Ne(t))])}function Hf(e,t,n,s){let r;const i=n,o=K(e);if(o||le(e)){const l=o&&vt(e);let c=!1,f=!1;l&&(c=!Le(e),f=ot(e),e=Un(e)),r=new Array(e.length);for(let a=0,d=e.length;at(l,c,void 0,i));else{const l=Object.keys(e);r=new Array(l.length);for(let c=0,f=l.length;cen(t)?!(t.type===ge||t.type===Te&&!Zi(t.children)):!0)?e:null}function $f(e,t){const n={};for(const s in e)n[/[A-Z]/.test(s)?`on:${s}`:Sn(s)]=e[s];return n}const Os=e=>e?Eo(e)?Yn(e):Os(e.parent):null,Kt=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Os(e.parent),$root:e=>Os(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>to(e),$forceUpdate:e=>e.f||(e.f=()=>{Qs(e.update)}),$nextTick:e=>e.n||(e.n=Bn.bind(e.proxy)),$watch:e=>Nc.bind(e)}),os=(e,t)=>e!==ee&&!e.__isScriptSetup&&Q(e,t),hc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const v=o[t];if(v!==void 0)switch(v){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(os(s,t))return o[t]=1,s[t];if(r!==ee&&Q(r,t))return o[t]=2,r[t];if((f=e.propsOptions[0])&&Q(f,t))return o[t]=3,i[t];if(n!==ee&&Q(n,t))return o[t]=4,n[t];Ps&&(o[t]=0)}}const a=Kt[t];let d,m;if(a)return t==="$attrs"&&_e(e.attrs,"get",""),a(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==ee&&Q(n,t))return o[t]=4,n[t];if(m=c.config.globalProperties,Q(m,t))return m[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return os(r,t)?(r[t]=n,!0):s!==ee&&Q(s,t)?(s[t]=n,!0):Q(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==ee&&Q(e,o)||os(t,o)||(l=i[0])&&Q(l,o)||Q(s,o)||Q(Kt,o)||Q(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Q(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function jf(){return pc().slots}function pc(){const e=ln();return e.setupContext||(e.setupContext=Ao(e))}function Er(e){return K(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ps=!0;function gc(e){const t=to(e),n=e.proxy,s=e.ctx;Ps=!1,t.beforeCreate&&Cr(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:c,inject:f,created:a,beforeMount:d,mounted:m,beforeUpdate:v,updated:b,activated:_,deactivated:U,beforeDestroy:P,beforeUnmount:j,destroyed:p,unmounted:g,render:O,renderTracked:D,renderTriggered:R,errorCaptured:V,serverPrefetch:T,expose:M,inheritAttrs:A,components:w,directives:F,filters:Y}=t;if(f&&mc(f,s,null),o)for(const X in o){const $=o[X];q($)&&(s[X]=$.bind(n))}if(r){const X=r.call(n,n);se(X)&&(e.data=Nt(X))}if(Ps=!0,i)for(const X in i){const $=i[X],oe=q($)?$.bind(n,n):q($.get)?$.get.bind(n,n):Be,an=!q($)&&q($.set)?$.set.bind(n):Be,ft=re({get:oe,set:an});Object.defineProperty(s,X,{enumerable:!0,configurable:!0,get:()=>ft.value,set:Ve=>ft.value=Ve})}if(l)for(const X in l)eo(l[X],s,n,X);if(c){const X=q(c)?c.call(n):c;Reflect.ownKeys(X).forEach($=>{Sc($,X[$])})}a&&Cr(a,e,"c");function W(X,$){K($)?$.forEach(oe=>X(oe.bind(n))):$&&X($.bind(n))}if(W(oc,d),W(Ht,m),W(lc,v),W(cc,b),W(sc,_),W(rc,U),W(dc,V),W(uc,D),W(fc,R),W(Yi,j),W(qn,g),W(ac,T),K(M))if(M.length){const X=e.exposed||(e.exposed={});M.forEach($=>{Object.defineProperty(X,$,{get:()=>n[$],set:oe=>n[$]=oe})})}else e.exposed||(e.exposed={});O&&e.render===Be&&(e.render=O),A!=null&&(e.inheritAttrs=A),w&&(e.components=w),F&&(e.directives=F),T&&er(e)}function mc(e,t,n=Be){K(e)&&(e=Ls(e));for(const s in e){const r=e[s];let i;se(r)?"default"in r?i=bt(r.from||s,r.default,!0):i=bt(r.from||s):i=bt(r),fe(i)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[s]=i}}function Cr(e,t,n){$e(K(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function eo(e,t,n,s){let r=s.includes(".")?mo(n,s):()=>n[s];if(le(e)){const i=t[e];q(i)&&Ie(r,i)}else if(q(e))Ie(r,e.bind(n));else if(se(e))if(K(e))e.forEach(i=>eo(i,t,n,s));else{const i=q(e.handler)?e.handler.bind(n):t[e.handler];q(i)&&Ie(r,i,e)}}function to(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Fn(c,f,o,!0)),Fn(c,t,o)),se(t)&&i.set(t,c),c}function Fn(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&Fn(e,i,n,!0),r&&r.forEach(o=>Fn(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=vc[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const vc={data:Ar,props:Rr,emits:Rr,methods:kt,computed:kt,beforeCreate:be,created:be,beforeMount:be,mounted:be,beforeUpdate:be,updated:be,beforeDestroy:be,beforeUnmount:be,destroyed:be,unmounted:be,activated:be,deactivated:be,errorCaptured:be,serverPrefetch:be,components:kt,directives:kt,watch:_c,provide:Ar,inject:yc};function Ar(e,t){return t?e?function(){return he(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function yc(e,t){return kt(Ls(e),Ls(t))}function Ls(e){if(K(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(s&&s.proxy):t}}function so(){return!!(ue||de||_t)}const ro={},io=()=>Object.create(ro),oo=e=>Object.getPrototypeOf(e)===ro;function Tc(e,t,n,s=!1){const r={},i=io();e.propsDefaults=Object.create(null),lo(e,t,r,i);for(const o in e.propsOptions[0])o in r||(r[o]=void 0);n?e.props=s?r:Pl(r):e.type.props?e.props=r:e.props=i,e.attrs=i}function xc(e,t,n,s){const{props:r,attrs:i,vnode:{patchFlag:o}}=e,l=z(r),[c]=e.propsOptions;let f=!1;if((s||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let d=0;d{c=!0;const[m,v]=co(d,t,!0);he(o,m),v&&l.push(...v)};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!i&&!c)return se(e)&&s.set(e,Mt),Mt;if(K(i))for(let a=0;ae[0]==="_"||e==="$stable",nr=e=>K(e)?e.map(Pe):[Pe(e)],Cc=(e,t,n)=>{if(t._n)return t;const s=Gl((...r)=>nr(t(...r)),n);return s._c=!1,s},ao=(e,t,n)=>{const s=e._ctx;for(const r in e){if(tr(r))continue;const i=e[r];if(q(i))t[r]=Cc(r,i,s);else if(i!=null){const o=nr(i);t[r]=()=>o}}},fo=(e,t)=>{const n=nr(t);e.slots.default=()=>n},uo=(e,t,n)=>{for(const s in t)(n||!tr(s))&&(e[s]=t[s])},Ac=(e,t,n)=>{const s=e.slots=io();if(e.vnode.shapeFlag&32){const r=t.__;r&&Ts(s,"__",r,!0);const i=t._;i?(uo(s,t,n),n&&Ts(s,"_",i,!0)):ao(t,s)}else t&&fo(e,t)},Rc=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=ee;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:uo(r,t,n):(i=!t.$stable,ao(t,r)),o=t}else t&&(fo(e,t),o={default:1});if(i)for(const l in r)!tr(l)&&o[l]==null&&delete r[l]},we=bo;function Mc(e){return ho(e)}function Oc(e){return ho(e,ec)}function ho(e,t){const n=Vn();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:c,setText:f,setElementText:a,parentNode:d,nextSibling:m,setScopeId:v=Be,insertStaticContent:b}=e,_=(u,h,y,E=null,S=null,x=null,N=void 0,I=null,L=!!h.dynamicChildren)=>{if(u===h)return;u&&!gt(u,h)&&(E=fn(u),Ve(u,S,x,!0),u=null),h.patchFlag===-2&&(L=!1,h.dynamicChildren=null);const{type:C,ref:B,shapeFlag:H}=h;switch(C){case wt:U(u,h,y,E);break;case ge:P(u,h,y,E);break;case qt:u==null&&j(h,y,E,N);break;case Te:w(u,h,y,E,S,x,N,I,L);break;default:H&1?O(u,h,y,E,S,x,N,I,L):H&6?F(u,h,y,E,S,x,N,I,L):(H&64||H&128)&&C.process(u,h,y,E,S,x,N,I,L,Tt)}B!=null&&S?It(B,u&&u.ref,x,h||u,!h):B==null&&u&&u.ref!=null&&It(u.ref,null,x,u,!0)},U=(u,h,y,E)=>{if(u==null)s(h.el=l(h.children),y,E);else{const S=h.el=u.el;h.children!==u.children&&f(S,h.children)}},P=(u,h,y,E)=>{u==null?s(h.el=c(h.children||""),y,E):h.el=u.el},j=(u,h,y,E)=>{[u.el,u.anchor]=b(u.children,h,y,E,u.el,u.anchor)},p=({el:u,anchor:h},y,E)=>{let S;for(;u&&u!==h;)S=m(u),s(u,y,E),u=S;s(h,y,E)},g=({el:u,anchor:h})=>{let y;for(;u&&u!==h;)y=m(u),r(u),u=y;r(h)},O=(u,h,y,E,S,x,N,I,L)=>{h.type==="svg"?N="svg":h.type==="math"&&(N="mathml"),u==null?D(h,y,E,S,x,N,I,L):T(u,h,S,x,N,I,L)},D=(u,h,y,E,S,x,N,I)=>{let L,C;const{props:B,shapeFlag:H,transition:k,dirs:G}=u;if(L=u.el=o(u.type,x,B&&B.is,B),H&8?a(L,u.children):H&16&&V(u.children,L,null,E,S,ls(u,x),N,I),G&&We(u,null,E,"created"),R(L,u,u.scopeId,N,E),B){for(const te in B)te!=="value"&&!Pt(te)&&i(L,te,null,B[te],x,E);"value"in B&&i(L,"value",null,B.value,x),(C=B.onVnodeBeforeMount)&&Oe(C,E,u)}G&&We(u,null,E,"beforeMount");const J=po(S,k);J&&k.beforeEnter(L),s(L,h,y),((C=B&&B.onVnodeMounted)||J||G)&&we(()=>{C&&Oe(C,E,u),J&&k.enter(L),G&&We(u,null,E,"mounted")},S)},R=(u,h,y,E,S)=>{if(y&&v(u,y),E)for(let x=0;x{for(let C=L;C{const I=h.el=u.el;let{patchFlag:L,dynamicChildren:C,dirs:B}=h;L|=u.patchFlag&16;const H=u.props||ee,k=h.props||ee;let G;if(y&&ut(y,!1),(G=k.onVnodeBeforeUpdate)&&Oe(G,y,h,u),B&&We(h,u,y,"beforeUpdate"),y&&ut(y,!0),(H.innerHTML&&k.innerHTML==null||H.textContent&&k.textContent==null)&&a(I,""),C?M(u.dynamicChildren,C,I,y,E,ls(h,S),x):N||$(u,h,I,null,y,E,ls(h,S),x,!1),L>0){if(L&16)A(I,H,k,y,S);else if(L&2&&H.class!==k.class&&i(I,"class",null,k.class,S),L&4&&i(I,"style",H.style,k.style,S),L&8){const J=h.dynamicProps;for(let te=0;te{G&&Oe(G,y,h,u),B&&We(h,u,y,"updated")},E)},M=(u,h,y,E,S,x,N)=>{for(let I=0;I{if(h!==y){if(h!==ee)for(const x in h)!Pt(x)&&!(x in y)&&i(u,x,h[x],null,S,E);for(const x in y){if(Pt(x))continue;const N=y[x],I=h[x];N!==I&&x!=="value"&&i(u,x,I,N,S,E)}"value"in y&&i(u,"value",h.value,y.value,S)}},w=(u,h,y,E,S,x,N,I,L)=>{const C=h.el=u?u.el:l(""),B=h.anchor=u?u.anchor:l("");let{patchFlag:H,dynamicChildren:k,slotScopeIds:G}=h;G&&(I=I?I.concat(G):G),u==null?(s(C,y,E),s(B,y,E),V(h.children||[],y,B,S,x,N,I,L)):H>0&&H&64&&k&&u.dynamicChildren?(M(u.dynamicChildren,k,y,S,x,N,I),(h.key!=null||S&&h===S.subTree)&&sr(u,h,!0)):$(u,h,y,B,S,x,N,I,L)},F=(u,h,y,E,S,x,N,I,L)=>{h.slotScopeIds=I,u==null?h.shapeFlag&512?S.ctx.activate(h,y,E,N,L):Y(h,y,E,S,x,N,L):ie(u,h,L)},Y=(u,h,y,E,S,x,N)=>{const I=u.component=qc(u,E,S);if(on(u)&&(I.ctx.renderer=Tt),Gc(I,!1,N),I.asyncDep){if(S&&S.registerDep(I,W,N),!u.el){const L=I.subTree=ae(ge);P(null,L,h,y)}}else W(I,u,h,y,S,x,N)},ie=(u,h,y)=>{const E=h.component=u.component;if(jc(u,h,y))if(E.asyncDep&&!E.asyncResolved){X(E,h,y);return}else E.next=h,E.update();else h.el=u.el,E.vnode=h},W=(u,h,y,E,S,x,N)=>{const I=()=>{if(u.isMounted){let{next:H,bu:k,u:G,parent:J,vnode:te}=u;{const Ce=go(u);if(Ce){H&&(H.el=te.el,X(u,H,N)),Ce.asyncDep.then(()=>{u.isUnmounted||I()});return}}let Z=H,xe;ut(u,!1),H?(H.el=te.el,X(u,H,N)):H=te,k&&Tn(k),(xe=H.props&&H.props.onVnodeBeforeUpdate)&&Oe(xe,J,H,te),ut(u,!0);const me=cs(u),Fe=u.subTree;u.subTree=me,_(Fe,me,d(Fe.el),fn(Fe),u,S,x),H.el=me.el,Z===null&&yo(u,me.el),G&&we(G,S),(xe=H.props&&H.props.onVnodeUpdated)&&we(()=>Oe(xe,J,H,te),S)}else{let H;const{el:k,props:G}=h,{bm:J,m:te,parent:Z,root:xe,type:me}=u,Fe=yt(h);if(ut(u,!1),J&&Tn(J),!Fe&&(H=G&&G.onVnodeBeforeMount)&&Oe(H,Z,h),ut(u,!0),k&&Zn){const Ce=()=>{u.subTree=cs(u),Zn(k,u.subTree,u,S,null)};Fe&&me.__asyncHydrate?me.__asyncHydrate(k,u,Ce):Ce()}else{xe.ce&&xe.ce._def.shadowRoot!==!1&&xe.ce._injectChildStyle(me);const Ce=u.subTree=cs(u);_(null,Ce,y,E,u,S,x),h.el=Ce.el}if(te&&we(te,S),!Fe&&(H=G&&G.onVnodeMounted)){const Ce=h;we(()=>Oe(H,Z,Ce),S)}(h.shapeFlag&256||Z&&yt(Z.vnode)&&Z.vnode.shapeFlag&256)&&u.a&&we(u.a,S),u.isMounted=!0,h=y=E=null}};u.scope.on();const L=u.effect=new _i(I);u.scope.off();const C=u.update=L.run.bind(L),B=u.job=L.runIfDirty.bind(L);B.i=u,B.id=u.uid,L.scheduler=()=>Qs(B),ut(u,!0),C()},X=(u,h,y)=>{h.component=u;const E=u.vnode.props;u.vnode=h,u.next=null,xc(u,h.props,E,y),Rc(u,h.children,y),Je(),vr(u),ze()},$=(u,h,y,E,S,x,N,I,L=!1)=>{const C=u&&u.children,B=u?u.shapeFlag:0,H=h.children,{patchFlag:k,shapeFlag:G}=h;if(k>0){if(k&128){an(C,H,y,E,S,x,N,I,L);return}else if(k&256){oe(C,H,y,E,S,x,N,I,L);return}}G&8?(B&16&&Dt(C,S,x),H!==C&&a(y,H)):B&16?G&16?an(C,H,y,E,S,x,N,I,L):Dt(C,S,x,!0):(B&8&&a(y,""),G&16&&V(H,y,E,S,x,N,I,L))},oe=(u,h,y,E,S,x,N,I,L)=>{u=u||Mt,h=h||Mt;const C=u.length,B=h.length,H=Math.min(C,B);let k;for(k=0;kB?Dt(u,S,x,!0,!1,H):V(h,y,E,S,x,N,I,L,H)},an=(u,h,y,E,S,x,N,I,L)=>{let C=0;const B=h.length;let H=u.length-1,k=B-1;for(;C<=H&&C<=k;){const G=u[C],J=h[C]=L?rt(h[C]):Pe(h[C]);if(gt(G,J))_(G,J,y,null,S,x,N,I,L);else break;C++}for(;C<=H&&C<=k;){const G=u[H],J=h[k]=L?rt(h[k]):Pe(h[k]);if(gt(G,J))_(G,J,y,null,S,x,N,I,L);else break;H--,k--}if(C>H){if(C<=k){const G=k+1,J=Gk)for(;C<=H;)Ve(u[C],S,x,!0),C++;else{const G=C,J=C,te=new Map;for(C=J;C<=k;C++){const Ae=h[C]=L?rt(h[C]):Pe(h[C]);Ae.key!=null&&te.set(Ae.key,C)}let Z,xe=0;const me=k-J+1;let Fe=!1,Ce=0;const $t=new Array(me);for(C=0;C=me){Ve(Ae,S,x,!0);continue}let ke;if(Ae.key!=null)ke=te.get(Ae.key);else for(Z=J;Z<=k;Z++)if($t[Z-J]===0&>(Ae,h[Z])){ke=Z;break}ke===void 0?Ve(Ae,S,x,!0):($t[ke-J]=C+1,ke>=Ce?Ce=ke:Fe=!0,_(Ae,h[ke],y,null,S,x,N,I,L),xe++)}const dr=Fe?Pc($t):Mt;for(Z=dr.length-1,C=me-1;C>=0;C--){const Ae=J+C,ke=h[Ae],hr=Ae+1{const{el:x,type:N,transition:I,children:L,shapeFlag:C}=u;if(C&6){ft(u.component.subTree,h,y,E);return}if(C&128){u.suspense.move(h,y,E);return}if(C&64){N.move(u,h,y,Tt);return}if(N===Te){s(x,h,y);for(let H=0;HI.enter(x),S);else{const{leave:H,delayLeave:k,afterLeave:G}=I,J=()=>{u.ctx.isUnmounted?r(x):s(x,h,y)},te=()=>{H(x,()=>{J(),G&&G()})};k?k(x,J,te):te()}else s(x,h,y)},Ve=(u,h,y,E=!1,S=!1)=>{const{type:x,props:N,ref:I,children:L,dynamicChildren:C,shapeFlag:B,patchFlag:H,dirs:k,cacheIndex:G}=u;if(H===-2&&(S=!1),I!=null&&(Je(),It(I,null,y,u,!0),ze()),G!=null&&(h.renderCache[G]=void 0),B&256){h.ctx.deactivate(u);return}const J=B&1&&k,te=!yt(u);let Z;if(te&&(Z=N&&N.onVnodeBeforeUnmount)&&Oe(Z,h,u),B&6)Jo(u.component,y,E);else{if(B&128){u.suspense.unmount(y,E);return}J&&We(u,null,h,"beforeUnmount"),B&64?u.type.remove(u,h,y,Tt,E):C&&!C.hasOnce&&(x!==Te||H>0&&H&64)?Dt(C,h,y,!1,!0):(x===Te&&H&384||!S&&B&16)&&Dt(L,h,y),E&&fr(u)}(te&&(Z=N&&N.onVnodeUnmounted)||J)&&we(()=>{Z&&Oe(Z,h,u),J&&We(u,null,h,"unmounted")},y)},fr=u=>{const{type:h,el:y,anchor:E,transition:S}=u;if(h===Te){Yo(y,E);return}if(h===qt){g(u);return}const x=()=>{r(y),S&&!S.persisted&&S.afterLeave&&S.afterLeave()};if(u.shapeFlag&1&&S&&!S.persisted){const{leave:N,delayLeave:I}=S,L=()=>N(y,x);I?I(u.el,x,L):L()}else x()},Yo=(u,h)=>{let y;for(;u!==h;)y=m(u),r(u),u=y;r(h)},Jo=(u,h,y)=>{const{bum:E,scope:S,job:x,subTree:N,um:I,m:L,a:C,parent:B,slots:{__:H}}=u;Or(L),Or(C),E&&Tn(E),B&&K(H)&&H.forEach(k=>{B.renderCache[k]=void 0}),S.stop(),x&&(x.flags|=8,Ve(N,u,h,y)),I&&we(I,h),we(()=>{u.isUnmounted=!0},h),h&&h.pendingBranch&&!h.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===h.pendingId&&(h.deps--,h.deps===0&&h.resolve())},Dt=(u,h,y,E=!1,S=!1,x=0)=>{for(let N=x;N{if(u.shapeFlag&6)return fn(u.component.subTree);if(u.shapeFlag&128)return u.suspense.next();const h=m(u.anchor||u.el),y=h&&h[ji];return y?m(y):h};let zn=!1;const ur=(u,h,y)=>{u==null?h._vnode&&Ve(h._vnode,null,null,!0):_(h._vnode||null,u,h,null,null,null,y),h._vnode=u,zn||(zn=!0,vr(),In(),zn=!1)},Tt={p:_,um:Ve,m:ft,r:fr,mt:Y,mc:V,pc:$,pbc:M,n:fn,o:e};let Qn,Zn;return t&&([Qn,Zn]=t(Tt)),{render:ur,hydrate:Qn,createApp:wc(ur,Qn)}}function ls({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function ut({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function po(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function sr(e,t,n=!1){const s=e.children,r=t.children;if(K(s)&&K(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function go(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:go(t)}function Or(e){if(e)for(let t=0;tbt(Lc);function rr(e,t){return Gn(e,null,t)}function Vf(e,t){return Gn(e,null,{flush:"post"})}function Ie(e,t,n){return Gn(e,t,n)}function Gn(e,t,n=ee){const{immediate:s,deep:r,flush:i,once:o}=n,l=he({},n),c=t&&s||!t&&i!=="post";let f;if(Ft){if(i==="sync"){const v=Ic();f=v.__watcherHandles||(v.__watcherHandles=[])}else if(!c){const v=()=>{};return v.stop=Be,v.resume=Be,v.pause=Be,v}}const a=ue;l.call=(v,b,_)=>$e(v,a,b,_);let d=!1;i==="post"?l.scheduler=v=>{we(v,a&&a.suspense)}:i!=="sync"&&(d=!0,l.scheduler=(v,b)=>{b?v():Qs(v)}),l.augmentJob=v=>{t&&(v.flags|=4),d&&(v.flags|=2,a&&(v.id=a.uid,v.i=a))};const m=Wl(e,t,l);return Ft&&(f?f.push(m):c&&m()),m}function Nc(e,t,n){const s=this.proxy,r=le(e)?e.includes(".")?mo(s,e):()=>s[e]:e.bind(s,s);let i;q(t)?i=t:(i=t.handler,n=t);const o=cn(this),l=Gn(r,i.bind(s),n);return o(),l}function mo(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;rt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ne(t)}Modifiers`]||e[`${at(t)}Modifiers`];function Hc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||ee;let r=n;const i=t.startsWith("update:"),o=i&&Fc(s,t.slice(7));o&&(o.trim&&(r=n.map(a=>le(a)?a.trim():a)),o.number&&(r=n.map(xs)));let l,c=s[l=Sn(t)]||s[l=Sn(Ne(t))];!c&&i&&(c=s[l=Sn(at(t))]),c&&$e(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,$e(f,e,6,r)}}function vo(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!q(e)){const c=f=>{const a=vo(f,t,!0);a&&(l=!0,he(o,a))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(se(e)&&s.set(e,null),null):(K(i)?i.forEach(c=>o[c]=null):he(o,i),se(e)&&s.set(e,o),o)}function Xn(e,t){return!e||!nn(t)?!1:(t=t.slice(2).replace(/Once$/,""),Q(e,t[0].toLowerCase()+t.slice(1))||Q(e,at(t))||Q(e,t))}function cs(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[i],slots:o,attrs:l,emit:c,render:f,renderCache:a,props:d,data:m,setupState:v,ctx:b,inheritAttrs:_}=e,U=Nn(e);let P,j;try{if(n.shapeFlag&4){const g=r||s,O=g;P=Pe(f.call(O,g,a,d,v,m,b)),j=l}else{const g=t;P=Pe(g.length>1?g(d,{attrs:l,slots:o,emit:c}):g(d,null)),j=t.props?l:Dc(l)}}catch(g){Gt.length=0,rn(g,e,1),P=ae(ge)}let p=P;if(j&&_!==!1){const g=Object.keys(j),{shapeFlag:O}=p;g.length&&O&7&&(i&&g.some(Vs)&&(j=$c(j,i)),p=lt(p,j,!1,!0))}return n.dirs&&(p=lt(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(n.dirs):n.dirs),n.transition&&Qt(p,n.transition),P=p,Nn(U),P}const Dc=e=>{let t;for(const n in e)(n==="class"||n==="style"||nn(n))&&((t||(t={}))[n]=e[n]);return t},$c=(e,t)=>{const n={};for(const s in e)(!Vs(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function jc(e,t,n){const{props:s,children:r,component:i}=e,{props:o,children:l,patchFlag:c}=t,f=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Pr(s,o,f):!!o;if(c&8){const a=t.dynamicProps;for(let d=0;de.__isSuspense;function bo(e,t){t&&t.pendingBranch?K(e)?t.effects.push(...e):t.effects.push(e):ql(e)}const Te=Symbol.for("v-fgt"),wt=Symbol.for("v-txt"),ge=Symbol.for("v-cmt"),qt=Symbol.for("v-stc"),Gt=[];let Re=null;function Ns(e=!1){Gt.push(Re=e?null:[])}function Vc(){Gt.pop(),Re=Gt[Gt.length-1]||null}let Zt=1;function Lr(e,t=!1){Zt+=e,e<0&&Re&&t&&(Re.hasOnce=!0)}function wo(e){return e.dynamicChildren=Zt>0?Re||Mt:null,Vc(),Zt>0&&Re&&Re.push(e),e}function kf(e,t,n,s,r,i){return wo(To(e,t,n,s,r,i,!0))}function Fs(e,t,n,s,r){return wo(ae(e,t,n,s,r,!0))}function en(e){return e?e.__v_isVNode===!0:!1}function gt(e,t){return e.type===t.type&&e.key===t.key}const So=({key:e})=>e??null,Cn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?le(e)||fe(e)||q(e)?{i:de,r:e,k:t,f:!!n}:e:null);function To(e,t=null,n=null,s=0,r=null,i=e===Te?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&So(t),ref:t&&Cn(t),scopeId:$i,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:de};return l?(ir(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=le(n)?8:16),Zt>0&&!o&&Re&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Re.push(c),c}const ae=kc;function kc(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===zi)&&(e=ge),en(e)){const l=lt(e,t,!0);return n&&ir(l,n),Zt>0&&!i&&Re&&(l.shapeFlag&6?Re[Re.indexOf(e)]=l:Re.push(l)),l.patchFlag=-2,l}if(zc(e)&&(e=e.__vccOpts),t){t=Uc(t);let{class:l,style:c}=t;l&&!le(l)&&(t.class=Bs(l)),se(c)&&(Js(c)&&!K(c)&&(c=he({},c)),t.style=Ws(c))}const o=le(e)?1:_o(e)?128:Vi(e)?64:se(e)?4:q(e)?2:0;return To(e,t,n,s,r,o,i,!0)}function Uc(e){return e?Js(e)||oo(e)?he({},e):e:null}function lt(e,t,n=!1,s=!1){const{props:r,ref:i,patchFlag:o,children:l,transition:c}=e,f=t?Wc(r||{},t):r,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&So(f),ref:t&&t.ref?n&&i?K(i)?i.concat(Cn(t)):[i,Cn(t)]:Cn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Te?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&<(e.ssContent),ssFallback:e.ssFallback&<(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&s&&Qt(a,c.clone(a)),a}function xo(e=" ",t=0){return ae(wt,null,e,t)}function Uf(e,t){const n=ae(qt,null,e);return n.staticCount=t,n}function Wf(e="",t=!1){return t?(Ns(),Fs(ge,null,e)):ae(ge,null,e)}function Pe(e){return e==null||typeof e=="boolean"?ae(ge):K(e)?ae(Te,null,e.slice()):en(e)?rt(e):ae(wt,null,String(e))}function rt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:lt(e)}function ir(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(K(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),ir(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!oo(t)?t._ctx=de:r===3&&de&&(de.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else q(t)?(t={default:t,_ctx:de},n=32):(t=String(t),s&64?(n=16,t=[xo(t)]):n=8);e.children=t,e.shapeFlag|=n}function Wc(...e){const t={};for(let n=0;nue||de;let Hn,Hs;{const e=Vn(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),i=>{r.length>1?r.forEach(o=>o(i)):r[0](i)}};Hn=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Hs=t("__VUE_SSR_SETTERS__",n=>Ft=n)}const cn=e=>{const t=ue;return Hn(e),e.scope.on(),()=>{e.scope.off(),Hn(t)}},Ir=()=>{ue&&ue.scope.off(),Hn(null)};function Eo(e){return e.vnode.shapeFlag&4}let Ft=!1;function Gc(e,t=!1,n=!1){t&&Hs(t);const{props:s,children:r}=e.vnode,i=Eo(e);Tc(e,s,i,t),Ac(e,r,n||t);const o=i?Xc(e,t):void 0;return t&&Hs(!1),o}function Xc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,hc);const{setup:s}=n;if(s){Je();const r=e.setupContext=s.length>1?Ao(e):null,i=cn(e),o=sn(s,e,0,[e.props,r]),l=di(o);if(ze(),i(),(l||e.sp)&&!yt(e)&&er(e),l){if(o.then(Ir,Ir),t)return o.then(c=>{Nr(e,c)}).catch(c=>{rn(c,e,0)});e.asyncDep=o}else Nr(e,o)}else Co(e)}function Nr(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:se(t)&&(e.setupState=Ni(t)),Co(e)}function Co(e,t,n){const s=e.type;e.render||(e.render=s.render||Be);{const r=cn(e);Je();try{gc(e)}finally{ze(),r()}}}const Yc={get(e,t){return _e(e,"get",""),e[t]}};function Ao(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Yc),slots:e.slots,emit:e.emit,expose:t}}function Yn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Ni(xn(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Kt)return Kt[n](e)},has(t,n){return n in t||n in Kt}})):e.proxy}function Jc(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function zc(e){return q(e)&&"__vccOpts"in e}const re=(e,t)=>kl(e,t,Ft);function Ds(e,t,n){const s=arguments.length;return s===2?se(t)&&!K(t)?en(t)?ae(e,null,[t]):ae(e,t):ae(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&en(n)&&(n=[n]),ae(e,t,n))}const Qc="3.5.17";/** +* @vue/runtime-dom v3.5.17 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let $s;const Fr=typeof window<"u"&&window.trustedTypes;if(Fr)try{$s=Fr.createPolicy("vue",{createHTML:e=>e})}catch{}const Ro=$s?e=>$s.createHTML(e):e=>e,Zc="http://www.w3.org/2000/svg",ea="http://www.w3.org/1998/Math/MathML",Ge=typeof document<"u"?document:null,Hr=Ge&&Ge.createElement("template"),ta={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?Ge.createElementNS(Zc,e):t==="mathml"?Ge.createElementNS(ea,e):n?Ge.createElement(e,{is:n}):Ge.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Ge.createTextNode(e),createComment:e=>Ge.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ge.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{Hr.innerHTML=Ro(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=Hr.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},tt="transition",Vt="animation",tn=Symbol("_vtc"),Mo={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},na=he({},Wi,Mo),sa=e=>(e.displayName="Transition",e.props=na,e),Bf=sa((e,{slots:t})=>Ds(zl,ra(e),t)),dt=(e,t=[])=>{K(e)?e.forEach(n=>n(...t)):e&&e(...t)},Dr=e=>e?K(e)?e.some(t=>t.length>1):e.length>1:!1;function ra(e){const t={};for(const w in e)w in Mo||(t[w]=e[w]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:f=o,appearToClass:a=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:m=`${n}-leave-active`,leaveToClass:v=`${n}-leave-to`}=e,b=ia(r),_=b&&b[0],U=b&&b[1],{onBeforeEnter:P,onEnter:j,onEnterCancelled:p,onLeave:g,onLeaveCancelled:O,onBeforeAppear:D=P,onAppear:R=j,onAppearCancelled:V=p}=t,T=(w,F,Y,ie)=>{w._enterCancelled=ie,ht(w,F?a:l),ht(w,F?f:o),Y&&Y()},M=(w,F)=>{w._isLeaving=!1,ht(w,d),ht(w,v),ht(w,m),F&&F()},A=w=>(F,Y)=>{const ie=w?R:j,W=()=>T(F,w,Y);dt(ie,[F,W]),$r(()=>{ht(F,w?c:i),qe(F,w?a:l),Dr(ie)||jr(F,s,_,W)})};return he(t,{onBeforeEnter(w){dt(P,[w]),qe(w,i),qe(w,o)},onBeforeAppear(w){dt(D,[w]),qe(w,c),qe(w,f)},onEnter:A(!1),onAppear:A(!0),onLeave(w,F){w._isLeaving=!0;const Y=()=>M(w,F);qe(w,d),w._enterCancelled?(qe(w,m),Ur()):(Ur(),qe(w,m)),$r(()=>{w._isLeaving&&(ht(w,d),qe(w,v),Dr(g)||jr(w,s,U,Y))}),dt(g,[w,Y])},onEnterCancelled(w){T(w,!1,void 0,!0),dt(p,[w])},onAppearCancelled(w){T(w,!0,void 0,!0),dt(V,[w])},onLeaveCancelled(w){M(w),dt(O,[w])}})}function ia(e){if(e==null)return null;if(se(e))return[as(e.enter),as(e.leave)];{const t=as(e);return[t,t]}}function as(e){return nl(e)}function qe(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[tn]||(e[tn]=new Set)).add(t)}function ht(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[tn];n&&(n.delete(t),n.size||(e[tn]=void 0))}function $r(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let oa=0;function jr(e,t,n,s){const r=e._endId=++oa,i=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=la(e,t);if(!o)return s();const f=o+"end";let a=0;const d=()=>{e.removeEventListener(f,m),i()},m=v=>{v.target===e&&++a>=c&&d()};setTimeout(()=>{a(n[b]||"").split(", "),r=s(`${tt}Delay`),i=s(`${tt}Duration`),o=Vr(r,i),l=s(`${Vt}Delay`),c=s(`${Vt}Duration`),f=Vr(l,c);let a=null,d=0,m=0;t===tt?o>0&&(a=tt,d=o,m=i.length):t===Vt?f>0&&(a=Vt,d=f,m=c.length):(d=Math.max(o,f),a=d>0?o>f?tt:Vt:null,m=a?a===tt?i.length:c.length:0);const v=a===tt&&/\b(transform|all)(,|$)/.test(s(`${tt}Property`).toString());return{type:a,timeout:d,propCount:m,hasTransform:v}}function Vr(e,t){for(;e.lengthkr(n)+kr(e[s])))}function kr(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Ur(){return document.body.offsetHeight}function ca(e,t,n){const s=e[tn];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Wr=Symbol("_vod"),aa=Symbol("_vsh"),fa=Symbol(""),ua=/(^|;)\s*display\s*:/;function da(e,t,n){const s=e.style,r=le(n);let i=!1;if(n&&!r){if(t)if(le(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&An(s,l,"")}else for(const o in t)n[o]==null&&An(s,o,"");for(const o in n)o==="display"&&(i=!0),An(s,o,n[o])}else if(r){if(t!==n){const o=s[fa];o&&(n+=";"+o),s.cssText=n,i=ua.test(n)}}else t&&e.removeAttribute("style");Wr in e&&(e[Wr]=i?s.display:"",e[aa]&&(s.display="none"))}const Br=/\s*!important$/;function An(e,t,n){if(K(n))n.forEach(s=>An(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=ha(e,t);Br.test(n)?e.setProperty(at(s),n.replace(Br,""),"important"):e[s]=n}}const Kr=["Webkit","Moz","ms"],fs={};function ha(e,t){const n=fs[t];if(n)return n;let s=Ne(t);if(s!=="filter"&&s in e)return fs[t]=s;s=jn(s);for(let r=0;rus||(va.then(()=>us=0),us=Date.now());function _a(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;$e(ba(s,n.value),t,5,[s])};return n.value=e,n.attached=ya(),n}function ba(e,t){if(K(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const zr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,wa=(e,t,n,s,r,i)=>{const o=r==="svg";t==="class"?ca(e,s,o):t==="style"?da(e,n,s):nn(t)?Vs(t)||ga(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Sa(e,t,s,o))?(Xr(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Gr(e,t,s,o,i,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!le(s))?Xr(e,Ne(t),s,i,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Gr(e,t,s,o))};function Sa(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&zr(t)&&q(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return zr(t)&&le(n)?!1:t in e}const Qr=e=>{const t=e.props["onUpdate:modelValue"]||!1;return K(t)?n=>Tn(t,n):t};function Ta(e){e.target.composing=!0}function Zr(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const ds=Symbol("_assign"),Kf={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[ds]=Qr(r);const i=s||r.props&&r.props.type==="number";At(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=xs(l)),e[ds](l)}),n&&At(e,"change",()=>{e.value=e.value.trim()}),t||(At(e,"compositionstart",Ta),At(e,"compositionend",Zr),At(e,"change",Zr))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:i}},o){if(e[ds]=Qr(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?xs(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===c)||(e.value=c))}},xa=["ctrl","shift","alt","meta"],Ea={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>xa.some(n=>e[`${n}Key`]&&!t.includes(n))},qf=(e,t)=>{const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(r,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=r=>{if(!("key"in r))return;const i=at(r.key);if(t.some(o=>o===i||Ca[o]===i))return e(r)})},Oo=he({patchProp:wa},ta);let Xt,ei=!1;function Aa(){return Xt||(Xt=Mc(Oo))}function Ra(){return Xt=ei?Xt:Oc(Oo),ei=!0,Xt}const Xf=(...e)=>{const t=Aa().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Lo(s);if(!r)return;const i=t._component;!q(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const o=n(r,!1,Po(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),o},t},Yf=(...e)=>{const t=Ra().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Lo(s);if(r)return n(r,!0,Po(r))},t};function Po(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Lo(e){return le(e)?document.querySelector(e):e}const Ma=window.__VP_SITE_DATA__;function Io(e){return yi()?(ul(e),!0):!1}const hs=new WeakMap,Oa=(...e)=>{var t;const n=e[0],s=(t=ln())==null?void 0:t.proxy;if(s==null&&!so())throw new Error("injectLocal must be called in setup");return s&&hs.has(s)&&n in hs.get(s)?hs.get(s)[n]:bt(...e)},No=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Jf=e=>e!=null,Pa=Object.prototype.toString,La=e=>Pa.call(e)==="[object Object]",ct=()=>{},ti=Ia();function Ia(){var e,t;return No&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function or(e,t){function n(...s){return new Promise((r,i)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(r).catch(i)})}return n}const Fo=e=>e();function Ho(e,t={}){let n,s,r=ct;const i=c=>{clearTimeout(c),r(),r=ct};let o;return c=>{const f=ce(e),a=ce(t.maxWait);return n&&i(n),f<=0||a!==void 0&&a<=0?(s&&(i(s),s=null),Promise.resolve(c())):new Promise((d,m)=>{r=t.rejectOnCancel?m:d,o=c,a&&!s&&(s=setTimeout(()=>{n&&i(n),s=null,d(o())},a)),n=setTimeout(()=>{s&&i(s),s=null,d(c())},f)})}}function Na(...e){let t=0,n,s=!0,r=ct,i,o,l,c,f;!fe(e[0])&&typeof e[0]=="object"?{delay:o,trailing:l=!0,leading:c=!0,rejectOnCancel:f=!1}=e[0]:[o,l=!0,c=!0,f=!1]=e;const a=()=>{n&&(clearTimeout(n),n=void 0,r(),r=ct)};return m=>{const v=ce(o),b=Date.now()-t,_=()=>i=m();return a(),v<=0?(t=Date.now(),_()):(b>v&&(c||!s)?(t=Date.now(),_()):l&&(i=new Promise((U,P)=>{r=f?P:U,n=setTimeout(()=>{t=Date.now(),s=!0,U(_()),a()},Math.max(0,v-b))})),!c&&!n&&(n=setTimeout(()=>s=!0,v)),s=!1,i)}}function Fa(e=Fo,t={}){const{initialState:n="active"}=t,s=lr(n==="active");function r(){s.value=!1}function i(){s.value=!0}const o=(...l)=>{s.value&&e(...l)};return{isActive:Wn(s),pause:r,resume:i,eventFilter:o}}function ni(e){return e.endsWith("rem")?Number.parseFloat(e)*16:Number.parseFloat(e)}function Ha(e){return ln()}function ps(e){return Array.isArray(e)?e:[e]}function lr(...e){if(e.length!==1)return $l(...e);const t=e[0];return typeof t=="function"?Wn(Fl(()=>({get:t,set:ct}))):De(t)}function Da(e,t=200,n={}){return or(Ho(t,n),e)}function $a(e,t=200,n=!1,s=!0,r=!1){return or(Na(t,n,s,r),e)}function Do(e,t,n={}){const{eventFilter:s=Fo,...r}=n;return Ie(e,or(s,t),r)}function ja(e,t,n={}){const{eventFilter:s,initialState:r="active",...i}=n,{eventFilter:o,pause:l,resume:c,isActive:f}=Fa(s,{initialState:r});return{stop:Do(e,t,{...i,eventFilter:o}),pause:l,resume:c,isActive:f}}function Jn(e,t=!0,n){Ha()?Ht(e,n):t?e():Bn(e)}function zf(e,t,n={}){const{debounce:s=0,maxWait:r=void 0,...i}=n;return Do(e,t,{...i,eventFilter:Ho(s,{maxWait:r})})}function Va(e,t,n){return Ie(e,t,{...n,immediate:!0})}function Qf(e,t,n){let s;fe(n)?s={evaluating:n}:s={};const{lazy:r=!1,evaluating:i=void 0,shallow:o=!0,onError:l=ct}=s,c=Ee(!r),f=o?Ee(t):De(t);let a=0;return rr(async d=>{if(!c.value)return;a++;const m=a;let v=!1;i&&Promise.resolve().then(()=>{i.value=!0});try{const b=await e(_=>{d(()=>{i&&(i.value=!1),v||_()})});m===a&&(f.value=b)}catch(b){l(b)}finally{i&&m===a&&(i.value=!1),v=!0}}),r?re(()=>(c.value=!0,f.value)):f}const je=No?window:void 0;function cr(e){var t;const n=ce(e);return(t=n==null?void 0:n.$el)!=null?t:n}function Qe(...e){const t=[],n=()=>{t.forEach(l=>l()),t.length=0},s=(l,c,f,a)=>(l.addEventListener(c,f,a),()=>l.removeEventListener(c,f,a)),r=re(()=>{const l=ps(ce(e[0])).filter(c=>c!=null);return l.every(c=>typeof c!="string")?l:void 0}),i=Va(()=>{var l,c;return[(c=(l=r.value)==null?void 0:l.map(f=>cr(f)))!=null?c:[je].filter(f=>f!=null),ps(ce(r.value?e[1]:e[0])),ps(zs(r.value?e[2]:e[1])),ce(r.value?e[3]:e[2])]},([l,c,f,a])=>{if(n(),!(l!=null&&l.length)||!(c!=null&&c.length)||!(f!=null&&f.length))return;const d=La(a)?{...a}:a;t.push(...l.flatMap(m=>c.flatMap(v=>f.map(b=>s(m,v,b,d)))))},{flush:"post"}),o=()=>{i(),n()};return Io(n),o}function ka(){const e=Ee(!1),t=ln();return t&&Ht(()=>{e.value=!0},t),e}function Ua(e){const t=ka();return re(()=>(t.value,!!e()))}function Wa(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function Zf(...e){let t,n,s={};e.length===3?(t=e[0],n=e[1],s=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],s=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:r=je,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=s,c=Wa(t);return Qe(r,i,a=>{a.repeat&&ce(l)||c(a)&&n(a)},o)}const Ba=Symbol("vueuse-ssr-width");function Ka(){const e=so()?Oa(Ba,null):null;return typeof e=="number"?e:void 0}function $o(e,t={}){const{window:n=je,ssrWidth:s=Ka()}=t,r=Ua(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function"),i=Ee(typeof s=="number"),o=Ee(),l=Ee(!1),c=f=>{l.value=f.matches};return rr(()=>{if(i.value){i.value=!r.value;const f=ce(e).split(",");l.value=f.some(a=>{const d=a.includes("not all"),m=a.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/),v=a.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/);let b=!!(m||v);return m&&b&&(b=s>=ni(m[1])),v&&b&&(b=s<=ni(v[1])),d?!b:b});return}r.value&&(o.value=n.matchMedia(ce(e)),l.value=o.value.matches)}),Qe(o,"change",c,{passive:!0}),re(()=>l.value)}const yn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},_n="__vueuse_ssr_handlers__",qa=Ga();function Ga(){return _n in yn||(yn[_n]=yn[_n]||{}),yn[_n]}function jo(e,t){return qa[e]||t}function Vo(e){return $o("(prefers-color-scheme: dark)",e)}function Xa(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Ya={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},si="vueuse-storage";function ar(e,t,n,s={}){var r;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:f=!1,shallow:a,window:d=je,eventFilter:m,onError:v=A=>{console.error(A)},initOnMounted:b}=s,_=(a?Ee:De)(typeof t=="function"?t():t),U=re(()=>ce(e));if(!n)try{n=jo("getDefaultStorage",()=>{var A;return(A=je)==null?void 0:A.localStorage})()}catch(A){v(A)}if(!n)return _;const P=ce(t),j=Xa(P),p=(r=s.serializer)!=null?r:Ya[j],{pause:g,resume:O}=ja(_,()=>R(_.value),{flush:i,deep:o,eventFilter:m});Ie(U,()=>T(),{flush:i}),d&&l&&Jn(()=>{n instanceof Storage?Qe(d,"storage",T,{passive:!0}):Qe(d,si,M),b&&T()}),b||T();function D(A,w){if(d){const F={key:U.value,oldValue:A,newValue:w,storageArea:n};d.dispatchEvent(n instanceof Storage?new StorageEvent("storage",F):new CustomEvent(si,{detail:F}))}}function R(A){try{const w=n.getItem(U.value);if(A==null)D(w,null),n.removeItem(U.value);else{const F=p.write(A);w!==F&&(n.setItem(U.value,F),D(w,F))}}catch(w){v(w)}}function V(A){const w=A?A.newValue:n.getItem(U.value);if(w==null)return c&&P!=null&&n.setItem(U.value,p.write(P)),P;if(!A&&f){const F=p.read(w);return typeof f=="function"?f(F,P):j==="object"&&!Array.isArray(F)?{...P,...F}:F}else return typeof w!="string"?w:p.read(w)}function T(A){if(!(A&&A.storageArea!==n)){if(A&&A.key==null){_.value=P;return}if(!(A&&A.key!==U.value)){g();try{(A==null?void 0:A.newValue)!==p.write(_.value)&&(_.value=V(A))}catch(w){v(w)}finally{A?Bn(O):O()}}}}function M(A){T(A.detail)}return _}const Ja="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function za(e={}){const{selector:t="html",attribute:n="class",initialValue:s="auto",window:r=je,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:f,disableTransition:a=!0}=e,d={auto:"",light:"light",dark:"dark",...e.modes||{}},m=Vo({window:r}),v=re(()=>m.value?"dark":"light"),b=c||(o==null?lr(s):ar(o,s,i,{window:r,listenToStorageChanges:l})),_=re(()=>b.value==="auto"?v.value:b.value),U=jo("updateHTMLAttrs",(g,O,D)=>{const R=typeof g=="string"?r==null?void 0:r.document.querySelector(g):cr(g);if(!R)return;const V=new Set,T=new Set;let M=null;if(O==="class"){const w=D.split(/\s/g);Object.values(d).flatMap(F=>(F||"").split(/\s/g)).filter(Boolean).forEach(F=>{w.includes(F)?V.add(F):T.add(F)})}else M={key:O,value:D};if(V.size===0&&T.size===0&&M===null)return;let A;a&&(A=r.document.createElement("style"),A.appendChild(document.createTextNode(Ja)),r.document.head.appendChild(A));for(const w of V)R.classList.add(w);for(const w of T)R.classList.remove(w);M&&R.setAttribute(M.key,M.value),a&&(r.getComputedStyle(A).opacity,document.head.removeChild(A))});function P(g){var O;U(t,n,(O=d[g])!=null?O:g)}function j(g){e.onChanged?e.onChanged(g,P):P(g)}Ie(_,j,{flush:"post",immediate:!0}),Jn(()=>j(_.value));const p=re({get(){return f?b.value:_.value},set(g){b.value=g}});return Object.assign(p,{store:b,system:v,state:_})}function Qa(e={}){const{valueDark:t="dark",valueLight:n=""}=e,s=za({...e,onChanged:(o,l)=>{var c;e.onChanged?(c=e.onChanged)==null||c.call(e,o==="dark",l,o):l(o)},modes:{dark:t,light:n}}),r=re(()=>s.system.value);return re({get(){return s.value==="dark"},set(o){const l=o?"dark":"light";r.value===l?s.value="auto":s.value=l}})}function gs(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}const ri=1;function Za(e,t={}){const{throttle:n=0,idle:s=200,onStop:r=ct,onScroll:i=ct,offset:o={left:0,right:0,top:0,bottom:0},eventListenerOptions:l={capture:!1,passive:!0},behavior:c="auto",window:f=je,onError:a=R=>{console.error(R)}}=t,d=Ee(0),m=Ee(0),v=re({get(){return d.value},set(R){_(R,void 0)}}),b=re({get(){return m.value},set(R){_(void 0,R)}});function _(R,V){var T,M,A,w;if(!f)return;const F=ce(e);if(!F)return;(A=F instanceof Document?f.document.body:F)==null||A.scrollTo({top:(T=ce(V))!=null?T:b.value,left:(M=ce(R))!=null?M:v.value,behavior:ce(c)});const Y=((w=F==null?void 0:F.document)==null?void 0:w.documentElement)||(F==null?void 0:F.documentElement)||F;v!=null&&(d.value=Y.scrollLeft),b!=null&&(m.value=Y.scrollTop)}const U=Ee(!1),P=Nt({left:!0,right:!1,top:!0,bottom:!1}),j=Nt({left:!1,right:!1,top:!1,bottom:!1}),p=R=>{U.value&&(U.value=!1,j.left=!1,j.right=!1,j.top=!1,j.bottom=!1,r(R))},g=Da(p,n+s),O=R=>{var V;if(!f)return;const T=((V=R==null?void 0:R.document)==null?void 0:V.documentElement)||(R==null?void 0:R.documentElement)||cr(R),{display:M,flexDirection:A,direction:w}=getComputedStyle(T),F=w==="rtl"?-1:1,Y=T.scrollLeft;j.left=Yd.value;const ie=Math.abs(Y*F)<=(o.left||0),W=Math.abs(Y*F)+T.clientWidth>=T.scrollWidth-(o.right||0)-ri;M==="flex"&&A==="row-reverse"?(P.left=W,P.right=ie):(P.left=ie,P.right=W),d.value=Y;let X=T.scrollTop;R===f.document&&!X&&(X=f.document.body.scrollTop),j.top=Xm.value;const $=Math.abs(X)<=(o.top||0),oe=Math.abs(X)+T.clientHeight>=T.scrollHeight-(o.bottom||0)-ri;M==="flex"&&A==="column-reverse"?(P.top=oe,P.bottom=$):(P.top=$,P.bottom=oe),m.value=X},D=R=>{var V;if(!f)return;const T=(V=R.target.documentElement)!=null?V:R.target;O(T),U.value=!0,g(R),i(R)};return Qe(e,"scroll",n?$a(D,n,!0,!1):D,l),Jn(()=>{try{const R=ce(e);if(!R)return;O(R)}catch(R){a(R)}}),Qe(e,"scrollend",p,l),{x:v,y:b,isScrolling:U,arrivedState:P,directions:j,measure(){const R=ce(e);f&&R&&O(R)}}}function eu(e,t,n={}){const{window:s=je}=n;return ar(e,t,s==null?void 0:s.localStorage,n)}function ko(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const ms=new WeakMap;function tu(e,t=!1){const n=Ee(t);let s=null,r="";Ie(lr(e),l=>{const c=gs(ce(l));if(c){const f=c;if(ms.get(f)||ms.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(r=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const i=()=>{const l=gs(ce(e));!l||n.value||(ti&&(s=Qe(l,"touchmove",c=>{ef(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=gs(ce(e));!l||!n.value||(ti&&(s==null||s()),l.style.overflow=r,ms.delete(l),n.value=!1)};return Io(o),re({get(){return n.value},set(l){l?i():o()}})}function nu(e,t,n={}){const{window:s=je}=n;return ar(e,t,s==null?void 0:s.sessionStorage,n)}function su(e={}){const{window:t=je,...n}=e;return Za(t,n)}function ru(e={}){const{window:t=je,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:s=Number.POSITIVE_INFINITY,listenOrientation:r=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=Ee(n),c=Ee(s),f=()=>{if(t)if(o==="outer")l.value=t.outerWidth,c.value=t.outerHeight;else if(o==="visual"&&t.visualViewport){const{width:d,height:m,scale:v}=t.visualViewport;l.value=Math.round(d*v),c.value=Math.round(m*v)}else i?(l.value=t.innerWidth,c.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,c.value=t.document.documentElement.clientHeight)};f(),Jn(f);const a={passive:!0};if(Qe("resize",f,a),t&&o==="visual"&&t.visualViewport&&Qe(t.visualViewport,"resize",f,a),r){const d=$o("(orientation: portrait)");Ie(d,()=>f())}return{width:l,height:c}}const vs={};var ys={};const Uo=/^(?:[a-z]+:|\/\/)/i,tf="vitepress-theme-appearance",nf=/#.*$/,sf=/[?#].*$/,rf=/(?:(^|\/)index)?\.(?:md|html)$/,ye=typeof document<"u",Wo={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function of(e,t,n=!1){if(t===void 0)return!1;if(e=ii(`/${e}`),n)return new RegExp(t).test(e);if(ii(t)!==e)return!1;const s=t.match(nf);return s?(ye?location.hash:"")===s[0]:!0}function ii(e){return decodeURI(e).replace(sf,"").replace(rf,"$1")}function lf(e){return Uo.test(e)}function cf(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!lf(n)&&of(t,`/${n}/`,!0))||"root"}function af(e,t){var s,r,i,o,l,c,f;const n=cf(e,t);return Object.assign({},e,{localeIndex:n,lang:((s=e.locales[n])==null?void 0:s.lang)??e.lang,dir:((r=e.locales[n])==null?void 0:r.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:Ko(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function Bo(e,t){const n=t.title||e.title,s=t.titleTemplate??e.titleTemplate;if(typeof s=="string"&&s.includes(":title"))return s.replace(/:title/g,n);const r=ff(e.title,s);return n===r.slice(3)?n:`${n}${r}`}function ff(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function uf(e,t){const[n,s]=t;if(n!=="meta")return!1;const r=Object.entries(s)[0];return r==null?!1:e.some(([i,o])=>i===n&&o[r[0]]===r[1])}function Ko(e,t){return[...e.filter(n=>!uf(t,n)),...t]}const df=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,hf=/^[a-z]:/i;function oi(e){const t=hf.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(df,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const _s=new Set;function pf(e){if(_s.size===0){const n=typeof process=="object"&&(ys==null?void 0:ys.VITE_EXTRA_EXTENSIONS)||(vs==null?void 0:vs.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(s=>_s.add(s))}const t=e.split(".").pop();return t==null||!_s.has(t.toLowerCase())}function iu(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const gf=Symbol(),St=Ee(Ma);function ou(e){const t=re(()=>af(St.value,e.data.relativePath)),n=t.value.appearance,s=n==="force-dark"?De(!0):n==="force-auto"?Vo():n?Qa({storageKey:tf,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):De(!1),r=De(ye?location.hash:"");return ye&&window.addEventListener("hashchange",()=>{r.value=location.hash}),Ie(()=>e.data,()=>{r.value=ye?location.hash:""}),{site:t,theme:re(()=>t.value.themeConfig),page:re(()=>e.data),frontmatter:re(()=>e.data.frontmatter),params:re(()=>e.data.params),lang:re(()=>t.value.lang),dir:re(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:re(()=>t.value.localeIndex||"root"),title:re(()=>Bo(t.value,e.data)),description:re(()=>e.data.description||t.value.description),isDark:s,hash:re(()=>r.value)}}function mf(){const e=bt(gf);if(!e)throw new Error("vitepress data not properly injected in app");return e}function vf(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function li(e){return Uo.test(e)||!e.startsWith("/")?e:vf(St.value.base,e)}function yf(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ye){const n="/";t=oi(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let s=__VP_HASH_MAP__[t.toLowerCase()];if(s||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",s=__VP_HASH_MAP__[t.toLowerCase()]),!s)return null;t=`${n}assets/${t}.${s}.js`}else t=`./${oi(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let Rn=[];function lu(e){Rn.push(e),qn(()=>{Rn=Rn.filter(t=>t!==e)})}function _f(){let e=St.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=ci(e,n);else if(Array.isArray(e))for(const s of e){const r=ci(s,n);if(r){t=r;break}}return t}function ci(e,t){const n=document.querySelector(e);if(!n)return 0;const s=n.getBoundingClientRect().bottom;return s<0?0:s+t}const bf=Symbol(),qo="http://a.com",wf=()=>({path:"/",component:null,data:Wo});function cu(e,t){const n=Nt(wf()),s={route:n,go:r};async function r(l=ye?location.href:"/"){var c,f;l=bs(l),await((c=s.onBeforeRouteChange)==null?void 0:c.call(s,l))!==!1&&(ye&&l!==bs(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((f=s.onAfterRouteChange??s.onAfterRouteChanged)==null?void 0:f(l)))}let i=null;async function o(l,c=0,f=!1){var m,v;if(await((m=s.onBeforePageLoad)==null?void 0:m.call(s,l))===!1)return;const a=new URL(l,qo),d=i=a.pathname;try{let b=await e(d);if(!b)throw new Error(`Page not found: ${d}`);if(i===d){i=null;const{default:_,__pageData:U}=b;if(!_)throw new Error(`Invalid route component: ${_}`);await((v=s.onAfterPageLoad)==null?void 0:v.call(s,l)),n.path=ye?d:li(d),n.component=xn(_),n.data=xn(U),ye&&Bn(()=>{let P=St.value.base+U.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!St.value.cleanUrls&&!P.endsWith("/")&&(P+=".html"),P!==a.pathname&&(a.pathname=P,l=P+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let j=null;try{j=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(p){console.warn(p)}if(j){ai(j,a.hash);return}}window.scrollTo(0,c)})}}catch(b){if(!/fetch|Page not found/.test(b.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(b),!f)try{const _=await fetch(St.value.base+"hashmap.json");window.__VP_HASH_MAP__=await _.json(),await o(l,c,!0);return}catch{}if(i===d){i=null,n.path=ye?d:li(d),n.component=t?xn(t):null;const _=ye?d.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={...Wo,relativePath:_}}}}return ye&&(history.state===null&&history.replaceState({},""),window.addEventListener("click",l=>{if(l.defaultPrevented||!(l.target instanceof Element)||l.target.closest("button")||l.button!==0||l.ctrlKey||l.shiftKey||l.altKey||l.metaKey)return;const c=l.target.closest("a");if(!c||c.closest(".vp-raw")||c.hasAttribute("download")||c.hasAttribute("target"))return;const f=c.getAttribute("href")??(c instanceof SVGAElement?c.getAttribute("xlink:href"):null);if(f==null)return;const{href:a,origin:d,pathname:m,hash:v,search:b}=new URL(f,c.baseURI),_=new URL(location.href);d===_.origin&&pf(m)&&(l.preventDefault(),m===_.pathname&&b===_.search?(v!==_.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:_.href,newURL:a}))),v?ai(c,v,c.classList.contains("header-anchor")):window.scrollTo(0,0)):r(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var f;if(l.state===null)return;const c=bs(location.href);await o(c,l.state&&l.state.scrollPosition||0),await((f=s.onAfterRouteChange??s.onAfterRouteChanged)==null?void 0:f(c))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),s}function Sf(){const e=bt(bf);if(!e)throw new Error("useRouter() is called without provider.");return e}function Go(){return Sf().route}function ai(e,t,n=!1){let s=null;try{s=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(r){console.warn(r)}if(s){let r=function(){!n||Math.abs(o-window.scrollY)>window.innerHeight?window.scrollTo(0,o):window.scrollTo({left:0,top:o,behavior:"smooth"})};const i=parseInt(window.getComputedStyle(s).paddingTop,10),o=window.scrollY+s.getBoundingClientRect().top-_f()+i;requestAnimationFrame(r)}}function bs(e){const t=new URL(e,qo);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),St.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const bn=()=>Rn.forEach(e=>e()),au=Zs({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Go(),{frontmatter:n,site:s}=mf();return Ie(n,bn,{deep:!0,flush:"post"}),()=>Ds(e.as,s.value.contentProps??{style:{position:"relative"}},[t.component?Ds(t.component,{onVnodeMounted:bn,onVnodeUpdated:bn,onVnodeUnmounted:bn}):"404 Page Not Found"])}}),fu=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Tf="modulepreload",xf=function(e){return"/"+e},fi={},uu=function(t,n,s){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));r=Promise.allSettled(n.map(c=>{if(c=xf(c),c in fi)return;fi[c]=!0;const f=c.endsWith(".css"),a=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${a}`))return;const d=document.createElement("link");if(d.rel=f?"stylesheet":Tf,f||(d.as="script"),d.crossOrigin="",d.href=c,l&&d.setAttribute("nonce",l),document.head.appendChild(d),f)return new Promise((m,v)=>{d.addEventListener("load",m),d.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return r.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},du=Zs({setup(e,{slots:t}){const n=De(!1);return Ht(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function hu(){ye&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const s=(n=t.parentElement)==null?void 0:n.parentElement;if(!s)return;const r=Array.from(s.querySelectorAll("input")).indexOf(t);if(r<0)return;const i=s.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(f=>f.classList.contains("active"));if(!o)return;const l=i.children[r];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=s==null?void 0:s.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function pu(){if(ye){const e=new WeakMap;window.addEventListener("click",t=>{var s;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const r=n.parentElement,i=(s=n.nextElementSibling)==null?void 0:s.nextElementSibling;if(!r||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(r.className),l=[".vp-copy-ignore",".diff.remove"],c=i.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(a=>a.remove());let f=c.textContent||"";o&&(f=f.replace(/^ *(\$|>) /gm,"").trim()),Ef(f).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const a=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,a)})}})}}async function Ef(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const s=document.getSelection(),r=s?s.rangeCount>0&&s.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),r&&(s.removeAllRanges(),s.addRange(r)),n&&n.focus()}}function gu(e,t){let n=!0,s=[];const r=i=>{if(n){n=!1,i.forEach(l=>{const c=ws(l);for(const f of document.head.children)if(f.isEqualNode(c)){s.push(f);return}});return}const o=i.map(ws);s.forEach((l,c)=>{const f=o.findIndex(a=>a==null?void 0:a.isEqualNode(l??null));f!==-1?delete o[f]:(l==null||l.remove(),delete s[c])}),o.forEach(l=>l&&document.head.appendChild(l)),s=[...s,...o].filter(Boolean)};rr(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],f=Bo(o,i);f!==document.title&&(document.title=f);const a=l||o.description;let d=document.querySelector("meta[name=description]");d?d.getAttribute("content")!==a&&d.setAttribute("content",a):ws(["meta",{name:"description",content:a}]),r(Ko(o.head,Af(c)))})}function ws([e,t,n]){const s=document.createElement(e);for(const r in t)s.setAttribute(r,t[r]);return n&&(s.innerHTML=n),e==="script"&&t.async==null&&(s.async=!1),s}function Cf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function Af(e){return e.filter(t=>!Cf(t))}const Ss=new Set,Xo=()=>document.createElement("link"),Rf=e=>{const t=Xo();t.rel="prefetch",t.href=e,document.head.appendChild(t)},Mf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let wn;const Of=ye&&(wn=Xo())&&wn.relList&&wn.relList.supports&&wn.relList.supports("prefetch")?Rf:Mf;function mu(){if(!ye||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const s=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!Ss.has(c)){Ss.add(c);const f=yf(c);f&&Of(f)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{hostname:o,pathname:l}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||i.target!=="_blank"&&o===location.hostname&&(l!==location.pathname?n.observe(i):Ss.add(l))})})};Ht(s);const r=Go();Ie(()=>r.path,s),qn(()=>{n&&n.disconnect()})}export{Yi as $,_f as A,Hf as B,Nf as C,Ee as D,lu as E,Te as F,ae as G,Ff as H,Uo as I,Go as J,Wc as K,bt as L,ru as M,Ws as N,Zf as O,Bn as P,su as Q,ye as R,Wn as S,Bf as T,If as U,uu as V,tu as W,Sc as X,$f as Y,Gf as Z,fu as _,xo as a,qf as a0,jf as a1,Ds as a2,gu as a3,bf as a4,ou as a5,gf as a6,au as a7,du as a8,St as a9,cu as aa,yf as ab,Yf as ac,mu as ad,pu as ae,hu as af,Uf as ag,ce as ah,ps as ai,cr as aj,Jf as ak,Io as al,Qf as am,nu as an,eu as ao,zf as ap,Sf as aq,Qe as ar,Pf as as,Kf as at,fe as au,Lf as av,xn as aw,Xf as ax,iu as ay,Fs as b,kf as c,Zs as d,Wf as e,pf as f,li as g,re as h,lf as i,To as j,zs as k,of as l,$o as m,Bs as n,Ns as o,De as p,Ie as q,Df as r,rr as s,al as t,mf as u,Ht as v,Gl as w,qn as x,Vf as y,cc as z}; diff --git a/docs/.vitepress/dist/assets/chunks/theme.Cwh4Yq8A.js b/docs/.vitepress/dist/assets/chunks/theme.Cwh4Yq8A.js new file mode 100644 index 0000000..b3cc8f2 --- /dev/null +++ b/docs/.vitepress/dist/assets/chunks/theme.Cwh4Yq8A.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/VPLocalSearchBox.D3VOKMMh.js","assets/chunks/framework.BHpayLOB.js"])))=>i.map(i=>d[i]); +import{d as m,c as u,r as c,n as M,o as a,a as z,t as I,b as k,w as f,T as ue,e as h,_ as g,u as Be,i as Ee,f as De,g as de,h as y,j as d,k as r,l as W,m as ae,p as T,q as F,s as Y,v as j,x as ve,y as pe,z as Fe,A as Oe,F as w,B as H,C as K,D as ye,E as Q,G as _,H as E,I as Pe,J as Z,K as U,L as x,M as Ge,N as Le,O as re,P as Ve,Q as Se,R as ee,S as Ue,U as je,V as ze,W as Te,X as Ne,Y as We,Z as Ke,$ as Re,a0 as qe,a1 as Je,a2 as Xe}from"./framework.BHpayLOB.js";const Ye=m({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(a(),u("span",{class:M(["VPBadge",e.type])},[c(e.$slots,"default",{},()=>[z(I(e.text),1)])],2))}}),Qe={key:0,class:"VPBackdrop"},Ze=m({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(a(),k(ue,{name:"fade"},{default:f(()=>[e.show?(a(),u("div",Qe)):h("",!0)]),_:1}))}}),xe=g(Ze,[["__scopeId","data-v-c79a1216"]]),L=Be;function et(s,e){let t,o=!1;return()=>{t&&clearTimeout(t),o?t=setTimeout(s,e):(s(),(o=!0)&&setTimeout(()=>o=!1,e))}}function ie(s){return s.startsWith("/")?s:`/${s}`}function fe(s){const{pathname:e,search:t,hash:o,protocol:n}=new URL(s,"http://a.com");if(Ee(s)||s.startsWith("#")||!n.startsWith("http")||!De(e))return s;const{site:i}=L(),l=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${t}${o}`);return de(l)}function q({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:o,theme:n,hash:i}=L(),l=y(()=>{var p,$;return{label:(p=e.value.locales[t.value])==null?void 0:p.label,link:(($=e.value.locales[t.value])==null?void 0:$.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:y(()=>Object.entries(e.value.locales).flatMap(([p,$])=>l.value.label===$.label?[]:{text:$.label,link:tt($.link||(p==="root"?"/":`/${p}/`),n.value.i18nRouting!==!1&&s,o.value.relativePath.slice(l.value.link.length-1),!e.value.cleanUrls)+i.value})),currentLang:l}}function tt(s,e,t,o){return e?s.replace(/\/$/,"")+ie(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,o?".html":"")):s}const nt={class:"NotFound"},ot={class:"code"},st={class:"title"},at={class:"quote"},rt={class:"action"},it=["href","aria-label"],lt=m({__name:"NotFound",setup(s){const{theme:e}=L(),{currentLang:t}=q();return(o,n)=>{var i,l,v,p,$;return a(),u("div",nt,[d("p",ot,I(((i=r(e).notFound)==null?void 0:i.code)??"404"),1),d("h1",st,I(((l=r(e).notFound)==null?void 0:l.title)??"PAGE NOT FOUND"),1),n[0]||(n[0]=d("div",{class:"divider"},null,-1)),d("blockquote",at,I(((v=r(e).notFound)==null?void 0:v.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),d("div",rt,[d("a",{class:"link",href:r(de)(r(t).link),"aria-label":((p=r(e).notFound)==null?void 0:p.linkLabel)??"go to home"},I((($=r(e).notFound)==null?void 0:$.linkText)??"Take me home"),9,it)])])}}}),ct=g(lt,[["__scopeId","data-v-d6be1790"]]);function Me(s,e){if(Array.isArray(s))return J(s);if(s==null)return[];e=ie(e);const t=Object.keys(s).sort((n,i)=>i.split("/").length-n.split("/").length).find(n=>e.startsWith(ie(n))),o=t?s[t]:[];return Array.isArray(o)?J(o):J(o.items,o.base)}function ut(s){const e=[];let t=0;for(const o in s){const n=s[o];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function dt(s){const e=[];function t(o){for(const n of o)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(s),e}function le(s,e){return Array.isArray(e)?e.some(t=>le(s,t)):W(s,e.link)?!0:e.items?le(s,e.items):!1}function J(s,e){return[...s].map(t=>{const o={...t},n=o.base||e;return n&&o.link&&(o.link=n+o.link),o.items&&(o.items=J(o.items,n)),o})}function O(){const{frontmatter:s,page:e,theme:t}=L(),o=ae("(min-width: 960px)"),n=T(!1),i=y(()=>{const C=t.value.sidebar,S=e.value.relativePath;return C?Me(C,S):[]}),l=T(i.value);F(i,(C,S)=>{JSON.stringify(C)!==JSON.stringify(S)&&(l.value=i.value)});const v=y(()=>s.value.sidebar!==!1&&l.value.length>0&&s.value.layout!=="home"),p=y(()=>$?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),$=y(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),V=y(()=>v.value&&o.value),b=y(()=>v.value?ut(l.value):[]);function P(){n.value=!0}function N(){n.value=!1}function A(){n.value?N():P()}return{isOpen:n,sidebar:l,sidebarGroups:b,hasSidebar:v,hasAside:$,leftAside:p,isSidebarEnabled:V,open:P,close:N,toggle:A}}function vt(s,e){let t;Y(()=>{t=s.value?document.activeElement:void 0}),j(()=>{window.addEventListener("keyup",o)}),ve(()=>{window.removeEventListener("keyup",o)});function o(n){n.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function pt(s){const{page:e,hash:t}=L(),o=T(!1),n=y(()=>s.value.collapsed!=null),i=y(()=>!!s.value.link),l=T(!1),v=()=>{l.value=W(e.value.relativePath,s.value.link)};F([e,s,t],v),j(v);const p=y(()=>l.value?!0:s.value.items?le(e.value.relativePath,s.value.items):!1),$=y(()=>!!(s.value.items&&s.value.items.length));Y(()=>{o.value=!!(n.value&&s.value.collapsed)}),pe(()=>{(l.value||p.value)&&(o.value=!1)});function V(){n.value&&(o.value=!o.value)}return{collapsed:o,collapsible:n,isLink:i,isActiveLink:l,hasActiveLink:p,hasChildren:$,toggle:V}}function ft(){const{hasSidebar:s}=O(),e=ae("(min-width: 960px)"),t=ae("(min-width: 1280px)");return{isAsideEnabled:y(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const ht=/\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/,ce=[];function Ie(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function he(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const o=Number(t.tagName[1]);return{element:t,title:mt(t),link:"#"+t.id,level:o}});return _t(e,s)}function mt(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(ht.test(t.className))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function _t(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;return gt(s,o,n)}function kt(s,e){const{isAsideEnabled:t}=ft(),o=et(i,100);let n=null;j(()=>{requestAnimationFrame(i),window.addEventListener("scroll",o)}),Fe(()=>{l(location.hash)}),ve(()=>{window.removeEventListener("scroll",o)});function i(){if(!t.value)return;const v=window.scrollY,p=window.innerHeight,$=document.body.offsetHeight,V=Math.abs(v+p-$)<1,b=ce.map(({element:N,link:A})=>({link:A,top:bt(N)})).filter(({top:N})=>!Number.isNaN(N)).sort((N,A)=>N.top-A.top);if(!b.length){l(null);return}if(v<1){l(null);return}if(V){l(b[b.length-1].link);return}let P=null;for(const{link:N,top:A}of b){if(A>v+Oe()+4)break;P=N}l(P)}function l(v){n&&n.classList.remove("active"),v==null?n=null:n=s.value.querySelector(`a[href="${decodeURIComponent(v)}"]`);const p=n;p?(p.classList.add("active"),e.value.style.top=p.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function bt(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}function gt(s,e,t){ce.length=0;const o=[],n=[];return s.forEach(i=>{const l={...i,children:[]};let v=n[n.length-1];for(;v&&v.level>=l.level;)n.pop(),v=n[n.length-1];if(l.element.classList.contains("ignore-header")||v&&"shouldIgnore"in v){n.push({level:l.level,shouldIgnore:!0});return}l.level>t||l.level{const n=K("VPDocOutlineItem",!0);return a(),u("ul",{class:M(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),u(w,null,H(t.headers,({children:i,link:l,title:v})=>(a(),u("li",null,[d("a",{class:"outline-link",href:l,onClick:e,title:v},I(v),9,$t),i!=null&&i.length?(a(),k(n,{key:0,headers:i},null,8,["headers"])):h("",!0)]))),256))],2)}}}),we=g(yt,[["__scopeId","data-v-b933a997"]]),Pt={class:"content"},Lt={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},Vt=m({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=L(),o=ye([]);Q(()=>{o.value=he(e.value.outline??t.value.outline)});const n=T(),i=T();return kt(n,i),(l,v)=>(a(),u("nav",{"aria-labelledby":"doc-outline-aria-label",class:M(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:n},[d("div",Pt,[d("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),d("div",Lt,I(r(Ie)(r(t))),1),_(we,{headers:o.value,root:!0},null,8,["headers"])])],2))}}),St=g(Vt,[["__scopeId","data-v-a5bbad30"]]),Tt={class:"VPDocAsideCarbonAds"},Nt=m({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,o)=>(a(),u("div",Tt,[_(r(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Mt={class:"VPDocAside"},It=m({__name:"VPDocAside",setup(s){const{theme:e}=L();return(t,o)=>(a(),u("div",Mt,[c(t.$slots,"aside-top",{},void 0,!0),c(t.$slots,"aside-outline-before",{},void 0,!0),_(St),c(t.$slots,"aside-outline-after",{},void 0,!0),o[0]||(o[0]=d("div",{class:"spacer"},null,-1)),c(t.$slots,"aside-ads-before",{},void 0,!0),r(e).carbonAds?(a(),k(Nt,{key:0,"carbon-ads":r(e).carbonAds},null,8,["carbon-ads"])):h("",!0),c(t.$slots,"aside-ads-after",{},void 0,!0),c(t.$slots,"aside-bottom",{},void 0,!0)]))}}),wt=g(It,[["__scopeId","data-v-3f215769"]]);function At(){const{theme:s,page:e}=L();return y(()=>{const{text:t="Edit this page",pattern:o=""}=s.value.editLink||{};let n;return typeof o=="function"?n=o(e.value):n=o.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function Ct(){const{page:s,theme:e,frontmatter:t}=L();return y(()=>{var $,V,b,P,N,A,C,S;const o=Me(e.value.sidebar,s.value.relativePath),n=dt(o),i=Ht(n,B=>B.link.replace(/[?#].*$/,"")),l=i.findIndex(B=>W(s.value.relativePath,B.link)),v=(($=e.value.docFooter)==null?void 0:$.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((V=e.value.docFooter)==null?void 0:V.next)===!1&&!t.value.next||t.value.next===!1;return{prev:v?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((b=i[l-1])==null?void 0:b.docFooterText)??((P=i[l-1])==null?void 0:P.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((N=i[l-1])==null?void 0:N.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=i[l+1])==null?void 0:A.docFooterText)??((C=i[l+1])==null?void 0:C.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=i[l+1])==null?void 0:S.link)}}})}function Ht(s,e){const t=new Set;return s.filter(o=>{const n=e(o);return t.has(n)?!1:t.add(n)})}const D=m({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.tag??(e.href?"a":"span")),o=y(()=>e.href&&Pe.test(e.href)||e.target==="_blank");return(n,i)=>(a(),k(E(t.value),{class:M(["VPLink",{link:n.href,"vp-external-link-icon":o.value,"no-icon":n.noIcon}]),href:n.href?r(fe)(n.href):void 0,target:n.target??(o.value?"_blank":void 0),rel:n.rel??(o.value?"noreferrer":void 0)},{default:f(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Bt={class:"VPLastUpdated"},Et=["datetime"],Dt=m({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,lang:o}=L(),n=y(()=>new Date(t.value.lastUpdated)),i=y(()=>n.value.toISOString()),l=T("");return j(()=>{Y(()=>{var v,p,$;l.value=new Intl.DateTimeFormat((p=(v=e.value.lastUpdated)==null?void 0:v.formatOptions)!=null&&p.forceLocale?o.value:void 0,(($=e.value.lastUpdated)==null?void 0:$.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(n.value)})}),(v,p)=>{var $;return a(),u("p",Bt,[z(I((($=r(e).lastUpdated)==null?void 0:$.text)||r(e).lastUpdatedText||"Last updated")+": ",1),d("time",{datetime:i.value},I(l.value),9,Et)])}}}),Ft=g(Dt,[["__scopeId","data-v-e98dd255"]]),Ot={key:0,class:"VPDocFooter"},Gt={key:0,class:"edit-info"},Ut={key:0,class:"edit-link"},jt={key:1,class:"last-updated"},zt={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},Wt={class:"pager"},Kt=["innerHTML"],Rt=["innerHTML"],qt={class:"pager"},Jt=["innerHTML"],Xt=["innerHTML"],Yt=m({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:o}=L(),n=At(),i=Ct(),l=y(()=>e.value.editLink&&o.value.editLink!==!1),v=y(()=>t.value.lastUpdated),p=y(()=>l.value||v.value||i.value.prev||i.value.next);return($,V)=>{var b,P,N,A;return p.value?(a(),u("footer",Ot,[c($.$slots,"doc-footer-before",{},void 0,!0),l.value||v.value?(a(),u("div",Gt,[l.value?(a(),u("div",Ut,[_(D,{class:"edit-link-button",href:r(n).url,"no-icon":!0},{default:f(()=>[V[0]||(V[0]=d("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),z(" "+I(r(n).text),1)]),_:1,__:[0]},8,["href"])])):h("",!0),v.value?(a(),u("div",jt,[_(Ft)])):h("",!0)])):h("",!0),(b=r(i).prev)!=null&&b.link||(P=r(i).next)!=null&&P.link?(a(),u("nav",zt,[V[1]||(V[1]=d("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),d("div",Wt,[(N=r(i).prev)!=null&&N.link?(a(),k(D,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:f(()=>{var C;return[d("span",{class:"desc",innerHTML:((C=r(e).docFooter)==null?void 0:C.prev)||"Previous page"},null,8,Kt),d("span",{class:"title",innerHTML:r(i).prev.text},null,8,Rt)]}),_:1},8,["href"])):h("",!0)]),d("div",qt,[(A=r(i).next)!=null&&A.link?(a(),k(D,{key:0,class:"pager-link next",href:r(i).next.link},{default:f(()=>{var C;return[d("span",{class:"desc",innerHTML:((C=r(e).docFooter)==null?void 0:C.next)||"Next page"},null,8,Jt),d("span",{class:"title",innerHTML:r(i).next.text},null,8,Xt)]}),_:1},8,["href"])):h("",!0)])])):h("",!0)])):h("",!0)}}}),Qt=g(Yt,[["__scopeId","data-v-e257564d"]]),Zt={class:"container"},xt={class:"aside-container"},en={class:"aside-content"},tn={class:"content"},nn={class:"content-container"},on={class:"main"},sn=m({__name:"VPDoc",setup(s){const{theme:e}=L(),t=Z(),{hasSidebar:o,hasAside:n,leftAside:i}=O(),l=y(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(v,p)=>{const $=K("Content");return a(),u("div",{class:M(["VPDoc",{"has-sidebar":r(o),"has-aside":r(n)}])},[c(v.$slots,"doc-top",{},void 0,!0),d("div",Zt,[r(n)?(a(),u("div",{key:0,class:M(["aside",{"left-aside":r(i)}])},[p[0]||(p[0]=d("div",{class:"aside-curtain"},null,-1)),d("div",xt,[d("div",en,[_(wt,null,{"aside-top":f(()=>[c(v.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(v.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(v.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(v.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(v.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(v.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):h("",!0),d("div",tn,[d("div",nn,[c(v.$slots,"doc-before",{},void 0,!0),d("main",on,[_($,{class:M(["vp-doc",[l.value,r(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),_(Qt,null,{"doc-footer-before":f(()=>[c(v.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(v.$slots,"doc-after",{},void 0,!0)])])]),c(v.$slots,"doc-bottom",{},void 0,!0)],2)}}}),an=g(sn,[["__scopeId","data-v-39a288b8"]]),rn=m({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.href&&Pe.test(e.href)),o=y(()=>e.tag||(e.href?"a":"button"));return(n,i)=>(a(),k(E(o.value),{class:M(["VPButton",[n.size,n.theme]]),href:n.href?r(fe)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:f(()=>[z(I(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),ln=g(rn,[["__scopeId","data-v-fa7799d5"]]),cn=["src","alt"],un=m({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const o=K("VPImage",!0);return e.image?(a(),u(w,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),u("img",U({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:r(de)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,cn)):(a(),u(w,{key:1},[_(o,U({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),_(o,U({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):h("",!0)}}}),X=g(un,[["__scopeId","data-v-8426fc1a"]]),dn={class:"container"},vn={class:"main"},pn={class:"heading"},fn=["innerHTML"],hn=["innerHTML"],mn=["innerHTML"],_n={key:0,class:"actions"},kn={key:0,class:"image"},bn={class:"image-container"},gn=m({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=x("hero-image-slot-exists");return(t,o)=>(a(),u("div",{class:M(["VPHero",{"has-image":t.image||r(e)}])},[d("div",dn,[d("div",vn,[c(t.$slots,"home-hero-info-before",{},void 0,!0),c(t.$slots,"home-hero-info",{},()=>[d("h1",pn,[t.name?(a(),u("span",{key:0,innerHTML:t.name,class:"name clip"},null,8,fn)):h("",!0),t.text?(a(),u("span",{key:1,innerHTML:t.text,class:"text"},null,8,hn)):h("",!0)]),t.tagline?(a(),u("p",{key:0,innerHTML:t.tagline,class:"tagline"},null,8,mn)):h("",!0)],!0),c(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),u("div",_n,[(a(!0),u(w,null,H(t.actions,n=>(a(),u("div",{key:n.link,class:"action"},[_(ln,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):h("",!0),c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||r(e)?(a(),u("div",kn,[d("div",bn,[o[0]||(o[0]=d("div",{class:"image-bg"},null,-1)),c(t.$slots,"home-hero-image",{},()=>[t.image?(a(),k(X,{key:0,class:"image-src",image:t.image},null,8,["image"])):h("",!0)],!0)])])):h("",!0)])],2))}}),$n=g(gn,[["__scopeId","data-v-4f9c455b"]]),yn=m({__name:"VPHomeHero",setup(s){const{frontmatter:e}=L();return(t,o)=>r(e).hero?(a(),k($n,{key:0,class:"VPHomeHero",name:r(e).hero.name,text:r(e).hero.text,tagline:r(e).hero.tagline,image:r(e).hero.image,actions:r(e).hero.actions},{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before")]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info")]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after")]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):h("",!0)}}),Pn={class:"box"},Ln={key:0,class:"icon"},Vn=["innerHTML"],Sn=["innerHTML"],Tn=["innerHTML"],Nn={key:4,class:"link-text"},Mn={class:"link-text-value"},In=m({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(a(),k(D,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:f(()=>[d("article",Pn,[typeof e.icon=="object"&&e.icon.wrap?(a(),u("div",Ln,[_(X,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),k(X,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),u("div",{key:2,class:"icon",innerHTML:e.icon},null,8,Vn)):h("",!0),d("h2",{class:"title",innerHTML:e.title},null,8,Sn),e.details?(a(),u("p",{key:3,class:"details",innerHTML:e.details},null,8,Tn)):h("",!0),e.linkText?(a(),u("div",Nn,[d("p",Mn,[z(I(e.linkText)+" ",1),t[0]||(t[0]=d("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):h("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),wn=g(In,[["__scopeId","data-v-a3976bdc"]]),An={key:0,class:"VPFeatures"},Cn={class:"container"},Hn={class:"items"},Bn=m({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=y(()=>{const o=e.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,n)=>o.features?(a(),u("div",An,[d("div",Cn,[d("div",Hn,[(a(!0),u(w,null,H(o.features,i=>(a(),u("div",{key:i.title,class:M(["item",[t.value]])},[_(wn,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):h("",!0)}}),En=g(Bn,[["__scopeId","data-v-a6181336"]]),Dn=m({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=L();return(t,o)=>r(e).features?(a(),k(En,{key:0,class:"VPHomeFeatures",features:r(e).features},null,8,["features"])):h("",!0)}}),Fn=m({__name:"VPHomeContent",setup(s){const{width:e}=Ge({initialWidth:0,includeScrollbar:!1});return(t,o)=>(a(),u("div",{class:"vp-doc container",style:Le(r(e)?{"--vp-offset":`calc(50% - ${r(e)/2}px)`}:{})},[c(t.$slots,"default",{},void 0,!0)],4))}}),On=g(Fn,[["__scopeId","data-v-8e2d4988"]]),Gn=m({__name:"VPHome",setup(s){const{frontmatter:e,theme:t}=L();return(o,n)=>{const i=K("Content");return a(),u("div",{class:M(["VPHome",{"external-link-icon-enabled":r(t).externalLinkIcon}])},[c(o.$slots,"home-hero-before",{},void 0,!0),_(yn,null,{"home-hero-info-before":f(()=>[c(o.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(o.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(o.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(o.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(o.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(o.$slots,"home-hero-after",{},void 0,!0),c(o.$slots,"home-features-before",{},void 0,!0),_(Dn),c(o.$slots,"home-features-after",{},void 0,!0),r(e).markdownStyles!==!1?(a(),k(On,{key:0},{default:f(()=>[_(i)]),_:1})):(a(),k(i,{key:1}))],2)}}}),Un=g(Gn,[["__scopeId","data-v-8b561e3d"]]),jn={},zn={class:"VPPage"};function Wn(s,e){const t=K("Content");return a(),u("div",zn,[c(s.$slots,"page-top"),_(t),c(s.$slots,"page-bottom")])}const Kn=g(jn,[["render",Wn]]),Rn=m({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=L(),{hasSidebar:o}=O();return(n,i)=>(a(),u("div",{class:M(["VPContent",{"has-sidebar":r(o),"is-home":r(t).layout==="home"}]),id:"VPContent"},[r(e).isNotFound?c(n.$slots,"not-found",{key:0},()=>[_(ct)],!0):r(t).layout==="page"?(a(),k(Kn,{key:1},{"page-top":f(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(t).layout==="home"?(a(),k(Un,{key:2},{"home-hero-before":f(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(t).layout&&r(t).layout!=="doc"?(a(),k(E(r(t).layout),{key:3})):(a(),k(an,{key:4},{"doc-top":f(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":f(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":f(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":f(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":f(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),qn=g(Rn,[["__scopeId","data-v-1428d186"]]),Jn={class:"container"},Xn=["innerHTML"],Yn=["innerHTML"],Qn=m({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=L(),{hasSidebar:o}=O();return(n,i)=>r(e).footer&&r(t).footer!==!1?(a(),u("footer",{key:0,class:M(["VPFooter",{"has-sidebar":r(o)}])},[d("div",Jn,[r(e).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:r(e).footer.message},null,8,Xn)):h("",!0),r(e).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:r(e).footer.copyright},null,8,Yn)):h("",!0)])],2)):h("",!0)}}),Zn=g(Qn,[["__scopeId","data-v-e315a0ad"]]);function xn(){const{theme:s,frontmatter:e}=L(),t=ye([]),o=y(()=>t.value.length>0);return Q(()=>{t.value=he(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:o}}const eo={class:"menu-text"},to={class:"header"},no={class:"outline"},oo=m({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=L(),o=T(!1),n=T(0),i=T(),l=T();function v(b){var P;(P=i.value)!=null&&P.contains(b.target)||(o.value=!1)}F(o,b=>{if(b){document.addEventListener("click",v);return}document.removeEventListener("click",v)}),re("Escape",()=>{o.value=!1}),Q(()=>{o.value=!1});function p(){o.value=!o.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function $(b){b.target.classList.contains("outline-link")&&(l.value&&(l.value.style.transition="none"),Ve(()=>{o.value=!1}))}function V(){o.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(b,P)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Le({"--vp-vh":n.value+"px"}),ref_key:"main",ref:i},[b.headers.length>0?(a(),u("button",{key:0,onClick:p,class:M({open:o.value})},[d("span",eo,I(r(Ie)(r(t))),1),P[0]||(P[0]=d("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(a(),u("button",{key:1,onClick:V},I(r(t).returnToTopLabel||"Return to top"),1)),_(ue,{name:"flyout"},{default:f(()=>[o.value?(a(),u("div",{key:0,ref_key:"items",ref:l,class:"items",onClick:$},[d("div",to,[d("a",{class:"top-link",href:"#",onClick:V},I(r(t).returnToTopLabel||"Return to top"),1)]),d("div",no,[_(we,{headers:b.headers},null,8,["headers"])])],512)):h("",!0)]),_:1})],4))}}),so=g(oo,[["__scopeId","data-v-8a42e2b4"]]),ao={class:"container"},ro=["aria-expanded"],io={class:"menu-text"},lo=m({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=L(),{hasSidebar:o}=O(),{headers:n}=xn(),{y:i}=Se(),l=T(0);j(()=>{l.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),Q(()=>{n.value=he(t.value.outline??e.value.outline)});const v=y(()=>n.value.length===0),p=y(()=>v.value&&!o.value),$=y(()=>({VPLocalNav:!0,"has-sidebar":o.value,empty:v.value,fixed:p.value}));return(V,b)=>r(t).layout!=="home"&&(!p.value||r(i)>=l.value)?(a(),u("div",{key:0,class:M($.value)},[d("div",ao,[r(o)?(a(),u("button",{key:0,class:"menu","aria-expanded":V.open,"aria-controls":"VPSidebarNav",onClick:b[0]||(b[0]=P=>V.$emit("open-menu"))},[b[1]||(b[1]=d("span",{class:"vpi-align-left menu-icon"},null,-1)),d("span",io,I(r(e).sidebarMenuLabel||"Menu"),1)],8,ro)):h("",!0),_(so,{headers:r(n),navHeight:l.value},null,8,["headers","navHeight"])])],2)):h("",!0)}}),co=g(lo,[["__scopeId","data-v-a6f0e41e"]]);function uo(){const s=T(!1);function e(){s.value=!0,window.addEventListener("resize",n)}function t(){s.value=!1,window.removeEventListener("resize",n)}function o(){s.value?t():e()}function n(){window.outerWidth>=768&&t()}const i=Z();return F(()=>i.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:o}}const vo={},po={class:"VPSwitch",type:"button",role:"switch"},fo={class:"check"},ho={key:0,class:"icon"};function mo(s,e){return a(),u("button",po,[d("span",fo,[s.$slots.default?(a(),u("span",ho,[c(s.$slots,"default",{},void 0,!0)])):h("",!0)])])}const _o=g(vo,[["render",mo],["__scopeId","data-v-1d5665e3"]]),ko=m({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=L(),o=x("toggle-appearance",()=>{e.value=!e.value}),n=T("");return pe(()=>{n.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(i,l)=>(a(),k(_o,{title:n.value,class:"VPSwitchAppearance","aria-checked":r(e),onClick:r(o)},{default:f(()=>l[0]||(l[0]=[d("span",{class:"vpi-sun sun"},null,-1),d("span",{class:"vpi-moon moon"},null,-1)])),_:1,__:[0]},8,["title","aria-checked","onClick"]))}}),me=g(ko,[["__scopeId","data-v-5337faa4"]]),bo={key:0,class:"VPNavBarAppearance"},go=m({__name:"VPNavBarAppearance",setup(s){const{site:e}=L();return(t,o)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",bo,[_(me)])):h("",!0)}}),$o=g(go,[["__scopeId","data-v-6c893767"]]),_e=T();let Ae=!1,se=0;function yo(s){const e=T(!1);if(ee){!Ae&&Po(),se++;const t=F(_e,o=>{var n,i,l;o===s.el.value||(n=s.el.value)!=null&&n.contains(o)?(e.value=!0,(i=s.onFocus)==null||i.call(s)):(e.value=!1,(l=s.onBlur)==null||l.call(s))});ve(()=>{t(),se--,se||Lo()})}return Ue(e)}function Po(){document.addEventListener("focusin",Ce),Ae=!0,_e.value=document.activeElement}function Lo(){document.removeEventListener("focusin",Ce)}function Ce(){_e.value=document.activeElement}const Vo={class:"VPMenuLink"},So=["innerHTML"],To=m({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=L();return(t,o)=>(a(),u("div",Vo,[_(D,{class:M({active:r(W)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon},{default:f(()=>[d("span",{innerHTML:t.item.text},null,8,So)]),_:1},8,["class","href","target","rel","no-icon"])]))}}),te=g(To,[["__scopeId","data-v-35975db6"]]),No={class:"VPMenuGroup"},Mo={key:0,class:"title"},Io=m({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",No,[e.text?(a(),u("p",Mo,I(e.text),1)):h("",!0),(a(!0),u(w,null,H(e.items,o=>(a(),u(w,null,["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):h("",!0)],64))),256))]))}}),wo=g(Io,[["__scopeId","data-v-69e747b5"]]),Ao={class:"VPMenu"},Co={key:0,class:"items"},Ho=m({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(a(),u("div",Ao,[e.items?(a(),u("div",Co,[(a(!0),u(w,null,H(e.items,o=>(a(),u(w,{key:JSON.stringify(o)},["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):"component"in o?(a(),k(E(o.component),U({key:1,ref_for:!0},o.props),null,16)):(a(),k(wo,{key:2,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):h("",!0),c(e.$slots,"default",{},void 0,!0)]))}}),Bo=g(Ho,[["__scopeId","data-v-b98bc113"]]),Eo=["aria-expanded","aria-label"],Do={key:0,class:"text"},Fo=["innerHTML"],Oo={key:1,class:"vpi-more-horizontal icon"},Go={class:"menu"},Uo=m({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=T(!1),t=T();yo({el:t,onBlur:o});function o(){e.value=!1}return(n,i)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:i[1]||(i[1]=l=>e.value=!0),onMouseleave:i[2]||(i[2]=l=>e.value=!1)},[d("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:i[0]||(i[0]=l=>e.value=!e.value)},[n.button||n.icon?(a(),u("span",Do,[n.icon?(a(),u("span",{key:0,class:M([n.icon,"option-icon"])},null,2)):h("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,Fo)):h("",!0),i[3]||(i[3]=d("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(a(),u("span",Oo))],8,Eo),d("div",Go,[_(Bo,{items:n.items},{default:f(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),ke=g(Uo,[["__scopeId","data-v-cf11d7a2"]]),jo=["href","aria-label","innerHTML"],zo=m({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=T();j(async()=>{var i;await Ve();const n=(i=t.value)==null?void 0:i.children[0];n instanceof HTMLElement&&n.className.startsWith("vpi-social-")&&(getComputedStyle(n).maskImage||getComputedStyle(n).webkitMaskImage)==="none"&&n.style.setProperty("--icon",`url('https://api.iconify.design/simple-icons/${e.icon}.svg')`)});const o=y(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,i)=>(a(),u("a",{ref_key:"el",ref:t,class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:o.value},null,8,jo))}}),Wo=g(zo,[["__scopeId","data-v-bd121fe5"]]),Ko={class:"VPSocialLinks"},Ro=m({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(a(),u("div",Ko,[(a(!0),u(w,null,H(e.links,({link:o,icon:n,ariaLabel:i})=>(a(),k(Wo,{key:o,icon:n,link:o,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),be=g(Ro,[["__scopeId","data-v-7bc22406"]]),qo={key:0,class:"group translations"},Jo={class:"trans-title"},Xo={key:1,class:"group"},Yo={class:"item appearance"},Qo={class:"label"},Zo={class:"appearance-action"},xo={key:2,class:"group"},es={class:"item social-links"},ts=m({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=L(),{localeLinks:o,currentLang:n}=q({correspondingLink:!0}),i=y(()=>o.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(l,v)=>i.value?(a(),k(ke,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:f(()=>[r(o).length&&r(n).label?(a(),u("div",qo,[d("p",Jo,I(r(n).label),1),(a(!0),u(w,null,H(r(o),p=>(a(),k(te,{key:p.link,item:p},null,8,["item"]))),128))])):h("",!0),r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Xo,[d("div",Yo,[d("p",Qo,I(r(t).darkModeSwitchLabel||"Appearance"),1),d("div",Zo,[_(me)])])])):h("",!0),r(t).socialLinks?(a(),u("div",xo,[d("div",es,[_(be,{class:"social-links-list",links:r(t).socialLinks},null,8,["links"])])])):h("",!0)]),_:1})):h("",!0)}}),ns=g(ts,[["__scopeId","data-v-bb2aa2f0"]]),os=["aria-expanded"],ss=m({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(a(),u("button",{type:"button",class:M(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=o=>e.$emit("click"))},t[1]||(t[1]=[d("span",{class:"container"},[d("span",{class:"top"}),d("span",{class:"middle"}),d("span",{class:"bottom"})],-1)]),10,os))}}),as=g(ss,[["__scopeId","data-v-e5dd9c1c"]]),rs=["innerHTML"],is=m({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=L();return(t,o)=>(a(),k(D,{class:M({VPNavBarMenuLink:!0,active:r(W)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,tabindex:"0"},{default:f(()=>[d("span",{innerHTML:t.item.text},null,8,rs)]),_:1},8,["class","href","target","rel","no-icon"]))}}),ls=g(is,[["__scopeId","data-v-e56f3d57"]]),cs=m({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=L(),o=i=>"component"in i?!1:"link"in i?W(t.value.relativePath,i.link,!!e.item.activeMatch):i.items.some(o),n=y(()=>o(e.item));return(i,l)=>(a(),k(ke,{class:M({VPNavBarMenuGroup:!0,active:r(W)(r(t).relativePath,i.item.activeMatch,!!i.item.activeMatch)||n.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),us={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},ds=m({__name:"VPNavBarMenu",setup(s){const{theme:e}=L();return(t,o)=>r(e).nav?(a(),u("nav",us,[o[0]||(o[0]=d("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(a(!0),u(w,null,H(r(e).nav,n=>(a(),u(w,{key:JSON.stringify(n)},["link"in n?(a(),k(ls,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props),null,16)):(a(),k(cs,{key:2,item:n},null,8,["item"]))],64))),128))])):h("",!0)}}),vs=g(ds,[["__scopeId","data-v-dc692963"]]);function ps(s){const{localeIndex:e,theme:t}=L();function o(n){var A,C,S;const i=n.split("."),l=(A=t.value.search)==null?void 0:A.options,v=l&&typeof l=="object",p=v&&((S=(C=l.locales)==null?void 0:C[e.value])==null?void 0:S.translations)||null,$=v&&l.translations||null;let V=p,b=$,P=s;const N=i.pop();for(const B of i){let G=null;const R=P==null?void 0:P[B];R&&(G=P=R);const ne=b==null?void 0:b[B];ne&&(G=b=ne);const oe=V==null?void 0:V[B];oe&&(G=V=oe),R||(P=G),ne||(b=G),oe||(V=G)}return(V==null?void 0:V[N])??(b==null?void 0:b[N])??(P==null?void 0:P[N])??""}return o}const fs=["aria-label"],hs={class:"DocSearch-Button-Container"},ms={class:"DocSearch-Button-Placeholder"},ge=m({__name:"VPNavBarSearchButton",setup(s){const t=ps({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(o,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(t)("button.buttonAriaLabel")},[d("span",hs,[n[0]||(n[0]=d("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),d("span",ms,I(r(t)("button.buttonText")),1)]),n[1]||(n[1]=d("span",{class:"DocSearch-Button-Keys"},[d("kbd",{class:"DocSearch-Button-Key"}),d("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,fs))}}),_s={class:"VPNavBarSearch"},ks={id:"local-search"},bs={key:1,id:"docsearch"},gs=m({__name:"VPNavBarSearch",setup(s){const e=je(()=>ze(()=>import("./VPLocalSearchBox.D3VOKMMh.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:o}=L(),n=T(!1),i=T(!1);j(()=>{});function l(){n.value||(n.value=!0,setTimeout(v,16))}function v(){const b=new Event("keydown");b.key="k",b.metaKey=!0,window.dispatchEvent(b),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||v()},16)}function p(b){const P=b.target,N=P.tagName;return P.isContentEditable||N==="INPUT"||N==="SELECT"||N==="TEXTAREA"}const $=T(!1);re("k",b=>{(b.ctrlKey||b.metaKey)&&(b.preventDefault(),$.value=!0)}),re("/",b=>{p(b)||(b.preventDefault(),$.value=!0)});const V="local";return(b,P)=>{var N;return a(),u("div",_s,[r(V)==="local"?(a(),u(w,{key:0},[$.value?(a(),k(r(e),{key:0,onClose:P[0]||(P[0]=A=>$.value=!1)})):h("",!0),d("div",ks,[_(ge,{onClick:P[1]||(P[1]=A=>$.value=!0)})])],64)):r(V)==="algolia"?(a(),u(w,{key:1},[n.value?(a(),k(r(t),{key:0,algolia:((N=r(o).search)==null?void 0:N.options)??r(o).algolia,onVnodeBeforeMount:P[2]||(P[2]=A=>i.value=!0)},null,8,["algolia"])):h("",!0),i.value?h("",!0):(a(),u("div",bs,[_(ge,{onClick:l})]))],64)):h("",!0)])}}}),$s=m({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=L();return(t,o)=>r(e).socialLinks?(a(),k(be,{key:0,class:"VPNavBarSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),ys=g($s,[["__scopeId","data-v-0394ad82"]]),Ps=["href","rel","target"],Ls=["innerHTML"],Vs={key:2},Ss=m({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=L(),{hasSidebar:o}=O(),{currentLang:n}=q(),i=y(()=>{var p;return typeof t.value.logoLink=="string"?t.value.logoLink:(p=t.value.logoLink)==null?void 0:p.link}),l=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.rel}),v=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.target});return(p,$)=>(a(),u("div",{class:M(["VPNavBarTitle",{"has-sidebar":r(o)}])},[d("a",{class:"title",href:i.value??r(fe)(r(n).link),rel:l.value,target:v.value},[c(p.$slots,"nav-bar-title-before",{},void 0,!0),r(t).logo?(a(),k(X,{key:0,class:"logo",image:r(t).logo},null,8,["image"])):h("",!0),r(t).siteTitle?(a(),u("span",{key:1,innerHTML:r(t).siteTitle},null,8,Ls)):r(t).siteTitle===void 0?(a(),u("span",Vs,I(r(e).title),1)):h("",!0),c(p.$slots,"nav-bar-title-after",{},void 0,!0)],8,Ps)],2))}}),Ts=g(Ss,[["__scopeId","data-v-1168a8e4"]]),Ns={class:"items"},Ms={class:"title"},Is=m({__name:"VPNavBarTranslations",setup(s){const{theme:e}=L(),{localeLinks:t,currentLang:o}=q({correspondingLink:!0});return(n,i)=>r(t).length&&r(o).label?(a(),k(ke,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:r(e).langMenuLabel||"Change language"},{default:f(()=>[d("div",Ns,[d("p",Ms,I(r(o).label),1),(a(!0),u(w,null,H(r(t),l=>(a(),k(te,{key:l.link,item:l},null,8,["item"]))),128))])]),_:1},8,["label"])):h("",!0)}}),ws=g(Is,[["__scopeId","data-v-88af2de4"]]),As={class:"wrapper"},Cs={class:"container"},Hs={class:"title"},Bs={class:"content"},Es={class:"content-body"},Ds=m({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const e=s,{y:t}=Se(),{hasSidebar:o}=O(),{frontmatter:n}=L(),i=T({});return pe(()=>{i.value={"has-sidebar":o.value,home:n.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(l,v)=>(a(),u("div",{class:M(["VPNavBar",i.value])},[d("div",As,[d("div",Cs,[d("div",Hs,[_(Ts,null,{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),d("div",Bs,[d("div",Es,[c(l.$slots,"nav-bar-content-before",{},void 0,!0),_(gs,{class:"search"}),_(vs,{class:"menu"}),_(ws,{class:"translations"}),_($o,{class:"appearance"}),_(ys,{class:"social-links"}),_(ns,{class:"extra"}),c(l.$slots,"nav-bar-content-after",{},void 0,!0),_(as,{class:"hamburger",active:l.isScreenOpen,onClick:v[0]||(v[0]=p=>l.$emit("toggle-screen"))},null,8,["active"])])])])]),v[1]||(v[1]=d("div",{class:"divider"},[d("div",{class:"divider-line"})],-1))],2))}}),Fs=g(Ds,[["__scopeId","data-v-6aa21345"]]),Os={key:0,class:"VPNavScreenAppearance"},Gs={class:"text"},Us=m({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=L();return(o,n)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Os,[d("p",Gs,I(r(t).darkModeSwitchLabel||"Appearance"),1),_(me)])):h("",!0)}}),js=g(Us,[["__scopeId","data-v-b44890b2"]]),zs=["innerHTML"],Ws=m({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(D,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[d("span",{innerHTML:t.item.text},null,8,zs)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),Ks=g(Ws,[["__scopeId","data-v-df37e6dd"]]),Rs=["innerHTML"],qs=m({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(D,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[d("span",{innerHTML:t.item.text},null,8,Rs)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),He=g(qs,[["__scopeId","data-v-3e9c20e4"]]),Js={class:"VPNavScreenMenuGroupSection"},Xs={key:0,class:"title"},Ys=m({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",Js,[e.text?(a(),u("p",Xs,I(e.text),1)):h("",!0),(a(!0),u(w,null,H(e.items,o=>(a(),k(He,{key:o.text,item:o},null,8,["item"]))),128))]))}}),Qs=g(Ys,[["__scopeId","data-v-8133b170"]]),Zs=["aria-controls","aria-expanded"],xs=["innerHTML"],ea=["id"],ta={key:0,class:"item"},na={key:1,class:"item"},oa={key:2,class:"group"},sa=m({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=T(!1),o=y(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(i,l)=>(a(),u("div",{class:M(["VPNavScreenMenuGroup",{open:t.value}])},[d("button",{class:"button","aria-controls":o.value,"aria-expanded":t.value,onClick:n},[d("span",{class:"button-text",innerHTML:i.text},null,8,xs),l[0]||(l[0]=d("span",{class:"vpi-plus button-icon"},null,-1))],8,Zs),d("div",{id:o.value,class:"items"},[(a(!0),u(w,null,H(i.items,v=>(a(),u(w,{key:JSON.stringify(v)},["link"in v?(a(),u("div",ta,[_(He,{item:v},null,8,["item"])])):"component"in v?(a(),u("div",na,[(a(),k(E(v.component),U({ref_for:!0},v.props,{"screen-menu":""}),null,16))])):(a(),u("div",oa,[_(Qs,{text:v.text,items:v.items},null,8,["text","items"])]))],64))),128))],8,ea)],2))}}),aa=g(sa,[["__scopeId","data-v-b9ab8c58"]]),ra={key:0,class:"VPNavScreenMenu"},ia=m({__name:"VPNavScreenMenu",setup(s){const{theme:e}=L();return(t,o)=>r(e).nav?(a(),u("nav",ra,[(a(!0),u(w,null,H(r(e).nav,n=>(a(),u(w,{key:JSON.stringify(n)},["link"in n?(a(),k(Ks,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props,{"screen-menu":""}),null,16)):(a(),k(aa,{key:2,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):h("",!0)}}),la=m({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=L();return(t,o)=>r(e).socialLinks?(a(),k(be,{key:0,class:"VPNavScreenSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),ca={class:"list"},ua=m({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=q({correspondingLink:!0}),o=T(!1);function n(){o.value=!o.value}return(i,l)=>r(e).length&&r(t).label?(a(),u("div",{key:0,class:M(["VPNavScreenTranslations",{open:o.value}])},[d("button",{class:"title",onClick:n},[l[0]||(l[0]=d("span",{class:"vpi-languages icon lang"},null,-1)),z(" "+I(r(t).label)+" ",1),l[1]||(l[1]=d("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),d("ul",ca,[(a(!0),u(w,null,H(r(e),v=>(a(),u("li",{key:v.link,class:"item"},[_(D,{class:"link",href:v.link},{default:f(()=>[z(I(v.text),1)]),_:2},1032,["href"])]))),128))])],2)):h("",!0)}}),da=g(ua,[["__scopeId","data-v-858fe1a4"]]),va={class:"container"},pa=m({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=T(null),t=Te(ee?document.body:null);return(o,n)=>(a(),k(ue,{name:"fade",onEnter:n[0]||(n[0]=i=>t.value=!0),onAfterLeave:n[1]||(n[1]=i=>t.value=!1)},{default:f(()=>[o.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[d("div",va,[c(o.$slots,"nav-screen-content-before",{},void 0,!0),_(ia,{class:"menu"}),_(da,{class:"translations"}),_(js,{class:"appearance"}),_(la,{class:"social-links"}),c(o.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):h("",!0)]),_:3}))}}),fa=g(pa,[["__scopeId","data-v-f2779853"]]),ha={key:0,class:"VPNav"},ma=m({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:o}=uo(),{frontmatter:n}=L(),i=y(()=>n.value.navbar!==!1);return Ne("close-screen",t),Y(()=>{ee&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(l,v)=>i.value?(a(),u("header",ha,[_(Fs,{"is-screen-open":r(e),onToggleScreen:r(o)},{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(l.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),_(fa,{open:r(e)},{"nav-screen-content-before":f(()=>[c(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):h("",!0)}}),_a=g(ma,[["__scopeId","data-v-ae24b3ad"]]),ka=["role","tabindex"],ba={key:1,class:"items"},ga=m({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:o,isLink:n,isActiveLink:i,hasActiveLink:l,hasChildren:v,toggle:p}=pt(y(()=>e.item)),$=y(()=>v.value?"section":"div"),V=y(()=>n.value?"a":"div"),b=y(()=>v.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),P=y(()=>n.value?void 0:"button"),N=y(()=>[[`level-${e.depth}`],{collapsible:o.value},{collapsed:t.value},{"is-link":n.value},{"is-active":i.value},{"has-active":l.value}]);function A(S){"key"in S&&S.key!=="Enter"||!e.item.link&&p()}function C(){e.item.link&&p()}return(S,B)=>{const G=K("VPSidebarItem",!0);return a(),k(E($.value),{class:M(["VPSidebarItem",N.value])},{default:f(()=>[S.item.text?(a(),u("div",U({key:0,class:"item",role:P.value},We(S.item.items?{click:A,keydown:A}:{},!0),{tabindex:S.item.items&&0}),[B[1]||(B[1]=d("div",{class:"indicator"},null,-1)),S.item.link?(a(),k(D,{key:0,tag:V.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:f(()=>[(a(),k(E(b.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),k(E(b.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:C,onKeydown:Ke(C,["enter"]),tabindex:"0"},B[0]||(B[0]=[d("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):h("",!0)],16,ka)):h("",!0),S.item.items&&S.item.items.length?(a(),u("div",ba,[S.depth<5?(a(!0),u(w,{key:0},H(S.item.items,R=>(a(),k(G,{key:R.text,item:R,depth:S.depth+1},null,8,["item","depth"]))),128)):h("",!0)])):h("",!0)]),_:1},8,["class"])}}}),$a=g(ga,[["__scopeId","data-v-b3fd67f8"]]),ya=m({__name:"VPSidebarGroup",props:{items:{}},setup(s){const e=T(!0);let t=null;return j(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),Re(()=>{t!=null&&(clearTimeout(t),t=null)}),(o,n)=>(a(!0),u(w,null,H(o.items,i=>(a(),u("div",{key:i.text,class:M(["group",{"no-transition":e.value}])},[_($a,{item:i,depth:0},null,8,["item"])],2))),128))}}),Pa=g(ya,[["__scopeId","data-v-c40bc020"]]),La={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},Va=m({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:e,hasSidebar:t}=O(),o=s,n=T(null),i=Te(ee?document.body:null);F([o,n],()=>{var v;o.open?(i.value=!0,(v=n.value)==null||v.focus()):i.value=!1},{immediate:!0,flush:"post"});const l=T(0);return F(e,()=>{l.value+=1},{deep:!0}),(v,p)=>r(t)?(a(),u("aside",{key:0,class:M(["VPSidebar",{open:v.open}]),ref_key:"navEl",ref:n,onClick:p[0]||(p[0]=qe(()=>{},["stop"]))},[p[2]||(p[2]=d("div",{class:"curtain"},null,-1)),d("nav",La,[p[1]||(p[1]=d("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),c(v.$slots,"sidebar-nav-before",{},void 0,!0),(a(),k(Pa,{items:r(e),key:l.value},null,8,["items"])),c(v.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):h("",!0)}}),Sa=g(Va,[["__scopeId","data-v-319d5ca6"]]),Ta=m({__name:"VPSkipLink",setup(s){const{theme:e}=L(),t=Z(),o=T();F(()=>t.path,()=>o.value.focus());function n({target:i}){const l=document.getElementById(decodeURIComponent(i.hash).slice(1));if(l){const v=()=>{l.removeAttribute("tabindex"),l.removeEventListener("blur",v)};l.setAttribute("tabindex","-1"),l.addEventListener("blur",v),l.focus(),window.scrollTo(0,0)}}return(i,l)=>(a(),u(w,null,[d("span",{ref_key:"backToTop",ref:o,tabindex:"-1"},null,512),d("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n},I(r(e).skipToContentLabel||"Skip to content"),1)],64))}}),Na=g(Ta,[["__scopeId","data-v-0b0ada53"]]),Ma=m({__name:"Layout",setup(s){const{isOpen:e,open:t,close:o}=O(),n=Z();F(()=>n.path,o),vt(e,o);const{frontmatter:i}=L(),l=Je(),v=y(()=>!!l["home-hero-image"]);return Ne("hero-image-slot-exists",v),(p,$)=>{const V=K("Content");return r(i).layout!==!1?(a(),u("div",{key:0,class:M(["Layout",r(i).pageClass])},[c(p.$slots,"layout-top",{},void 0,!0),_(Na),_(xe,{class:"backdrop",show:r(e),onClick:r(o)},null,8,["show","onClick"]),_(_a,null,{"nav-bar-title-before":f(()=>[c(p.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(p.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(p.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(p.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":f(()=>[c(p.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(p.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),_(co,{open:r(e),onOpenMenu:r(t)},null,8,["open","onOpenMenu"]),_(Sa,{open:r(e)},{"sidebar-nav-before":f(()=>[c(p.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":f(()=>[c(p.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),_(qn,null,{"page-top":f(()=>[c(p.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(p.$slots,"page-bottom",{},void 0,!0)]),"not-found":f(()=>[c(p.$slots,"not-found",{},void 0,!0)]),"home-hero-before":f(()=>[c(p.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(p.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(p.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(p.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(p.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(p.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(p.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(p.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(p.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":f(()=>[c(p.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(p.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(p.$slots,"doc-after",{},void 0,!0)]),"doc-top":f(()=>[c(p.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(p.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":f(()=>[c(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),_(Zn),c(p.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),k(V,{key:1}))}}}),Ia=g(Ma,[["__scopeId","data-v-5d98c3a5"]]),$e={Layout:Ia,enhanceApp:({app:s})=>{s.component("Badge",Ye)}},Aa={extends:$e,Layout:()=>Xe($e.Layout,null,{}),enhanceApp({app:s,router:e,siteData:t}){}};export{Aa as R,ps as c,L as u}; diff --git a/docs/.vitepress/dist/assets/chunks/theme.D24d9p6K.js b/docs/.vitepress/dist/assets/chunks/theme.D24d9p6K.js deleted file mode 100644 index c710e2e..0000000 --- a/docs/.vitepress/dist/assets/chunks/theme.D24d9p6K.js +++ /dev/null @@ -1 +0,0 @@ -import{d as m,c as u,r as c,n as N,o as a,a as z,t as M,b as k,w as f,T as ce,e as h,_ as b,u as Be,i as Ce,f as Ee,g as ue,h as $,j as v,k as r,l as W,m as ae,p as T,q as D,s as Q,v as j,x as de,y as ve,z as Fe,A as De,F as w,B,C as q,D as $e,E as X,G as _,H as E,I as ye,J as Z,K as U,L as x,M as Oe,N as Pe,O as Ge,P as Le,Q as Ve,R as ee,S as Ue,U as Se,V as Te,W as je,X as ze,Y as We,Z as qe,$ as Ke,a0 as Re}from"./framework.B8KKhRA6.js";const Je=m({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(a(),u("span",{class:N(["VPBadge",e.type])},[c(e.$slots,"default",{},()=>[z(M(e.text),1)])],2))}}),Ye={key:0,class:"VPBackdrop"},Qe=m({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(a(),k(ce,{name:"fade"},{default:f(()=>[e.show?(a(),u("div",Ye)):h("",!0)]),_:1}))}}),Xe=b(Qe,[["__scopeId","data-v-c79a1216"]]),P=Be;function Ze(s,e){let t,o=!1;return()=>{t&&clearTimeout(t),o?t=setTimeout(s,e):(s(),(o=!0)&&setTimeout(()=>o=!1,e))}}function re(s){return s.startsWith("/")?s:`/${s}`}function pe(s){const{pathname:e,search:t,hash:o,protocol:n}=new URL(s,"http://a.com");if(Ce(s)||s.startsWith("#")||!n.startsWith("http")||!Ee(e))return s;const{site:i}=P(),l=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${t}${o}`);return ue(l)}function R({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:o,theme:n,hash:i}=P(),l=$(()=>{var d,y;return{label:(d=e.value.locales[t.value])==null?void 0:d.label,link:((y=e.value.locales[t.value])==null?void 0:y.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:$(()=>Object.entries(e.value.locales).flatMap(([d,y])=>l.value.label===y.label?[]:{text:y.label,link:xe(y.link||(d==="root"?"/":`/${d}/`),n.value.i18nRouting!==!1&&s,o.value.relativePath.slice(l.value.link.length-1),!e.value.cleanUrls)+i.value})),currentLang:l}}function xe(s,e,t,o){return e?s.replace(/\/$/,"")+re(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,o?".html":"")):s}const et={class:"NotFound"},tt={class:"code"},nt={class:"title"},ot={class:"quote"},st={class:"action"},at=["href","aria-label"],rt=m({__name:"NotFound",setup(s){const{theme:e}=P(),{currentLang:t}=R();return(o,n)=>{var i,l,p,d,y;return a(),u("div",et,[v("p",tt,M(((i=r(e).notFound)==null?void 0:i.code)??"404"),1),v("h1",nt,M(((l=r(e).notFound)==null?void 0:l.title)??"PAGE NOT FOUND"),1),n[0]||(n[0]=v("div",{class:"divider"},null,-1)),v("blockquote",ot,M(((p=r(e).notFound)==null?void 0:p.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),v("div",st,[v("a",{class:"link",href:r(ue)(r(t).link),"aria-label":((d=r(e).notFound)==null?void 0:d.linkLabel)??"go to home"},M(((y=r(e).notFound)==null?void 0:y.linkText)??"Take me home"),9,at)])])}}}),it=b(rt,[["__scopeId","data-v-d6be1790"]]);function Ne(s,e){if(Array.isArray(s))return J(s);if(s==null)return[];e=re(e);const t=Object.keys(s).sort((n,i)=>i.split("/").length-n.split("/").length).find(n=>e.startsWith(re(n))),o=t?s[t]:[];return Array.isArray(o)?J(o):J(o.items,o.base)}function lt(s){const e=[];let t=0;for(const o in s){const n=s[o];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function ct(s){const e=[];function t(o){for(const n of o)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(s),e}function ie(s,e){return Array.isArray(e)?e.some(t=>ie(s,t)):W(s,e.link)?!0:e.items?ie(s,e.items):!1}function J(s,e){return[...s].map(t=>{const o={...t},n=o.base||e;return n&&o.link&&(o.link=n+o.link),o.items&&(o.items=J(o.items,n)),o})}function O(){const{frontmatter:s,page:e,theme:t}=P(),o=ae("(min-width: 960px)"),n=T(!1),i=$(()=>{const A=t.value.sidebar,S=e.value.relativePath;return A?Ne(A,S):[]}),l=T(i.value);D(i,(A,S)=>{JSON.stringify(A)!==JSON.stringify(S)&&(l.value=i.value)});const p=$(()=>s.value.sidebar!==!1&&l.value.length>0&&s.value.layout!=="home"),d=$(()=>y?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),y=$(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),L=$(()=>p.value&&o.value),g=$(()=>p.value?lt(l.value):[]);function V(){n.value=!0}function I(){n.value=!1}function H(){n.value?I():V()}return{isOpen:n,sidebar:l,sidebarGroups:g,hasSidebar:p,hasAside:y,leftAside:d,isSidebarEnabled:L,open:V,close:I,toggle:H}}function ut(s,e){let t;Q(()=>{t=s.value?document.activeElement:void 0}),j(()=>{window.addEventListener("keyup",o)}),de(()=>{window.removeEventListener("keyup",o)});function o(n){n.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function dt(s){const{page:e,hash:t}=P(),o=T(!1),n=$(()=>s.value.collapsed!=null),i=$(()=>!!s.value.link),l=T(!1),p=()=>{l.value=W(e.value.relativePath,s.value.link)};D([e,s,t],p),j(p);const d=$(()=>l.value?!0:s.value.items?ie(e.value.relativePath,s.value.items):!1),y=$(()=>!!(s.value.items&&s.value.items.length));Q(()=>{o.value=!!(n.value&&s.value.collapsed)}),ve(()=>{(l.value||d.value)&&(o.value=!1)});function L(){n.value&&(o.value=!o.value)}return{collapsed:o,collapsible:n,isLink:i,isActiveLink:l,hasActiveLink:d,hasChildren:y,toggle:L}}function vt(){const{hasSidebar:s}=O(),e=ae("(min-width: 960px)"),t=ae("(min-width: 1280px)");return{isAsideEnabled:$(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const pt=/\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/,le=[];function Me(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function fe(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const o=Number(t.tagName[1]);return{element:t,title:ft(t),link:"#"+t.id,level:o}});return ht(e,s)}function ft(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(pt.test(t.className))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function ht(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;return kt(s,o,n)}function mt(s,e){const{isAsideEnabled:t}=vt(),o=Ze(i,100);let n=null;j(()=>{requestAnimationFrame(i),window.addEventListener("scroll",o)}),Fe(()=>{l(location.hash)}),de(()=>{window.removeEventListener("scroll",o)});function i(){if(!t.value)return;const p=window.scrollY,d=window.innerHeight,y=document.body.offsetHeight,L=Math.abs(p+d-y)<1,g=le.map(({element:I,link:H})=>({link:H,top:_t(I)})).filter(({top:I})=>!Number.isNaN(I)).sort((I,H)=>I.top-H.top);if(!g.length){l(null);return}if(p<1){l(null);return}if(L){l(g[g.length-1].link);return}let V=null;for(const{link:I,top:H}of g){if(H>p+De()+4)break;V=I}l(V)}function l(p){n&&n.classList.remove("active"),p==null?n=null:n=s.value.querySelector(`a[href="${decodeURIComponent(p)}"]`);const d=n;d?(d.classList.add("active"),e.value.style.top=d.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function _t(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}function kt(s,e,t){le.length=0;const o=[],n=[];return s.forEach(i=>{const l={...i,children:[]};let p=n[n.length-1];for(;p&&p.level>=l.level;)n.pop(),p=n[n.length-1];if(l.element.classList.contains("ignore-header")||p&&"shouldIgnore"in p){n.push({level:l.level,shouldIgnore:!0});return}l.level>t||l.level{const n=q("VPDocOutlineItem",!0);return a(),u("ul",{class:N(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),u(w,null,B(t.headers,({children:i,link:l,title:p})=>(a(),u("li",null,[v("a",{class:"outline-link",href:l,onClick:e,title:p},M(p),9,bt),i!=null&&i.length?(a(),k(n,{key:0,headers:i},null,8,["headers"])):h("",!0)]))),256))],2)}}}),Ie=b(gt,[["__scopeId","data-v-b933a997"]]),$t={class:"content"},yt={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},Pt=m({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=P(),o=$e([]);X(()=>{o.value=fe(e.value.outline??t.value.outline)});const n=T(),i=T();return mt(n,i),(l,p)=>(a(),u("nav",{"aria-labelledby":"doc-outline-aria-label",class:N(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:n},[v("div",$t,[v("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),v("div",yt,M(r(Me)(r(t))),1),_(Ie,{headers:o.value,root:!0},null,8,["headers"])])],2))}}),Lt=b(Pt,[["__scopeId","data-v-a5bbad30"]]),Vt={class:"VPDocAsideCarbonAds"},St=m({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,o)=>(a(),u("div",Vt,[_(r(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Tt={class:"VPDocAside"},Nt=m({__name:"VPDocAside",setup(s){const{theme:e}=P();return(t,o)=>(a(),u("div",Tt,[c(t.$slots,"aside-top",{},void 0,!0),c(t.$slots,"aside-outline-before",{},void 0,!0),_(Lt),c(t.$slots,"aside-outline-after",{},void 0,!0),o[0]||(o[0]=v("div",{class:"spacer"},null,-1)),c(t.$slots,"aside-ads-before",{},void 0,!0),r(e).carbonAds?(a(),k(St,{key:0,"carbon-ads":r(e).carbonAds},null,8,["carbon-ads"])):h("",!0),c(t.$slots,"aside-ads-after",{},void 0,!0),c(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Mt=b(Nt,[["__scopeId","data-v-3f215769"]]);function It(){const{theme:s,page:e}=P();return $(()=>{const{text:t="Edit this page",pattern:o=""}=s.value.editLink||{};let n;return typeof o=="function"?n=o(e.value):n=o.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function wt(){const{page:s,theme:e,frontmatter:t}=P();return $(()=>{var y,L,g,V,I,H,A,S;const o=Ne(e.value.sidebar,s.value.relativePath),n=ct(o),i=Ht(n,C=>C.link.replace(/[?#].*$/,"")),l=i.findIndex(C=>W(s.value.relativePath,C.link)),p=((y=e.value.docFooter)==null?void 0:y.prev)===!1&&!t.value.prev||t.value.prev===!1,d=((L=e.value.docFooter)==null?void 0:L.next)===!1&&!t.value.next||t.value.next===!1;return{prev:p?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((g=i[l-1])==null?void 0:g.docFooterText)??((V=i[l-1])==null?void 0:V.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((I=i[l-1])==null?void 0:I.link)},next:d?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((H=i[l+1])==null?void 0:H.docFooterText)??((A=i[l+1])==null?void 0:A.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=i[l+1])==null?void 0:S.link)}}})}function Ht(s,e){const t=new Set;return s.filter(o=>{const n=e(o);return t.has(n)?!1:t.add(n)})}const F=m({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=$(()=>e.tag??(e.href?"a":"span")),o=$(()=>e.href&&ye.test(e.href)||e.target==="_blank");return(n,i)=>(a(),k(E(t.value),{class:N(["VPLink",{link:n.href,"vp-external-link-icon":o.value,"no-icon":n.noIcon}]),href:n.href?r(pe)(n.href):void 0,target:n.target??(o.value?"_blank":void 0),rel:n.rel??(o.value?"noreferrer":void 0)},{default:f(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),At={class:"VPLastUpdated"},Bt=["datetime"],Ct=m({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,lang:o}=P(),n=$(()=>new Date(t.value.lastUpdated)),i=$(()=>n.value.toISOString()),l=T("");return j(()=>{Q(()=>{var p,d,y;l.value=new Intl.DateTimeFormat((d=(p=e.value.lastUpdated)==null?void 0:p.formatOptions)!=null&&d.forceLocale?o.value:void 0,((y=e.value.lastUpdated)==null?void 0:y.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(n.value)})}),(p,d)=>{var y;return a(),u("p",At,[z(M(((y=r(e).lastUpdated)==null?void 0:y.text)||r(e).lastUpdatedText||"Last updated")+": ",1),v("time",{datetime:i.value},M(l.value),9,Bt)])}}}),Et=b(Ct,[["__scopeId","data-v-e98dd255"]]),Ft={key:0,class:"VPDocFooter"},Dt={key:0,class:"edit-info"},Ot={key:0,class:"edit-link"},Gt={key:1,class:"last-updated"},Ut={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},jt={class:"pager"},zt=["innerHTML"],Wt=["innerHTML"],qt={class:"pager"},Kt=["innerHTML"],Rt=["innerHTML"],Jt=m({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:o}=P(),n=It(),i=wt(),l=$(()=>e.value.editLink&&o.value.editLink!==!1),p=$(()=>t.value.lastUpdated),d=$(()=>l.value||p.value||i.value.prev||i.value.next);return(y,L)=>{var g,V,I,H;return d.value?(a(),u("footer",Ft,[c(y.$slots,"doc-footer-before",{},void 0,!0),l.value||p.value?(a(),u("div",Dt,[l.value?(a(),u("div",Ot,[_(F,{class:"edit-link-button",href:r(n).url,"no-icon":!0},{default:f(()=>[L[0]||(L[0]=v("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),z(" "+M(r(n).text),1)]),_:1,__:[0]},8,["href"])])):h("",!0),p.value?(a(),u("div",Gt,[_(Et)])):h("",!0)])):h("",!0),(g=r(i).prev)!=null&&g.link||(V=r(i).next)!=null&&V.link?(a(),u("nav",Ut,[L[1]||(L[1]=v("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),v("div",jt,[(I=r(i).prev)!=null&&I.link?(a(),k(F,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:f(()=>{var A;return[v("span",{class:"desc",innerHTML:((A=r(e).docFooter)==null?void 0:A.prev)||"Previous page"},null,8,zt),v("span",{class:"title",innerHTML:r(i).prev.text},null,8,Wt)]}),_:1},8,["href"])):h("",!0)]),v("div",qt,[(H=r(i).next)!=null&&H.link?(a(),k(F,{key:0,class:"pager-link next",href:r(i).next.link},{default:f(()=>{var A;return[v("span",{class:"desc",innerHTML:((A=r(e).docFooter)==null?void 0:A.next)||"Next page"},null,8,Kt),v("span",{class:"title",innerHTML:r(i).next.text},null,8,Rt)]}),_:1},8,["href"])):h("",!0)])])):h("",!0)])):h("",!0)}}}),Yt=b(Jt,[["__scopeId","data-v-e257564d"]]),Qt={class:"container"},Xt={class:"aside-container"},Zt={class:"aside-content"},xt={class:"content"},en={class:"content-container"},tn={class:"main"},nn=m({__name:"VPDoc",setup(s){const{theme:e}=P(),t=Z(),{hasSidebar:o,hasAside:n,leftAside:i}=O(),l=$(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(p,d)=>{const y=q("Content");return a(),u("div",{class:N(["VPDoc",{"has-sidebar":r(o),"has-aside":r(n)}])},[c(p.$slots,"doc-top",{},void 0,!0),v("div",Qt,[r(n)?(a(),u("div",{key:0,class:N(["aside",{"left-aside":r(i)}])},[d[0]||(d[0]=v("div",{class:"aside-curtain"},null,-1)),v("div",Xt,[v("div",Zt,[_(Mt,null,{"aside-top":f(()=>[c(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):h("",!0),v("div",xt,[v("div",en,[c(p.$slots,"doc-before",{},void 0,!0),v("main",tn,[_(y,{class:N(["vp-doc",[l.value,r(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),_(Yt,null,{"doc-footer-before":f(()=>[c(p.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(p.$slots,"doc-after",{},void 0,!0)])])]),c(p.$slots,"doc-bottom",{},void 0,!0)],2)}}}),on=b(nn,[["__scopeId","data-v-39a288b8"]]),sn=m({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=$(()=>e.href&&ye.test(e.href)),o=$(()=>e.tag||(e.href?"a":"button"));return(n,i)=>(a(),k(E(o.value),{class:N(["VPButton",[n.size,n.theme]]),href:n.href?r(pe)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:f(()=>[z(M(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),an=b(sn,[["__scopeId","data-v-fa7799d5"]]),rn=["src","alt"],ln=m({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const o=q("VPImage",!0);return e.image?(a(),u(w,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),u("img",U({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:r(ue)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,rn)):(a(),u(w,{key:1},[_(o,U({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),_(o,U({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):h("",!0)}}}),Y=b(ln,[["__scopeId","data-v-8426fc1a"]]),cn={class:"container"},un={class:"main"},dn={class:"heading"},vn=["innerHTML"],pn=["innerHTML"],fn=["innerHTML"],hn={key:0,class:"actions"},mn={key:0,class:"image"},_n={class:"image-container"},kn=m({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=x("hero-image-slot-exists");return(t,o)=>(a(),u("div",{class:N(["VPHero",{"has-image":t.image||r(e)}])},[v("div",cn,[v("div",un,[c(t.$slots,"home-hero-info-before",{},void 0,!0),c(t.$slots,"home-hero-info",{},()=>[v("h1",dn,[t.name?(a(),u("span",{key:0,innerHTML:t.name,class:"name clip"},null,8,vn)):h("",!0),t.text?(a(),u("span",{key:1,innerHTML:t.text,class:"text"},null,8,pn)):h("",!0)]),t.tagline?(a(),u("p",{key:0,innerHTML:t.tagline,class:"tagline"},null,8,fn)):h("",!0)],!0),c(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),u("div",hn,[(a(!0),u(w,null,B(t.actions,n=>(a(),u("div",{key:n.link,class:"action"},[_(an,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):h("",!0),c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||r(e)?(a(),u("div",mn,[v("div",_n,[o[0]||(o[0]=v("div",{class:"image-bg"},null,-1)),c(t.$slots,"home-hero-image",{},()=>[t.image?(a(),k(Y,{key:0,class:"image-src",image:t.image},null,8,["image"])):h("",!0)],!0)])])):h("",!0)])],2))}}),bn=b(kn,[["__scopeId","data-v-4f9c455b"]]),gn=m({__name:"VPHomeHero",setup(s){const{frontmatter:e}=P();return(t,o)=>r(e).hero?(a(),k(bn,{key:0,class:"VPHomeHero",name:r(e).hero.name,text:r(e).hero.text,tagline:r(e).hero.tagline,image:r(e).hero.image,actions:r(e).hero.actions},{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before")]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info")]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after")]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):h("",!0)}}),$n={class:"box"},yn={key:0,class:"icon"},Pn=["innerHTML"],Ln=["innerHTML"],Vn=["innerHTML"],Sn={key:4,class:"link-text"},Tn={class:"link-text-value"},Nn=m({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(a(),k(F,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:f(()=>[v("article",$n,[typeof e.icon=="object"&&e.icon.wrap?(a(),u("div",yn,[_(Y,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),k(Y,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),u("div",{key:2,class:"icon",innerHTML:e.icon},null,8,Pn)):h("",!0),v("h2",{class:"title",innerHTML:e.title},null,8,Ln),e.details?(a(),u("p",{key:3,class:"details",innerHTML:e.details},null,8,Vn)):h("",!0),e.linkText?(a(),u("div",Sn,[v("p",Tn,[z(M(e.linkText)+" ",1),t[0]||(t[0]=v("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):h("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Mn=b(Nn,[["__scopeId","data-v-a3976bdc"]]),In={key:0,class:"VPFeatures"},wn={class:"container"},Hn={class:"items"},An=m({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=$(()=>{const o=e.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,n)=>o.features?(a(),u("div",In,[v("div",wn,[v("div",Hn,[(a(!0),u(w,null,B(o.features,i=>(a(),u("div",{key:i.title,class:N(["item",[t.value]])},[_(Mn,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):h("",!0)}}),Bn=b(An,[["__scopeId","data-v-a6181336"]]),Cn=m({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=P();return(t,o)=>r(e).features?(a(),k(Bn,{key:0,class:"VPHomeFeatures",features:r(e).features},null,8,["features"])):h("",!0)}}),En=m({__name:"VPHomeContent",setup(s){const{width:e}=Oe({initialWidth:0,includeScrollbar:!1});return(t,o)=>(a(),u("div",{class:"vp-doc container",style:Pe(r(e)?{"--vp-offset":`calc(50% - ${r(e)/2}px)`}:{})},[c(t.$slots,"default",{},void 0,!0)],4))}}),Fn=b(En,[["__scopeId","data-v-8e2d4988"]]),Dn=m({__name:"VPHome",setup(s){const{frontmatter:e,theme:t}=P();return(o,n)=>{const i=q("Content");return a(),u("div",{class:N(["VPHome",{"external-link-icon-enabled":r(t).externalLinkIcon}])},[c(o.$slots,"home-hero-before",{},void 0,!0),_(gn,null,{"home-hero-info-before":f(()=>[c(o.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(o.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(o.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(o.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(o.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(o.$slots,"home-hero-after",{},void 0,!0),c(o.$slots,"home-features-before",{},void 0,!0),_(Cn),c(o.$slots,"home-features-after",{},void 0,!0),r(e).markdownStyles!==!1?(a(),k(Fn,{key:0},{default:f(()=>[_(i)]),_:1})):(a(),k(i,{key:1}))],2)}}}),On=b(Dn,[["__scopeId","data-v-8b561e3d"]]),Gn={},Un={class:"VPPage"};function jn(s,e){const t=q("Content");return a(),u("div",Un,[c(s.$slots,"page-top"),_(t),c(s.$slots,"page-bottom")])}const zn=b(Gn,[["render",jn]]),Wn=m({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=P(),{hasSidebar:o}=O();return(n,i)=>(a(),u("div",{class:N(["VPContent",{"has-sidebar":r(o),"is-home":r(t).layout==="home"}]),id:"VPContent"},[r(e).isNotFound?c(n.$slots,"not-found",{key:0},()=>[_(it)],!0):r(t).layout==="page"?(a(),k(zn,{key:1},{"page-top":f(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(t).layout==="home"?(a(),k(On,{key:2},{"home-hero-before":f(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(t).layout&&r(t).layout!=="doc"?(a(),k(E(r(t).layout),{key:3})):(a(),k(on,{key:4},{"doc-top":f(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":f(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":f(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":f(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":f(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),qn=b(Wn,[["__scopeId","data-v-1428d186"]]),Kn={class:"container"},Rn=["innerHTML"],Jn=["innerHTML"],Yn=m({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=P(),{hasSidebar:o}=O();return(n,i)=>r(e).footer&&r(t).footer!==!1?(a(),u("footer",{key:0,class:N(["VPFooter",{"has-sidebar":r(o)}])},[v("div",Kn,[r(e).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:r(e).footer.message},null,8,Rn)):h("",!0),r(e).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:r(e).footer.copyright},null,8,Jn)):h("",!0)])],2)):h("",!0)}}),Qn=b(Yn,[["__scopeId","data-v-e315a0ad"]]);function Xn(){const{theme:s,frontmatter:e}=P(),t=$e([]),o=$(()=>t.value.length>0);return X(()=>{t.value=fe(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:o}}const Zn={class:"menu-text"},xn={class:"header"},eo={class:"outline"},to=m({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=P(),o=T(!1),n=T(0),i=T(),l=T();function p(g){var V;(V=i.value)!=null&&V.contains(g.target)||(o.value=!1)}D(o,g=>{if(g){document.addEventListener("click",p);return}document.removeEventListener("click",p)}),Ge("Escape",()=>{o.value=!1}),X(()=>{o.value=!1});function d(){o.value=!o.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function y(g){g.target.classList.contains("outline-link")&&(l.value&&(l.value.style.transition="none"),Le(()=>{o.value=!1}))}function L(){o.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(g,V)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Pe({"--vp-vh":n.value+"px"}),ref_key:"main",ref:i},[g.headers.length>0?(a(),u("button",{key:0,onClick:d,class:N({open:o.value})},[v("span",Zn,M(r(Me)(r(t))),1),V[0]||(V[0]=v("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(a(),u("button",{key:1,onClick:L},M(r(t).returnToTopLabel||"Return to top"),1)),_(ce,{name:"flyout"},{default:f(()=>[o.value?(a(),u("div",{key:0,ref_key:"items",ref:l,class:"items",onClick:y},[v("div",xn,[v("a",{class:"top-link",href:"#",onClick:L},M(r(t).returnToTopLabel||"Return to top"),1)]),v("div",eo,[_(Ie,{headers:g.headers},null,8,["headers"])])],512)):h("",!0)]),_:1})],4))}}),no=b(to,[["__scopeId","data-v-8a42e2b4"]]),oo={class:"container"},so=["aria-expanded"],ao={class:"menu-text"},ro=m({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=P(),{hasSidebar:o}=O(),{headers:n}=Xn(),{y:i}=Ve(),l=T(0);j(()=>{l.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),X(()=>{n.value=fe(t.value.outline??e.value.outline)});const p=$(()=>n.value.length===0),d=$(()=>p.value&&!o.value),y=$(()=>({VPLocalNav:!0,"has-sidebar":o.value,empty:p.value,fixed:d.value}));return(L,g)=>r(t).layout!=="home"&&(!d.value||r(i)>=l.value)?(a(),u("div",{key:0,class:N(y.value)},[v("div",oo,[r(o)?(a(),u("button",{key:0,class:"menu","aria-expanded":L.open,"aria-controls":"VPSidebarNav",onClick:g[0]||(g[0]=V=>L.$emit("open-menu"))},[g[1]||(g[1]=v("span",{class:"vpi-align-left menu-icon"},null,-1)),v("span",ao,M(r(e).sidebarMenuLabel||"Menu"),1)],8,so)):h("",!0),_(no,{headers:r(n),navHeight:l.value},null,8,["headers","navHeight"])])],2)):h("",!0)}}),io=b(ro,[["__scopeId","data-v-a6f0e41e"]]);function lo(){const s=T(!1);function e(){s.value=!0,window.addEventListener("resize",n)}function t(){s.value=!1,window.removeEventListener("resize",n)}function o(){s.value?t():e()}function n(){window.outerWidth>=768&&t()}const i=Z();return D(()=>i.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:o}}const co={},uo={class:"VPSwitch",type:"button",role:"switch"},vo={class:"check"},po={key:0,class:"icon"};function fo(s,e){return a(),u("button",uo,[v("span",vo,[s.$slots.default?(a(),u("span",po,[c(s.$slots,"default",{},void 0,!0)])):h("",!0)])])}const ho=b(co,[["render",fo],["__scopeId","data-v-1d5665e3"]]),mo=m({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=P(),o=x("toggle-appearance",()=>{e.value=!e.value}),n=T("");return ve(()=>{n.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(i,l)=>(a(),k(ho,{title:n.value,class:"VPSwitchAppearance","aria-checked":r(e),onClick:r(o)},{default:f(()=>l[0]||(l[0]=[v("span",{class:"vpi-sun sun"},null,-1),v("span",{class:"vpi-moon moon"},null,-1)])),_:1,__:[0]},8,["title","aria-checked","onClick"]))}}),he=b(mo,[["__scopeId","data-v-5337faa4"]]),_o={key:0,class:"VPNavBarAppearance"},ko=m({__name:"VPNavBarAppearance",setup(s){const{site:e}=P();return(t,o)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",_o,[_(he)])):h("",!0)}}),bo=b(ko,[["__scopeId","data-v-6c893767"]]),me=T();let we=!1,se=0;function go(s){const e=T(!1);if(ee){!we&&$o(),se++;const t=D(me,o=>{var n,i,l;o===s.el.value||(n=s.el.value)!=null&&n.contains(o)?(e.value=!0,(i=s.onFocus)==null||i.call(s)):(e.value=!1,(l=s.onBlur)==null||l.call(s))});de(()=>{t(),se--,se||yo()})}return Ue(e)}function $o(){document.addEventListener("focusin",He),we=!0,me.value=document.activeElement}function yo(){document.removeEventListener("focusin",He)}function He(){me.value=document.activeElement}const Po={class:"VPMenuLink"},Lo=["innerHTML"],Vo=m({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=P();return(t,o)=>(a(),u("div",Po,[_(F,{class:N({active:r(W)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,Lo)]),_:1},8,["class","href","target","rel","no-icon"])]))}}),te=b(Vo,[["__scopeId","data-v-35975db6"]]),So={class:"VPMenuGroup"},To={key:0,class:"title"},No=m({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",So,[e.text?(a(),u("p",To,M(e.text),1)):h("",!0),(a(!0),u(w,null,B(e.items,o=>(a(),u(w,null,["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):h("",!0)],64))),256))]))}}),Mo=b(No,[["__scopeId","data-v-69e747b5"]]),Io={class:"VPMenu"},wo={key:0,class:"items"},Ho=m({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(a(),u("div",Io,[e.items?(a(),u("div",wo,[(a(!0),u(w,null,B(e.items,o=>(a(),u(w,{key:JSON.stringify(o)},["link"in o?(a(),k(te,{key:0,item:o},null,8,["item"])):"component"in o?(a(),k(E(o.component),U({key:1,ref_for:!0},o.props),null,16)):(a(),k(Mo,{key:2,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):h("",!0),c(e.$slots,"default",{},void 0,!0)]))}}),Ao=b(Ho,[["__scopeId","data-v-b98bc113"]]),Bo=["aria-expanded","aria-label"],Co={key:0,class:"text"},Eo=["innerHTML"],Fo={key:1,class:"vpi-more-horizontal icon"},Do={class:"menu"},Oo=m({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=T(!1),t=T();go({el:t,onBlur:o});function o(){e.value=!1}return(n,i)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:i[1]||(i[1]=l=>e.value=!0),onMouseleave:i[2]||(i[2]=l=>e.value=!1)},[v("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:i[0]||(i[0]=l=>e.value=!e.value)},[n.button||n.icon?(a(),u("span",Co,[n.icon?(a(),u("span",{key:0,class:N([n.icon,"option-icon"])},null,2)):h("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,Eo)):h("",!0),i[3]||(i[3]=v("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(a(),u("span",Fo))],8,Bo),v("div",Do,[_(Ao,{items:n.items},{default:f(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),_e=b(Oo,[["__scopeId","data-v-cf11d7a2"]]),Go=["href","aria-label","innerHTML"],Uo=m({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=T();j(async()=>{var i;await Le();const n=(i=t.value)==null?void 0:i.children[0];n instanceof HTMLElement&&n.className.startsWith("vpi-social-")&&(getComputedStyle(n).maskImage||getComputedStyle(n).webkitMaskImage)==="none"&&n.style.setProperty("--icon",`url('https://api.iconify.design/simple-icons/${e.icon}.svg')`)});const o=$(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,i)=>(a(),u("a",{ref_key:"el",ref:t,class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:o.value},null,8,Go))}}),jo=b(Uo,[["__scopeId","data-v-bd121fe5"]]),zo={class:"VPSocialLinks"},Wo=m({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(a(),u("div",zo,[(a(!0),u(w,null,B(e.links,({link:o,icon:n,ariaLabel:i})=>(a(),k(jo,{key:o,icon:n,link:o,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),ke=b(Wo,[["__scopeId","data-v-7bc22406"]]),qo={key:0,class:"group translations"},Ko={class:"trans-title"},Ro={key:1,class:"group"},Jo={class:"item appearance"},Yo={class:"label"},Qo={class:"appearance-action"},Xo={key:2,class:"group"},Zo={class:"item social-links"},xo=m({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=P(),{localeLinks:o,currentLang:n}=R({correspondingLink:!0}),i=$(()=>o.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(l,p)=>i.value?(a(),k(_e,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:f(()=>[r(o).length&&r(n).label?(a(),u("div",qo,[v("p",Ko,M(r(n).label),1),(a(!0),u(w,null,B(r(o),d=>(a(),k(te,{key:d.link,item:d},null,8,["item"]))),128))])):h("",!0),r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Ro,[v("div",Jo,[v("p",Yo,M(r(t).darkModeSwitchLabel||"Appearance"),1),v("div",Qo,[_(he)])])])):h("",!0),r(t).socialLinks?(a(),u("div",Xo,[v("div",Zo,[_(ke,{class:"social-links-list",links:r(t).socialLinks},null,8,["links"])])])):h("",!0)]),_:1})):h("",!0)}}),es=b(xo,[["__scopeId","data-v-bb2aa2f0"]]),ts=["aria-expanded"],ns=m({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(a(),u("button",{type:"button",class:N(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=o=>e.$emit("click"))},t[1]||(t[1]=[v("span",{class:"container"},[v("span",{class:"top"}),v("span",{class:"middle"}),v("span",{class:"bottom"})],-1)]),10,ts))}}),os=b(ns,[["__scopeId","data-v-e5dd9c1c"]]),ss=["innerHTML"],as=m({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=P();return(t,o)=>(a(),k(F,{class:N({VPNavBarMenuLink:!0,active:r(W)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,tabindex:"0"},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,ss)]),_:1},8,["class","href","target","rel","no-icon"]))}}),rs=b(as,[["__scopeId","data-v-e56f3d57"]]),is=m({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=P(),o=i=>"component"in i?!1:"link"in i?W(t.value.relativePath,i.link,!!e.item.activeMatch):i.items.some(o),n=$(()=>o(e.item));return(i,l)=>(a(),k(_e,{class:N({VPNavBarMenuGroup:!0,active:r(W)(r(t).relativePath,i.item.activeMatch,!!i.item.activeMatch)||n.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),ls={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},cs=m({__name:"VPNavBarMenu",setup(s){const{theme:e}=P();return(t,o)=>r(e).nav?(a(),u("nav",ls,[o[0]||(o[0]=v("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(a(!0),u(w,null,B(r(e).nav,n=>(a(),u(w,{key:JSON.stringify(n)},["link"in n?(a(),k(rs,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props),null,16)):(a(),k(is,{key:2,item:n},null,8,["item"]))],64))),128))])):h("",!0)}}),us=b(cs,[["__scopeId","data-v-dc692963"]]);function ds(s){const{localeIndex:e,theme:t}=P();function o(n){var H,A,S;const i=n.split("."),l=(H=t.value.search)==null?void 0:H.options,p=l&&typeof l=="object",d=p&&((S=(A=l.locales)==null?void 0:A[e.value])==null?void 0:S.translations)||null,y=p&&l.translations||null;let L=d,g=y,V=s;const I=i.pop();for(const C of i){let G=null;const K=V==null?void 0:V[C];K&&(G=V=K);const ne=g==null?void 0:g[C];ne&&(G=g=ne);const oe=L==null?void 0:L[C];oe&&(G=L=oe),K||(V=G),ne||(g=G),oe||(L=G)}return(L==null?void 0:L[I])??(g==null?void 0:g[I])??(V==null?void 0:V[I])??""}return o}const vs=["aria-label"],ps={class:"DocSearch-Button-Container"},fs={class:"DocSearch-Button-Placeholder"},be=m({__name:"VPNavBarSearchButton",setup(s){const t=ds({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(o,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(t)("button.buttonAriaLabel")},[v("span",ps,[n[0]||(n[0]=v("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),v("span",fs,M(r(t)("button.buttonText")),1)]),n[1]||(n[1]=v("span",{class:"DocSearch-Button-Keys"},[v("kbd",{class:"DocSearch-Button-Key"}),v("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,vs))}}),hs={class:"VPNavBarSearch"},ms={id:"local-search"},_s={key:1,id:"docsearch"},ks=m({__name:"VPNavBarSearch",setup(s){const e=()=>null,t=()=>null,{theme:o}=P(),n=T(!1),i=T(!1);j(()=>{});function l(){n.value||(n.value=!0,setTimeout(p,16))}function p(){const L=new Event("keydown");L.key="k",L.metaKey=!0,window.dispatchEvent(L),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||p()},16)}const d=T(!1),y="";return(L,g)=>{var V;return a(),u("div",hs,[r(y)==="local"?(a(),u(w,{key:0},[d.value?(a(),k(r(e),{key:0,onClose:g[0]||(g[0]=I=>d.value=!1)})):h("",!0),v("div",ms,[_(be,{onClick:g[1]||(g[1]=I=>d.value=!0)})])],64)):r(y)==="algolia"?(a(),u(w,{key:1},[n.value?(a(),k(r(t),{key:0,algolia:((V=r(o).search)==null?void 0:V.options)??r(o).algolia,onVnodeBeforeMount:g[2]||(g[2]=I=>i.value=!0)},null,8,["algolia"])):h("",!0),i.value?h("",!0):(a(),u("div",_s,[_(be,{onClick:l})]))],64)):h("",!0)])}}}),bs=m({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=P();return(t,o)=>r(e).socialLinks?(a(),k(ke,{key:0,class:"VPNavBarSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),gs=b(bs,[["__scopeId","data-v-0394ad82"]]),$s=["href","rel","target"],ys=["innerHTML"],Ps={key:2},Ls=m({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=P(),{hasSidebar:o}=O(),{currentLang:n}=R(),i=$(()=>{var d;return typeof t.value.logoLink=="string"?t.value.logoLink:(d=t.value.logoLink)==null?void 0:d.link}),l=$(()=>{var d;return typeof t.value.logoLink=="string"||(d=t.value.logoLink)==null?void 0:d.rel}),p=$(()=>{var d;return typeof t.value.logoLink=="string"||(d=t.value.logoLink)==null?void 0:d.target});return(d,y)=>(a(),u("div",{class:N(["VPNavBarTitle",{"has-sidebar":r(o)}])},[v("a",{class:"title",href:i.value??r(pe)(r(n).link),rel:l.value,target:p.value},[c(d.$slots,"nav-bar-title-before",{},void 0,!0),r(t).logo?(a(),k(Y,{key:0,class:"logo",image:r(t).logo},null,8,["image"])):h("",!0),r(t).siteTitle?(a(),u("span",{key:1,innerHTML:r(t).siteTitle},null,8,ys)):r(t).siteTitle===void 0?(a(),u("span",Ps,M(r(e).title),1)):h("",!0),c(d.$slots,"nav-bar-title-after",{},void 0,!0)],8,$s)],2))}}),Vs=b(Ls,[["__scopeId","data-v-1168a8e4"]]),Ss={class:"items"},Ts={class:"title"},Ns=m({__name:"VPNavBarTranslations",setup(s){const{theme:e}=P(),{localeLinks:t,currentLang:o}=R({correspondingLink:!0});return(n,i)=>r(t).length&&r(o).label?(a(),k(_e,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:r(e).langMenuLabel||"Change language"},{default:f(()=>[v("div",Ss,[v("p",Ts,M(r(o).label),1),(a(!0),u(w,null,B(r(t),l=>(a(),k(te,{key:l.link,item:l},null,8,["item"]))),128))])]),_:1},8,["label"])):h("",!0)}}),Ms=b(Ns,[["__scopeId","data-v-88af2de4"]]),Is={class:"wrapper"},ws={class:"container"},Hs={class:"title"},As={class:"content"},Bs={class:"content-body"},Cs=m({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const e=s,{y:t}=Ve(),{hasSidebar:o}=O(),{frontmatter:n}=P(),i=T({});return ve(()=>{i.value={"has-sidebar":o.value,home:n.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(l,p)=>(a(),u("div",{class:N(["VPNavBar",i.value])},[v("div",Is,[v("div",ws,[v("div",Hs,[_(Vs,null,{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),v("div",As,[v("div",Bs,[c(l.$slots,"nav-bar-content-before",{},void 0,!0),_(ks,{class:"search"}),_(us,{class:"menu"}),_(Ms,{class:"translations"}),_(bo,{class:"appearance"}),_(gs,{class:"social-links"}),_(es,{class:"extra"}),c(l.$slots,"nav-bar-content-after",{},void 0,!0),_(os,{class:"hamburger",active:l.isScreenOpen,onClick:p[0]||(p[0]=d=>l.$emit("toggle-screen"))},null,8,["active"])])])])]),p[1]||(p[1]=v("div",{class:"divider"},[v("div",{class:"divider-line"})],-1))],2))}}),Es=b(Cs,[["__scopeId","data-v-6aa21345"]]),Fs={key:0,class:"VPNavScreenAppearance"},Ds={class:"text"},Os=m({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=P();return(o,n)=>r(e).appearance&&r(e).appearance!=="force-dark"&&r(e).appearance!=="force-auto"?(a(),u("div",Fs,[v("p",Ds,M(r(t).darkModeSwitchLabel||"Appearance"),1),_(he)])):h("",!0)}}),Gs=b(Os,[["__scopeId","data-v-b44890b2"]]),Us=["innerHTML"],js=m({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(F,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,Us)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),zs=b(js,[["__scopeId","data-v-df37e6dd"]]),Ws=["innerHTML"],qs=m({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=x("close-screen");return(t,o)=>(a(),k(F,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:r(e)},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,Ws)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),Ae=b(qs,[["__scopeId","data-v-3e9c20e4"]]),Ks={class:"VPNavScreenMenuGroupSection"},Rs={key:0,class:"title"},Js=m({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",Ks,[e.text?(a(),u("p",Rs,M(e.text),1)):h("",!0),(a(!0),u(w,null,B(e.items,o=>(a(),k(Ae,{key:o.text,item:o},null,8,["item"]))),128))]))}}),Ys=b(Js,[["__scopeId","data-v-8133b170"]]),Qs=["aria-controls","aria-expanded"],Xs=["innerHTML"],Zs=["id"],xs={key:0,class:"item"},ea={key:1,class:"item"},ta={key:2,class:"group"},na=m({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=T(!1),o=$(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(i,l)=>(a(),u("div",{class:N(["VPNavScreenMenuGroup",{open:t.value}])},[v("button",{class:"button","aria-controls":o.value,"aria-expanded":t.value,onClick:n},[v("span",{class:"button-text",innerHTML:i.text},null,8,Xs),l[0]||(l[0]=v("span",{class:"vpi-plus button-icon"},null,-1))],8,Qs),v("div",{id:o.value,class:"items"},[(a(!0),u(w,null,B(i.items,p=>(a(),u(w,{key:JSON.stringify(p)},["link"in p?(a(),u("div",xs,[_(Ae,{item:p},null,8,["item"])])):"component"in p?(a(),u("div",ea,[(a(),k(E(p.component),U({ref_for:!0},p.props,{"screen-menu":""}),null,16))])):(a(),u("div",ta,[_(Ys,{text:p.text,items:p.items},null,8,["text","items"])]))],64))),128))],8,Zs)],2))}}),oa=b(na,[["__scopeId","data-v-b9ab8c58"]]),sa={key:0,class:"VPNavScreenMenu"},aa=m({__name:"VPNavScreenMenu",setup(s){const{theme:e}=P();return(t,o)=>r(e).nav?(a(),u("nav",sa,[(a(!0),u(w,null,B(r(e).nav,n=>(a(),u(w,{key:JSON.stringify(n)},["link"in n?(a(),k(zs,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props,{"screen-menu":""}),null,16)):(a(),k(oa,{key:2,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):h("",!0)}}),ra=m({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=P();return(t,o)=>r(e).socialLinks?(a(),k(ke,{key:0,class:"VPNavScreenSocialLinks",links:r(e).socialLinks},null,8,["links"])):h("",!0)}}),ia={class:"list"},la=m({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=R({correspondingLink:!0}),o=T(!1);function n(){o.value=!o.value}return(i,l)=>r(e).length&&r(t).label?(a(),u("div",{key:0,class:N(["VPNavScreenTranslations",{open:o.value}])},[v("button",{class:"title",onClick:n},[l[0]||(l[0]=v("span",{class:"vpi-languages icon lang"},null,-1)),z(" "+M(r(t).label)+" ",1),l[1]||(l[1]=v("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),v("ul",ia,[(a(!0),u(w,null,B(r(e),p=>(a(),u("li",{key:p.link,class:"item"},[_(F,{class:"link",href:p.link},{default:f(()=>[z(M(p.text),1)]),_:2},1032,["href"])]))),128))])],2)):h("",!0)}}),ca=b(la,[["__scopeId","data-v-858fe1a4"]]),ua={class:"container"},da=m({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=T(null),t=Se(ee?document.body:null);return(o,n)=>(a(),k(ce,{name:"fade",onEnter:n[0]||(n[0]=i=>t.value=!0),onAfterLeave:n[1]||(n[1]=i=>t.value=!1)},{default:f(()=>[o.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[v("div",ua,[c(o.$slots,"nav-screen-content-before",{},void 0,!0),_(aa,{class:"menu"}),_(ca,{class:"translations"}),_(Gs,{class:"appearance"}),_(ra,{class:"social-links"}),c(o.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):h("",!0)]),_:3}))}}),va=b(da,[["__scopeId","data-v-f2779853"]]),pa={key:0,class:"VPNav"},fa=m({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:o}=lo(),{frontmatter:n}=P(),i=$(()=>n.value.navbar!==!1);return Te("close-screen",t),Q(()=>{ee&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(l,p)=>i.value?(a(),u("header",pa,[_(Es,{"is-screen-open":r(e),onToggleScreen:r(o)},{"nav-bar-title-before":f(()=>[c(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(l.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),_(va,{open:r(e)},{"nav-screen-content-before":f(()=>[c(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):h("",!0)}}),ha=b(fa,[["__scopeId","data-v-ae24b3ad"]]),ma=["role","tabindex"],_a={key:1,class:"items"},ka=m({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:o,isLink:n,isActiveLink:i,hasActiveLink:l,hasChildren:p,toggle:d}=dt($(()=>e.item)),y=$(()=>p.value?"section":"div"),L=$(()=>n.value?"a":"div"),g=$(()=>p.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),V=$(()=>n.value?void 0:"button"),I=$(()=>[[`level-${e.depth}`],{collapsible:o.value},{collapsed:t.value},{"is-link":n.value},{"is-active":i.value},{"has-active":l.value}]);function H(S){"key"in S&&S.key!=="Enter"||!e.item.link&&d()}function A(){e.item.link&&d()}return(S,C)=>{const G=q("VPSidebarItem",!0);return a(),k(E(y.value),{class:N(["VPSidebarItem",I.value])},{default:f(()=>[S.item.text?(a(),u("div",U({key:0,class:"item",role:V.value},je(S.item.items?{click:H,keydown:H}:{},!0),{tabindex:S.item.items&&0}),[C[1]||(C[1]=v("div",{class:"indicator"},null,-1)),S.item.link?(a(),k(F,{key:0,tag:L.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:f(()=>[(a(),k(E(g.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),k(E(g.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:A,onKeydown:ze(A,["enter"]),tabindex:"0"},C[0]||(C[0]=[v("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):h("",!0)],16,ma)):h("",!0),S.item.items&&S.item.items.length?(a(),u("div",_a,[S.depth<5?(a(!0),u(w,{key:0},B(S.item.items,K=>(a(),k(G,{key:K.text,item:K,depth:S.depth+1},null,8,["item","depth"]))),128)):h("",!0)])):h("",!0)]),_:1},8,["class"])}}}),ba=b(ka,[["__scopeId","data-v-b3fd67f8"]]),ga=m({__name:"VPSidebarGroup",props:{items:{}},setup(s){const e=T(!0);let t=null;return j(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),We(()=>{t!=null&&(clearTimeout(t),t=null)}),(o,n)=>(a(!0),u(w,null,B(o.items,i=>(a(),u("div",{key:i.text,class:N(["group",{"no-transition":e.value}])},[_(ba,{item:i,depth:0},null,8,["item"])],2))),128))}}),$a=b(ga,[["__scopeId","data-v-c40bc020"]]),ya={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},Pa=m({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:e,hasSidebar:t}=O(),o=s,n=T(null),i=Se(ee?document.body:null);D([o,n],()=>{var p;o.open?(i.value=!0,(p=n.value)==null||p.focus()):i.value=!1},{immediate:!0,flush:"post"});const l=T(0);return D(e,()=>{l.value+=1},{deep:!0}),(p,d)=>r(t)?(a(),u("aside",{key:0,class:N(["VPSidebar",{open:p.open}]),ref_key:"navEl",ref:n,onClick:d[0]||(d[0]=qe(()=>{},["stop"]))},[d[2]||(d[2]=v("div",{class:"curtain"},null,-1)),v("nav",ya,[d[1]||(d[1]=v("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),c(p.$slots,"sidebar-nav-before",{},void 0,!0),(a(),k($a,{items:r(e),key:l.value},null,8,["items"])),c(p.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):h("",!0)}}),La=b(Pa,[["__scopeId","data-v-319d5ca6"]]),Va=m({__name:"VPSkipLink",setup(s){const{theme:e}=P(),t=Z(),o=T();D(()=>t.path,()=>o.value.focus());function n({target:i}){const l=document.getElementById(decodeURIComponent(i.hash).slice(1));if(l){const p=()=>{l.removeAttribute("tabindex"),l.removeEventListener("blur",p)};l.setAttribute("tabindex","-1"),l.addEventListener("blur",p),l.focus(),window.scrollTo(0,0)}}return(i,l)=>(a(),u(w,null,[v("span",{ref_key:"backToTop",ref:o,tabindex:"-1"},null,512),v("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n},M(r(e).skipToContentLabel||"Skip to content"),1)],64))}}),Sa=b(Va,[["__scopeId","data-v-0b0ada53"]]),Ta=m({__name:"Layout",setup(s){const{isOpen:e,open:t,close:o}=O(),n=Z();D(()=>n.path,o),ut(e,o);const{frontmatter:i}=P(),l=Ke(),p=$(()=>!!l["home-hero-image"]);return Te("hero-image-slot-exists",p),(d,y)=>{const L=q("Content");return r(i).layout!==!1?(a(),u("div",{key:0,class:N(["Layout",r(i).pageClass])},[c(d.$slots,"layout-top",{},void 0,!0),_(Sa),_(Xe,{class:"backdrop",show:r(e),onClick:r(o)},null,8,["show","onClick"]),_(ha,null,{"nav-bar-title-before":f(()=>[c(d.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(d.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(d.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(d.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":f(()=>[c(d.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(d.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),_(io,{open:r(e),onOpenMenu:r(t)},null,8,["open","onOpenMenu"]),_(La,{open:r(e)},{"sidebar-nav-before":f(()=>[c(d.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":f(()=>[c(d.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),_(qn,null,{"page-top":f(()=>[c(d.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(d.$slots,"page-bottom",{},void 0,!0)]),"not-found":f(()=>[c(d.$slots,"not-found",{},void 0,!0)]),"home-hero-before":f(()=>[c(d.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(d.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(d.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(d.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(d.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(d.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(d.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(d.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(d.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":f(()=>[c(d.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(d.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(d.$slots,"doc-after",{},void 0,!0)]),"doc-top":f(()=>[c(d.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(d.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":f(()=>[c(d.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(d.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(d.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(d.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(d.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(d.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),_(Qn),c(d.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),k(L,{key:1}))}}}),Na=b(Ta,[["__scopeId","data-v-5d98c3a5"]]),ge={Layout:Na,enhanceApp:({app:s})=>{s.component("Badge",Je)}},Ia={extends:ge,Layout:()=>Re(ge.Layout,null,{}),enhanceApp({app:s,router:e,siteData:t}){}};export{Ia as R}; diff --git a/docs/.vitepress/dist/assets/coredataeditor_2x.C-_TZgB_.png b/docs/.vitepress/dist/assets/coredataeditor_2x.C-_TZgB_.png new file mode 100644 index 0000000..b091a3f Binary files /dev/null and b/docs/.vitepress/dist/assets/coredataeditor_2x.C-_TZgB_.png differ diff --git a/docs/.vitepress/dist/assets/coredatanamespace_2x.DT2Ua0ZZ.png b/docs/.vitepress/dist/assets/coredatanamespace_2x.DT2Ua0ZZ.png new file mode 100644 index 0000000..c2bf691 Binary files /dev/null and b/docs/.vitepress/dist/assets/coredatanamespace_2x.DT2Ua0ZZ.png differ diff --git a/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.js b/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.js new file mode 100644 index 0000000..ad98fc2 --- /dev/null +++ b/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.js @@ -0,0 +1 @@ +import{_ as n,c as t,o as r,j as e,a as i}from"./chunks/framework.BHpayLOB.js";const x=JSON.parse('{"title":"前端工程化","description":"","frontmatter":{},"headers":[],"relativePath":"engineering/index.md","filePath":"engineering/index.md"}'),o={name:"engineering/index.md"};function s(d,a,c,l,p,m){return r(),t("div",null,a[0]||(a[0]=[e("h1",{id:"前端工程化",tabindex:"-1"},[i("前端工程化 "),e("a",{class:"header-anchor",href:"#前端工程化","aria-label":'Permalink to "前端工程化"'},"​")],-1),e("p",null,"待更新...",-1)]))}const _=n(o,[["render",s]]);export{x as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.lean.js b/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.lean.js new file mode 100644 index 0000000..ad98fc2 --- /dev/null +++ b/docs/.vitepress/dist/assets/engineering_index.md.B2wQBafC.lean.js @@ -0,0 +1 @@ +import{_ as n,c as t,o as r,j as e,a as i}from"./chunks/framework.BHpayLOB.js";const x=JSON.parse('{"title":"前端工程化","description":"","frontmatter":{},"headers":[],"relativePath":"engineering/index.md","filePath":"engineering/index.md"}'),o={name:"engineering/index.md"};function s(d,a,c,l,p,m){return r(),t("div",null,a[0]||(a[0]=[e("h1",{id:"前端工程化",tabindex:"-1"},[i("前端工程化 "),e("a",{class:"header-anchor",href:"#前端工程化","aria-label":'Permalink to "前端工程化"'},"​")],-1),e("p",null,"待更新...",-1)]))}const _=n(o,[["render",s]]);export{x as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.js b/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.js new file mode 100644 index 0000000..2295fc4 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.js @@ -0,0 +1 @@ +import{_ as d,c as a,o as e,ag as r}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"XML 常见转义字符","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/base/xml-tips.md","filePath":"frontend/base/xml-tips.md"}'),o={name:"frontend/base/xml-tips.md"};function l(s,t,m,n,p,i){return e(),a("div",null,t[0]||(t[0]=[r('

XML 常见转义字符

XML常见用转义字符

html 转义字符

字符转义字符描述
&&amp;
<&lt;小于号
>&gt;大于号
"&quot;双引号
'&apos;单引号
&nbsp;空格
©&copy;版权符
®&reg;注册符

在iOS 开发中,如遇到native与js交互的时候,使用js向web传值的时候就会遇到js报错。使用转义字符转义后的字符串就可以正常的传递。

date: 2019-04-25 10:00:00 author: "Gao Fei"

',6)]))}const c=d(o,[["render",l]]);export{_ as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.lean.js b/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.lean.js new file mode 100644 index 0000000..dfb9767 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_base_xml-tips.md.CjgTKY38.lean.js @@ -0,0 +1 @@ +import{_ as d,c as a,o as e,ag as r}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"XML 常见转义字符","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/base/xml-tips.md","filePath":"frontend/base/xml-tips.md"}'),o={name:"frontend/base/xml-tips.md"};function l(s,t,m,n,p,i){return e(),a("div",null,t[0]||(t[0]=[r("",6)]))}const c=d(o,[["render",l]]);export{_ as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.js b/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.js new file mode 100644 index 0000000..e86ca61 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.js @@ -0,0 +1 @@ +import{_ as e,c as i,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const r="/img/apple/1-1.png",s="/img/apple/2-1-0.png",n="/img/apple/2-1-1.png",l="/img/apple/2-1-2.png",d="/img/apple/2-1-3.png",p="/img/apple/2-1-4.png",c="/img/apple/2-2-1.png",m="/img/apple/2-2-2.png",g="/img/apple/2-2-3.png",_="/img/apple/2-2-4.png",u="/img/apple/2-3-0.png",P="/img/apple/2-3-1.png",h="/img/apple/2-3-2.png",f="/img/apple/2-3-3.png",q="/img/apple/2-3-4.png",C="/img/apple/2-4-1.png",b="/img/apple/2-4-2.png",A="/img/apple/2-4-3.png",v="/img/apple/2-4-4.png",x="/img/apple/2-4-5.png",D="/img/apple/3-1-1.png",I="/img/apple/3-1-2.png",S="/img/apple/3-1-3.png",N="/img/apple/3-1-4.png",k="/img/apple/3-2.png",w=JSON.parse('{"title":"更新 App store 发布证书","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/apple-update-cert.md","filePath":"frontend/ios/apple-update-cert.md"}'),R={name:"frontend/ios/apple-update-cert.md"};function B(O,t,T,$,y,E){return a(),i("div",null,t[0]||(t[0]=[o('

更新 App store 发布证书

分三步去更新

  1. 首先找到已过期的APP ID;
  2. 根据APP ID重新生成Certifictes;
  3. 更新Provisioning Profiles.

示例

1.确定已过期的 APP ID

1.1 找到已过期或者即将过期的 APP ID(Xcode 中为bundle id),位于图图1-1中3所在位置。将该 APP ID (以下简称id)记录下来。 图1-1

2.根据APP ID重新生成Certifictes

2.1 点击 Certificates 中的 Production可以看到所有的生产环境的证书,同时也可以看到是否过期。选择右上角的新建+,如下图所示。

选择证书的适用的场景, (1)Development 对应 xcode 中的debug环境,开发调试的使用,包含了推送与非推送版本。 (2)Production 对应 xcode 中的 release 环境,也即是上线 app store 的环境, 常用的是有不带推送的、带推送的、带apple pay的证书。 示例就以生产中带推送的做参考,选择 Apple Push Notification, 点击Continue。 选择需要更新的APP ID, 点击Continue 出现创建CSR文件的界面,里面说明了创建的步骤。下面我们按照步骤创建CSR。 在mac应用程序中找到 “钥匙串访问”,打开“钥匙串访问”app, 在导航栏中点击“钥匙串访问”-> "证书助理" -> "从证书颁发机构请求证书", 输入邮箱地址,常用名称,选择存储到磁盘,点击“继续”.其中常用名称可以采用公司名称+app名称+环境名 输入名称名称, 选择存储位置, 点击"存储". 将请求下来的的CSR证书保存在桌面上。 回到创建证书的页面,点击"Continu" 出现选择证书的页面,点击"Choose File..." 找到之前创建的CSR文件,点击"选取" 上传CSR文件, 点击“Continue” 上传完成之后,证书就生成完毕, 点击"Download",下载到本地磁盘。 下载完毕后会得到一个aps.cer证书, 但是不能直接发给别人使用, 需要双击cer文件,安装到钥匙串中,然后导出为.p12文件.

接下来说明一下导出P12文件给服务器使用。 在钥匙串中找到对应id的证书(可以通过id+证书名称确定) 选择导出“Apple Push Service: xxxxx” 弹出保存框, 输入存储名称,选择存储位置,点击"存储"。存储名称建议使用公司名称+app名称+环境+apns的形式,方便以管理。 输入导出的密码, 此密码用于其他人员读取P12文件时使用。 输入电脑登录用户的密码,点击“允许”。此处成功导出P12推送证书。备注:有的服务器只识别pem格式的文件,需要将P12格式转换为pem格式的。 再次回到apple deleloper 页面,找到已过期的的描述文件(Provisioning Profiles),点击“Edit”, 选择对应的App ID 以及 Certificates, 点击 “Generate” 到此新的Provisioning Profiles 已生成,点击"Download" 刚才已过期的 Provisioning Profiles 的 Status has changed to Active 按照同样的方式,更新development 下的Certificates & Provisioning Profiles 一共产生了5个文件,如下图所示

序列示例名称说明
1BOCI_appName_development_apns.p12Apple Push Development Certificatexcode debug app
2BOCI_appName_distribution_apns.p12Apple Push Production Certificatexcode release app/backend push server
3BOCI_appName_distribution_apns.mobileprovisionProduction Provisioning Profilesxcode release app
4BOCI_appName_development_apns.mobileprovisionDevelopment Provisioning Profilesxcode debug app
5BOCI_appName_distribution_apns.certSigningRequestCSR自己保留

将1-4的文件发送给开发人员,开发人员根据新的证书重新打包ipa,上线发布app就可以了。

2019-04-28

',13)]))}const F=e(R,[["render",B]]);export{w as __pageData,F as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.lean.js b/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.lean.js new file mode 100644 index 0000000..d3dbfee --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_apple-update-cert.md.4HxgwTte.lean.js @@ -0,0 +1 @@ +import{_ as e,c as i,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const r="/img/apple/1-1.png",s="/img/apple/2-1-0.png",n="/img/apple/2-1-1.png",l="/img/apple/2-1-2.png",d="/img/apple/2-1-3.png",p="/img/apple/2-1-4.png",c="/img/apple/2-2-1.png",m="/img/apple/2-2-2.png",g="/img/apple/2-2-3.png",_="/img/apple/2-2-4.png",u="/img/apple/2-3-0.png",P="/img/apple/2-3-1.png",h="/img/apple/2-3-2.png",f="/img/apple/2-3-3.png",q="/img/apple/2-3-4.png",C="/img/apple/2-4-1.png",b="/img/apple/2-4-2.png",A="/img/apple/2-4-3.png",v="/img/apple/2-4-4.png",x="/img/apple/2-4-5.png",D="/img/apple/3-1-1.png",I="/img/apple/3-1-2.png",S="/img/apple/3-1-3.png",N="/img/apple/3-1-4.png",k="/img/apple/3-2.png",w=JSON.parse('{"title":"更新 App store 发布证书","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/apple-update-cert.md","filePath":"frontend/ios/apple-update-cert.md"}'),R={name:"frontend/ios/apple-update-cert.md"};function B(O,t,T,$,y,E){return a(),i("div",null,t[0]||(t[0]=[o("",13)]))}const F=e(R,[["render",B]]);export{w as __pageData,F as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.js b/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.js new file mode 100644 index 0000000..f221c85 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as p,ag as r}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Appstore","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/appstore-share.md","filePath":"frontend/ios/appstore-share.md"}'),o={name:"frontend/ios/appstore-share.md"};function s(n,e,i,c,l,d){return p(),a("div",null,e[0]||(e[0]=[r('

Appstore


##关于app强制更新的itunes地址

通过微信的测试结果 https://itunes.apple.com/cn/app/we--chat/id414478124?mt=8https://itunes.apple.com/cn/app/id414478124?mt=8https://itunes.apple.com/cn/app/微信/id414478124?mt=8 都可以找到app的下载地址 格式如下 https://itunes.apple.com/cn/app/应用名称/id?mt=8 应用的名称:可以没有 id414478124 :必须有,id后面的数值 为Apple ID,开发者账号中可以查看到该应用的地址 mt=8 :参数可以没有,也可以等于其他值,即mt=7等等。

date: 2017-09-15 16:00:00 author: "Gao Fei"

',5)]))}const _=t(o,[["render",s]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.lean.js b/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.lean.js new file mode 100644 index 0000000..715caf9 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_appstore-share.md.B_qI_911.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as p,ag as r}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Appstore","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/appstore-share.md","filePath":"frontend/ios/appstore-share.md"}'),o={name:"frontend/ios/appstore-share.md"};function s(n,e,i,c,l,d){return p(),a("div",null,e[0]||(e[0]=[r("",5)]))}const _=t(o,[["render",s]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.js b/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.js new file mode 100644 index 0000000..50d3137 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.js @@ -0,0 +1,8 @@ +import{_ as s,c as e,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/autoPackage-tips.md","filePath":"frontend/ios/autoPackage-tips.md"}'),p={name:"frontend/ios/autoPackage-tips.md"};function o(c,a,i,l,r,d){return n(),e("div",null,a[0]||(a[0]=[t(`

#自动打包测试流程 1、将AutoPackageShell文件夹放到项目根目录下 2、打开autoPackageShell.sh文件,修改下列项目参数成你要打包的项目:

# 是否编译工作空间 (例:若是用Cocopods管理的.xcworkspace项目,赋值true;用Xcode默认创建的.xcodeproj,赋值false)
+is_workspace="false"
+#scheme名(一般是Target名)
+scheme_name="MobileAssistant_SIT"
+#指定项目名称
+project_name="MobileAssistant"
+# 指定要打包编译的方式 : Release,Debug...
+build_configuration="Release"

3、打开exportOptionsPlist.plist文件,把teamID改成打包证书的teamID

4、打开终端,cd到AutoPackageShell文件夹,输入命令 sh autoPackageShell.sh  回车

备注:Xcode 安装了多个版本之后,可以将目标打包的Xcode名称(eg:Xcode8.2.app)改为Xcode.app teamID可以在xxx.xcodeproj包文件中==project.pbxproj==,找到==DEVELOPMENT_TEAM==的值

date: 2017-06-01 16:00:00 author: "Gao Fei"

`,6)]))}const g=s(p,[["render",o]]);export{_ as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.lean.js b/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.lean.js new file mode 100644 index 0000000..9d6fc41 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_autoPackage-tips.md.COCidwNT.lean.js @@ -0,0 +1 @@ +import{_ as s,c as e,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/autoPackage-tips.md","filePath":"frontend/ios/autoPackage-tips.md"}'),p={name:"frontend/ios/autoPackage-tips.md"};function o(c,a,i,l,r,d){return n(),e("div",null,a[0]||(a[0]=[t("",6)]))}const g=s(p,[["render",o]]);export{_ as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.js b/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.js new file mode 100644 index 0000000..42f64e7 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.js @@ -0,0 +1,26 @@ +import{_ as a,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"cocoapods 入门","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/cocoapods.md","filePath":"frontend/ios/cocoapods.md"}'),o={name:"frontend/ios/cocoapods.md"};function c(l,s,t,i,d,r){return p(),n("div",null,s[0]||(s[0]=[e(`

cocoapods 入门

COCOAPODS 入门

1. cocoapods

特点

# 查看gem源地址,如果显示为默认源 https://rubygems.org/,需要考虑替换
+$ $gem sources -l
+# 移除系统 ruby 默认源
+$gem sources --remove https://rubygems.org/
+# 使用新的源
+$gem source -a https://gems.ruby-china.com
+# 验证是否安装成功
+$gem sources -l
+# 安装最新版本
+$sudo gem install -n /usr/local/bin cocoapods
+
+# 安装指定版本
+$sudo gem install -n /usr/local/bin cocoapods -v 1.0.0
+# 安装
+$pod setup

2. 初始化项目

cd 到需要创建项目的目录下
+$ ng new <projectname>
+# 1. 先创建,再安装
+$ ng new <projectname> --skip-install
+$ cd <projectname>
+$ cnpm install
+
+#运行
+$ ng serve --open
+
+#创建组件,在app目录下,创建components目录并创建home组件
+$ ng g component components/home

date: 2020-03-24 14:00:00 author: "Gao Fei"

`,8)]))}const m=a(o,[["render",c]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.lean.js b/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.lean.js new file mode 100644 index 0000000..1bb1f82 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_cocoapods.md.Bbev3CRS.lean.js @@ -0,0 +1 @@ +import{_ as a,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"cocoapods 入门","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/cocoapods.md","filePath":"frontend/ios/cocoapods.md"}'),o={name:"frontend/ios/cocoapods.md"};function c(l,s,t,i,d,r){return p(),n("div",null,s[0]||(s[0]=[e("",8)]))}const m=a(o,[["render",c]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.js b/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.js new file mode 100644 index 0000000..83fac51 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.js @@ -0,0 +1,7 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Download issues","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/download-share.md","filePath":"frontend/ios/download-share.md"}'),o={name:"frontend/ios/download-share.md"};function i(l,a,p,d,r,c){return e(),n("div",null,a[0]||(a[0]=[t(`

Download issues

下载问题

  • (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location; 使用该方法的时候,注意事项: 1. location 为一个零时的目录,在当前线程中出了{},就会立即清除。 2. 如果下载的delegate队列为 [NSOperationQueue mainQueue],在该方法中使用异步队列复制或移动下载的零时文件(CFNetworkDownload_OCZZDW.tmp)时,会提示找不到location目录(该零时文件)。 3. 如果下载的队列为[[NSOperationQueue alloc] init],该方法已经在异步队列中,记得在主队列中返回数据
			// NSOperation
+			[[NSOperationQueue mainQueue] addOperationWithBlock:^{
+       		 // 需要回调的结果
+    		}];
			// GCD
+			dispatch_barrier_async(dispatch_get_main_queue(), ^{
+        		// 需要回调的结果
+    		});

NSOperation 的使用

load...

date: 2017-09-18 16:00:00 author: "Gao Fei"

`,8)]))}const _=s(o,[["render",i]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.lean.js b/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.lean.js new file mode 100644 index 0000000..2c1950c --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_download-share.md.r3iHDhjb.lean.js @@ -0,0 +1 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Download issues","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/download-share.md","filePath":"frontend/ios/download-share.md"}'),o={name:"frontend/ios/download-share.md"};function i(l,a,p,d,r,c){return e(),n("div",null,a[0]||(a[0]=[t("",8)]))}const _=s(o,[["render",i]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.js b/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.js new file mode 100644 index 0000000..da79deb --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.js @@ -0,0 +1,15 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/flutter.md","filePath":"frontend/ios/flutter.md"}'),p={name:"frontend/ios/flutter.md"};function l(i,a,r,o,c,d){return e(),n("div",null,a[0]||(a[0]=[t(`

Flutter 入门

1. Flutter 介绍

  • 三重缓存
  • Skia 渲染引擎
  • Dart 语言学习
  • Flutter 学习
  1. 下载 flutter SDK

  2. 配置环境变量, 在~/.bash_profile 下增加如下内容:

# flutter
+#国内用户需要设置
+export PUB_HOSTED_URL=https://pub.flutter-io.cn
+export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+# flutter bin
+export FLUTTER_HOME=/Users/gaofei/development/flutter/bin
+# dart bin
+export DART_HOME=$FLUTTER_HOME/cache/dart-sdk/bin
+export PATH=$FLUTTER_HOME:$PATH
+export PATH="\${DART_HOME}:\${PATH}"

在环境配置完毕后,一般是重新电脑才会生效,如果想要立即生效,执行以下指令

source <相应文件配置文件>
+
+#示例
+source ~/.bash_profile

注意: 如果你使用的是zsh,终端启动时 ~/.bash_profile 将不会被加载,解决办法就是修改 ~/.zshrc ,在其中添加与 ~/.bash_profile 内相同的环境

vi ~/.zshrc
+# 输入环境后保存,然后再启动
+source ~/.zshrc

2. Flutter

添加的仓库包括 http://apt.saurik.com

3. Dart

3.1 变量 var const final dynamic 定义字符串,可以是 单引号,双引号,三引号 \${} 替换变量 集合 接口与抽象类 函数的返回值 函数的可选参数 - 位置可选参数[],命名可选参数{} 函数只有可选参数 有默认值 没有的函数的重载 函数是一等公民,函数A可以作为另外一个B的参数,也可以作为函数B的返回值。 匿名函数,箭头函数(函数体只有1行);

赋值运算符 ??= 当原来的变量有值时,就不执行 ?? 前面的数据有值,那么就使用??前面的数据,相当于三目运算符的简写 级联运算符

面向对象 类

`,16)]))}const _=s(p,[["render",l]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.lean.js b/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.lean.js new file mode 100644 index 0000000..9f28a3d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_flutter.md.DFpOWWZg.lean.js @@ -0,0 +1 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/flutter.md","filePath":"frontend/ios/flutter.md"}'),p={name:"frontend/ios/flutter.md"};function l(i,a,r,o,c,d){return e(),n("div",null,a[0]||(a[0]=[t("",16)]))}const _=s(p,[["render",l]]);export{h as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.js b/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.js new file mode 100644 index 0000000..50d41e9 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.js @@ -0,0 +1 @@ +import{_ as o,c as r,o as a,ag as t}from"./chunks/framework.BHpayLOB.js";const n=JSON.parse('{"title":"Cocoa Touch Framework","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/framework-share.md","filePath":"frontend/ios/framework-share.md"}'),c={name:"frontend/ios/framework-share.md"};function s(i,e,d,p,l,u){return a(),r("div",null,e[0]||(e[0]=[t('

Cocoa Touch Framework

###打包framework(Cocoa Touch Framework)

xcode打包需要配置

1.检查基本的配置

2.选择支持的最低版本

  1. 改为静态打包(对于ios8以上的系统,可以使用动态库(Dynamic Library))
  1. 导入工程中.m与 .h文件

合并模拟器与真机版本

在终端输入

lipo -create 【模拟器打包path】 【真机打包path】 -output 【导出兼容版本path】 如下: lipo -create /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/Release-iphonesimulator/FSNetworkAccesser.framework/FSNetworkAccesser /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/Release-iphoneos/FSNetworkAccesser.framework/FSNetworkAccesser -output /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/FSNetworkAccesser

对于打包到Bundle中的文件,在其他地方使用[NSBundle mainBundle]不能访问库文件中bundle的资源文件

静态库(Cocoa Touch Static Library)

date: 2017-09-18 16:00:00 author: "Gao Fei"

',13)]))}const h=o(c,[["render",s]]);export{n as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.lean.js b/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.lean.js new file mode 100644 index 0000000..c72096c --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_framework-share.md.K-VOmPO9.lean.js @@ -0,0 +1 @@ +import{_ as o,c as r,o as a,ag as t}from"./chunks/framework.BHpayLOB.js";const n=JSON.parse('{"title":"Cocoa Touch Framework","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/framework-share.md","filePath":"frontend/ios/framework-share.md"}'),c={name:"frontend/ios/framework-share.md"};function s(i,e,d,p,l,u){return a(),r("div",null,e[0]||(e[0]=[t("",13)]))}const h=o(c,[["render",s]]);export{n as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.js b/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.js new file mode 100644 index 0000000..7ef0ad8 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as t,ag as p}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"使用iTunes获取ipa","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/get-ipa.md","filePath":"frontend/ios/get-ipa.md"}'),l={name:"frontend/ios/get-ipa.md"};function n(s,e,o,r,u,c){return t(),a("div",null,e[0]||(e[0]=[p('

使用iTunes获取ipa

目前使用iTunes 12.7以上的版本已经无法下载ipa包,故需要安装iTunes 12.6以下的版本 安装连接:https://support.apple.com/en-us/HT208079 注意: 最新的安装版本为12.6.5,不支持macOS Mojave

步骤:

  1. 下载旧版本的 iTunes 12.6

  2. 卸载原有的iTunes 12.7 以上的版本 (如果在提示不能删除iTunes,则需要按以下的步骤进行)

    • 重启电脑,在重启的过程中按住command+R组合键进入到恢复工具界面,然后点击“实用工具”选项卡中的“终端”一栏,
    • 进入终端以后,在终端中csrutil disable命令,看到提示成功以后就解除权限控制了,
    • 再次重启电脑,打开终端,在终端中输入命令:cd /Applications,
    • 输入命令:rm -rf iTunes.app,
    • 重启电脑,然后按住command+R进入进入到恢复工具界面,打开终端,在终端中输入命令:csrutil enable.
  3. 删除Music/iTunes 目录下的所有所有文件

  4. 安装下载好的iTunes 12.6.5.dmg

  5. 任意下载自己需要的app

date: 2018-12-31 14:00:00 author: "Gao Fei"

',5)]))}const m=i(l,[["render",n]]);export{_ as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.lean.js b/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.lean.js new file mode 100644 index 0000000..b8727f6 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_get-ipa.md.Cj8aHUTQ.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as t,ag as p}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"使用iTunes获取ipa","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/get-ipa.md","filePath":"frontend/ios/get-ipa.md"}'),l={name:"frontend/ios/get-ipa.md"};function n(s,e,o,r,u,c){return t(),a("div",null,e[0]||(e[0]=[p("",5)]))}const m=i(l,[["render",n]]);export{_ as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.js b/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.js new file mode 100644 index 0000000..512e420 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.js @@ -0,0 +1 @@ +import{_ as e,c as a,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"IM Introduction","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/im-first.md","filePath":"frontend/ios/im-first.md"}'),d={name:"frontend/ios/im-first.md"};function i(n,t,l,c,s,h){return r(),a("div",null,t[0]||(t[0]=[o('

IM Introduction

IM 即时通讯技术 介绍

应用场景

即时通信的常用应用场景:即实时性要求高的场景,常见的如下: 视频会议、聊天、私信 弹幕、抽奖 互动游戏 协同编辑 股票基金实时报价、体育实况更新、 基于位置的应用:Uber、滴滴司机位置 在线教育 智能家居

基本的发展阶段

轮询-》长轮询-》长连接

注意长短连接与长短轮询的区别 概念范畴:长短轮询是应用层概念、长短连接是传输层概念 协商方式:一个 TCP 连接是否为长连接,是通过设置 HTTP 的 Connection Header 来决定的,而且是需要两边都设置才有效。而一种轮询方式是否为长轮询,是根据服务端的处理方式来决定的,与客户端没有关系。 实现方式:连接的长短是通过协议来规定和实现的。而轮询的长短,是服务器通过编程的方式手动挂起请求来实现的

数据传输格式

自定义二进制 开源协议:protocol buffers 文本协议(json\\xml)

常见的实现方式

  1. 基于Scoket:代表框架:CocoaAsyncSocket
  2. 基于WebScoket: SocketRocket
  3. 基于MQTT: MQTTKit
  4. 基于XMPP: XMPPFramework
名称协议举例优点缺点
SocketSocket+protocol buffers
WebScoketWebScoket+json高效、节约流量(比如使用protocol buffers,或压缩json格式),ios Android web三端通用对设计者要求高
MQTT协议简单,流量少、订阅+推送模式并不是专门为IM设计的协议,多用于推送
XMPPScoket+xml开源、可扩展性强、方便接入XML表现力差、额外信息多、流量耗费大

重连机制

TCP KeepAlive机制心跳机制
检测连接的状态检测通信双方的存活状态
在定时的时间(一般为7200s)到后, 发送相应的KeepAlive探针,
失败后重试10次,每次超时时间75s通常可设置3-5min发Ping

date: 2017-11-27 16:00:00 author: "Gao Fei"

',15)]))}const m=e(d,[["render",i]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.lean.js b/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.lean.js new file mode 100644 index 0000000..3a29434 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_im-first.md.C0UI8p3Z.lean.js @@ -0,0 +1 @@ +import{_ as e,c as a,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"IM Introduction","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/im-first.md","filePath":"frontend/ios/im-first.md"}'),d={name:"frontend/ios/im-first.md"};function i(n,t,l,c,s,h){return r(),a("div",null,t[0]||(t[0]=[o("",15)]))}const m=e(d,[["render",i]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.js b/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.js new file mode 100644 index 0000000..4e879b6 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.js @@ -0,0 +1,107 @@ +import{_ as s,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Image","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/image-on-iphone.md","filePath":"frontend/ios/image-on-iphone.md"}'),i={name:"frontend/ios/image-on-iphone.md"};function l(t,n,o,r,c,m){return p(),a("div",null,n[0]||(n[0]=[e(`

Image

The record related to Image

iPhone拍照的部分图片在windows上显示被旋转的问题

/**
 旋转图片
+
+ 解决在window 系统中 不能识别UIImageOrientationRight时的方向值,
+ 会出现逆时针90,所以
+ 
+ @param image 原图
+ @return 新图
+ */
++ (UIImage *)rotateImage:(UIImage *) image
+{
+   
+    @autoreleasepool {
+        CGImageRef imgRef = image.CGImage;
+        
+        CGFloat width = CGImageGetWidth(imgRef);
+        CGFloat height = CGImageGetHeight(imgRef);
+        
+        
+        CGAffineTransform transform = CGAffineTransformIdentity;
+        CGRect bounds = CGRectMake(0, 0, width, height);
+
+        CGFloat scaleRatio = bounds.size.width / width;
+        CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
+        CGFloat boundHeight;
+        UIImageOrientation orient = image.imageOrientation;
+        switch(orient) {
+                
+            case UIImageOrientationUp: //EXIF = 1
+                transform = CGAffineTransformIdentity;
+                break;
+                
+            case UIImageOrientationUpMirrored: //EXIF = 2
+                transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
+                transform = CGAffineTransformScale(transform, -1.0, 1.0);
+                break;
+                
+            case UIImageOrientationDown: //EXIF = 3
+                transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
+                transform = CGAffineTransformRotate(transform, M_PI);
+                break;
+                
+            case UIImageOrientationDownMirrored: //EXIF = 4
+                transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
+                transform = CGAffineTransformScale(transform, 1.0, -1.0);
+                break;
+                
+            case UIImageOrientationLeftMirrored: //EXIF = 5
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
+                transform = CGAffineTransformScale(transform, -1.0, 1.0);
+                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationLeft: //EXIF = 8
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
+                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationRightMirrored: //EXIF = 7
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeScale(-1.0, 1.0);
+                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationRight: //EXIF = 6
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
+                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
+                break;
+                
+            default:
+                [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
+                
+        }
+        
+        UIGraphicsBeginImageContext(bounds.size);
+        
+        CGContextRef context = UIGraphicsGetCurrentContext();
+        
+        if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
+            CGContextScaleCTM(context, -scaleRatio, scaleRatio);
+            CGContextTranslateCTM(context, -height, 0);
+        }
+        else {
+            CGContextScaleCTM(context, scaleRatio, -scaleRatio);
+            CGContextTranslateCTM(context, 0, -height);
+        }
+        
+        CGContextConcatCTM(context, transform);
+        
+        CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
+        UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
+        UIGraphicsEndImageContext();
+        
+        return imageCopy;
+
+    }
+}

date: 2017-11-27 16:00:00 author: "Gao Fei"

`,5)]))}const g=s(i,[["render",l]]);export{h as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.lean.js b/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.lean.js new file mode 100644 index 0000000..8fb55fb --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_image-on-iphone.md.BLfaLcNU.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Image","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/image-on-iphone.md","filePath":"frontend/ios/image-on-iphone.md"}'),i={name:"frontend/ios/image-on-iphone.md"};function l(t,n,o,r,c,m){return p(),a("div",null,n[0]||(n[0]=[e("",5)]))}const g=s(i,[["render",l]]);export{h as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.js b/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.js new file mode 100644 index 0000000..a161ff0 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.js @@ -0,0 +1 @@ +import{_ as l,c as a,o as t,ag as p}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"iOS App 程序启动过程","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/index.md","filePath":"frontend/ios/index.md"}'),e={name:"frontend/ios/index.md"};function n(o,i,c,r,d,s){return t(),a("div",null,i[0]||(i[0]=[p('

iOS App 程序启动过程

在main函数中进行的设置UIApplication对象的代理。 App容易受到干扰。正在玩游戏,一个电话打过来了。

  • 应用程序的生命周期事件(如程序启动和关闭)
  • 系统事件(如来电)
  • 内存警告
  • … … ** 处理这些干扰事件,就要用到AppDelegate代理对象了。 ** 总结: AppDelegate的主要作用就是处理(监听)应用程序本身的各种事件:
  • 应用程序启动完毕
  • 应用程序进入后台
  • 应用程序进入前台
  • 内存警告
  • 等等, 都是应用程序自身的一些事件 ** 要想成为UIApplication的代理对象, 必须遵守:UIApplicationDelegate协议。 ** 代理中的若干方法介绍:
    • (BOOL)application: didFinishLaunchingWithOptions: // app第一次启动完毕后就会调用(当程序启动后会显示一张启动图片, 当这个图片显示完毕, 消失后, 就开始调用这个方法)
    • (void)applicationDidEnterBackground:(UIApplication *)application // 当程序进入后台时, 调用该方法。(比如:按了Home键, 或者一个电话打过来了, 当前程序都会进入后台。) // 在这个方法中可以做一些保存当前程序数据, 暂停程序的操作。
    • (void)applicationWillEnterForeground:(UIApplication *)application // 当程序再次进入前台的时候调用。
    • (void)applicationDidReceiveMemoryWarning:(UIApplication *)application // 当发生内存警告时触发该事件。 程序启动后: didFinishLaunchingWithOptions-->applicationDidBecomeActive 按home键使程序进入后台:applicationWillResignActive--->applicationDidEnterBackground 让程序会到主界面:applicationWillEnterForeground--->applicationDidBecomeActive 在主界面时让程序退出:applicationDidEnterBackground--->applicationWillTerminate 在后台时退出:applicationWillTerminate

date: 2017-04-22 16:00:00 author: "Gao Fei"

',5)]))}const g=l(e,[["render",n]]);export{_ as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.lean.js b/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.lean.js new file mode 100644 index 0000000..2eedc10 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_index.md.CTrSx6HD.lean.js @@ -0,0 +1 @@ +import{_ as l,c as a,o as t,ag as p}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"iOS App 程序启动过程","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/index.md","filePath":"frontend/ios/index.md"}'),e={name:"frontend/ios/index.md"};function n(o,i,c,r,d,s){return t(),a("div",null,i[0]||(i[0]=[p("",5)]))}const g=l(e,[["render",n]]);export{_ as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.js b/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.js new file mode 100644 index 0000000..6c046e6 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.js @@ -0,0 +1,4 @@ +import{_ as e,c as s,o as t,ag as i}from"./chunks/framework.BHpayLOB.js";const b=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/jailbreak.md","filePath":"frontend/ios/jailbreak.md"}'),n={name:"frontend/ios/jailbreak.md"};function r(l,a,o,p,d,c){return t(),s("div",null,a[0]||(a[0]=[i(`

Jailbreak 入门

1. Jailbreak 工具

  • ios 10 推荐 安装 meridia 来越狱,越狱为 非完美越狱,在手机系统从新启动时 需要从新 越狱操作
  • iOS 11 以上 推荐安装 unc0ver
#  ios 10 Jailbreak 工具,使用手机 safari 打开一下连接
+https://kubadownload.com/news/meridian-jailbreak/
+#   unc0ver 工具
+https://unc0ver.dev

2. 添加仓库源

添加的仓库包括 http://apt.saurik.com

date: 2020-05-12 14:00:00 author: "Gao Fei"

`,8)]))}const u=e(n,[["render",r]]);export{b as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.lean.js b/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.lean.js new file mode 100644 index 0000000..adfa903 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_jailbreak.md.CZwC3MmJ.lean.js @@ -0,0 +1 @@ +import{_ as e,c as s,o as t,ag as i}from"./chunks/framework.BHpayLOB.js";const b=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/jailbreak.md","filePath":"frontend/ios/jailbreak.md"}'),n={name:"frontend/ios/jailbreak.md"};function r(l,a,o,p,d,c){return t(),s("div",null,a[0]||(a[0]=[i("",8)]))}const u=e(n,[["render",r]]);export{b as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.js b/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.js new file mode 100644 index 0000000..156e935 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as i,ag as r}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"琐碎的记录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/lock-share.md","filePath":"frontend/ios/lock-share.md"}'),o={name:"frontend/ios/lock-share.md"};function l(p,a,n,h,s,c){return i(),t("div",null,a[0]||(a[0]=[r('

琐碎的记录

数据存储方式对比

  1. plist文件 可以存储的数据类型:Number(interger,real),String,Boolean(false,true),Date,Data,Array,Dictionary

  2. NSUserDefaults 数据类型 NSString, NSData, NSNumber(NSInteger,float,double), NSDate, NSArray, NSDictionary and NSURL

  3. NSKeyedArchiver / NSKeyedUnarchiver 数据类型 NSData

  4. Sqlite

  5. CoreData

关于锁:

OSSpinLock 自旋锁,性能最高的锁。原理很简单,就是一直 do while 忙等。它的缺点是当等待时会消耗大量 CPU 资源,所以它不适用于较长时间的任务。对于内存缓存的存取来说,它非常合适。 NSDictionary + OSSpinLock 实现高性能缓存

dispatch_semaphore 是信号量,但当信号总量设为 1 时也可以当作锁来。在没有等待情况出现时,它的性能比 pthread_mutex 还要高,但一旦有等待情况出现时,性能就会下降许多。相对于 OSSpinLock 来说,它的优势在于等待时不会消耗 CPU 资源。对磁盘缓存来说,它比较合适。

磁盘缓存

1 基于文件读写 SDWebImage、 TMDiskCache、 PINDiskCache 等缓存,都是基于文件系统的,即一个 Value 对应一个文件,通过文件读写来缓存数据。他们的实现都比较简单,性能也都相近,缺点:不方便扩展、没有元数据、难以实现较好的淘汰算法、数据统计缓慢。

2 基于 mmap 文件内存映射 FastImageCache 采用的是 mmap 将文件映射到内存。mmap 性能非常高, 缺点:热数据的文件不要超过物理内存大小,不然 mmap 会导致内存交换严重降低性能(MongoDB也有同样的问题);另外内存中的数据是定时 flush 到文件的,如果数据还未同步时程序挂掉,就会导致数据错误。

3 基于数据库 NSURLCache、YYDiskCache、FBDiskCache 都是基于 SQLite 数据库的。基于数据库的缓存可以很好的支持元数据、扩展方便、数据统计速度快,也很容易实现 LRU 或其他淘汰算法,当单条数据小于 20K 时,数据越小 SQLite 读取性能越高;单条数据大于 20K 时,直接写为文件速度会更快一些,直接从官网下载最新的 SQLite 源码编译,会比 iOS 系统自带的 sqlite3.dylib 性能要高很多 磁盘缓存最好是把 SQLite 和文件存储结合起来:key-value 元数据保存在 SQLite 中,而 value 数据则根据大小不同选择 SQLite 或文件存储。NSURLCache 选定的数据大小的阈值是 16K;FBDiskCache 则把所有 value 数据都保存成了文件。

##常用的文件头编码 JPEG(jpg) 文件头:FFD8FFE1 PNG(png) 文件头:89504E47 GIF(gif) 文件头:47494638 Windows Bitmap(bmp) 文件头:424D WebP : 524946462A73010057454250

Adobe Photoshop (psd),文件头:38425053  Rich Text Format (rtf),文件头:7B5C727466  XML (xml),文件头:3C3F786D6C  HTML (html),文件头:68746D6C3E  Adobe Acrobat (pdf),文件头:255044462D312E ZIP Archive (zip),文件头:504B0304 RAR Archive (rar),文件头:52617221

Wave (wav),文件头:57415645  Quicktime (mov),文件头:6D6F6F76 AVI (avi),文件头:41564920 Real Audio (ram),文件头:2E7261FD Real Media (rm),文件头:2E524D46  MPEG (mpg),文件头:000001BA  MPEG (mpg),文件头:000001B3

date: 2017-08-11 16:00:00 author: "Gao Fei"

',14)]))}const S=e(o,[["render",l]]);export{m as __pageData,S as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.lean.js b/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.lean.js new file mode 100644 index 0000000..00baa0a --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_lock-share.md.CQLBBqsy.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as i,ag as r}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"琐碎的记录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/lock-share.md","filePath":"frontend/ios/lock-share.md"}'),o={name:"frontend/ios/lock-share.md"};function l(p,a,n,h,s,c){return i(),t("div",null,a[0]||(a[0]=[r("",14)]))}const S=e(o,[["render",l]]);export{m as __pageData,S as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.js b/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.js new file mode 100644 index 0000000..5f27d65 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.js @@ -0,0 +1,42 @@ +import{_ as n,c as s,o as e,ag as i}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"Macro Define","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/macro-define.md","filePath":"frontend/ios/macro-define.md"}'),p={name:"frontend/ios/macro-define.md"};function o(t,a,l,r,c,d){return e(),s("div",null,a[0]||(a[0]=[i(`

Macro Define

常用的宏定义

1. DEBUG Log

#ifdef DEBUG
+#define LLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+#else
+#define LLog(fmt, ...) while(0){}
+#endif

ios开发中难免会遇到一些oc与c混编的时候,当使用了pch文件时,c文件是不会识别上面的条件编译和#import等指令的,这时候应该使用另外一个条件编译来避免出现问题:

#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif

2. ios版本兼容

编译设置

Base SDK 当前编译所使用的SDK版本 Deployment Target 运行APP所需要的最低的操作系统版本 Base SDK 可以设置为Xcode默认的设置,比如Latest iOS(iOS10.2),Deployment Target设置为iOS 8.0,目前大多数APP都支持到该版本

iOS宏定义

静态检查

在编译阶段就检查当前SDK编译与构建应用是否能使用某个API 编译常量 __IPHONE_OS_VERSION_MIN_REQUIRED 系统最低版本(也就是iOS Deployment Target选择的版本) __IPHONE_OS_VERSION_MAX_ALLOWED 系统最高版本(当前手机系统允许使用的SDK的最高版本)

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0
+    // 系统版本在iOS9.0及以上则编译此部分代码
+#else
+    // 如果低于iOS9.0则编译此部分代码
+#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0
+// 如果选择(iOS Deployment Target)的最低支持版本在iOS8.0及以上才可以使用
+#endif

动态检查

CoreFoudation/NSFoundation版本宏

定义的宏如下,可以看出某些系统版本的值是一样的,而且没有对ios 10.0以上版本进行定义,需要自己定义

#define kCFCoreFoundationVersionNumber_iOS_8_0 1140.1
+#define kCFCoreFoundationVersionNumber_iOS_8_1 1141.14
+#define kCFCoreFoundationVersionNumber_iOS_8_2 1142.16
+#define kCFCoreFoundationVersionNumber_iOS_8_3 1144.17
+#define kCFCoreFoundationVersionNumber_iOS_8_4 1145.15
+#define kCFCoreFoundationVersionNumber_iOS_8_x_Max 1199
+#define kCFCoreFoundationVersionNumber_iOS_9_0 1240.1
+#define kCFCoreFoundationVersionNumber_iOS_9_1 1241.11
+#define kCFCoreFoundationVersionNumber_iOS_9_2 1242.13
+#define kCFCoreFoundationVersionNumber_iOS_9_3 1242.13
+#define kCFCoreFoundationVersionNumber_iOS_9_4 1280.38
+#define kCFCoreFoundationVersionNumber_iOS_9_x_Max 1299

使用方式

if (kCFCoreFoundationVersionNumber <kCFCoreFoundationVersionNumber_iOS_9_0) {
+        //系统版本低于iOS9.0
+    }

综合而论,不推荐使用

检查运行的iOS系统版本

转换为基本数据类型比较

if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
+        
+    }

使用systemVersion方法获取到的值为8.1 ,如比较8.1.1和8.1.2,就很困难了

字符串比较

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
+#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
+#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

使用字符串的比较 存在的问题 比如8.1 相对于8.1.0 结果为NSOrderedAscending, 即8.1 < 8.1.0

使用NSOperatingSystemVersion(iOS 8.0)

NSOperatingSystemVersion 为结构体,如下所示

typedef struct {
+    NSInteger majorVersion;
+    NSInteger minorVersion;
+    NSInteger patchVersion;
+} NSOperatingSystemVersion;
NSOperatingSystemVersion version = (NSOperatingSystemVersion){8,2,0};
+    if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
+        // 高于该版本
+    }else {
+        // 低于该版本
+    }

date: 2017-04-22 16:00:00 author: "Gao Fei"

`,33)]))}const h=n(p,[["render",o]]);export{u as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.lean.js b/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.lean.js new file mode 100644 index 0000000..8ee5892 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_macro-define.md.DnhUoQxo.lean.js @@ -0,0 +1 @@ +import{_ as n,c as s,o as e,ag as i}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"Macro Define","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/macro-define.md","filePath":"frontend/ios/macro-define.md"}'),p={name:"frontend/ios/macro-define.md"};function o(t,a,l,r,c,d){return e(),s("div",null,a[0]||(a[0]=[i("",33)]))}const h=n(p,[["render",o]]);export{u as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.js b/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.js new file mode 100644 index 0000000..5b73b6d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.js @@ -0,0 +1,18 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"iOS 网络状态检测","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/network-share.md","filePath":"frontend/ios/network-share.md"}'),l={name:"frontend/ios/network-share.md"};function p(i,a,r,o,c,d){return e(),n("div",null,a[0]||(a[0]=[t(`

iOS 网络状态检测

导入CoreTelephony.framework框架

CTCellularData *cellularData = [[CTCellularData alloc]init];
+    cellularData.cellularDataRestrictionDidUpdateNotifier =  ^(CTCellularDataRestrictedState state){
+        //状态改变时进行相关操作
+    };
    CTCellularData *cellularData = [[CTCellularData alloc]init];
+    CTCellularDataRestrictedState state = cellularData.restrictedState;
+    switch (state) {
+        case kCTCellularDataRestricted:
+            NSLog(@"Restricrted");
+            break;
+        case kCTCellularDataNotRestricted:
+            NSLog(@"Not Restricted");
+            break;
+        case kCTCellularDataRestrictedStateUnknown:
+            NSLog(@"Unknown");
+            break;
+        default:
+            break;
+    }

date: 2017-07-16 16:00:00 author: "Gao Fei"

`,5)]))}const C=s(l,[["render",p]]);export{h as __pageData,C as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.lean.js b/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.lean.js new file mode 100644 index 0000000..b348897 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_network-share.md.BvSwKl10.lean.js @@ -0,0 +1 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"iOS 网络状态检测","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/network-share.md","filePath":"frontend/ios/network-share.md"}'),l={name:"frontend/ios/network-share.md"};function p(i,a,r,o,c,d){return e(),n("div",null,a[0]||(a[0]=[t("",5)]))}const C=s(l,[["render",p]]);export{h as __pageData,C as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.js b/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.js new file mode 100644 index 0000000..6ac4a4d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"琐碎的记录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/note-share.md","filePath":"frontend/ios/note-share.md"}'),n={name:"frontend/ios/note-share.md"};function s(h,e,l,d,i,p){return r(),a("div",null,e[0]||(e[0]=[o('

琐碎的记录

免费的二级域名申请

境内:花生壳 http://hsk.oray.com/ 境外:dot.tk http://www.dot.tk/zh/index.html

免费的ssl证书

Let’s Encrypt https://letsencrypt.org

date: 2017-08-16 16:00:00 author: "Gao Fei"

',6)]))}const f=t(n,[["render",s]]);export{_ as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.lean.js b/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.lean.js new file mode 100644 index 0000000..1529b5f --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_note-share.md.pMsyM96B.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"琐碎的记录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/note-share.md","filePath":"frontend/ios/note-share.md"}'),n={name:"frontend/ios/note-share.md"};function s(h,e,l,d,i,p){return r(),a("div",null,e[0]||(e[0]=[o("",6)]))}const f=t(n,[["render",s]]);export{_ as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.js b/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.js new file mode 100644 index 0000000..70c30eb --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.js @@ -0,0 +1,61 @@ +import{_ as s,c as a,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const C=JSON.parse('{"title":"Get Current ViewController","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-current-controller.md","filePath":"frontend/ios/post-current-controller.md"}'),l={name:"frontend/ios/post-current-controller.md"};function t(r,n,i,o,c,d){return e(),a("div",null,n[0]||(n[0]=[p(`

Get Current ViewController

"Get the current view controller from the app delegate"

1.Get the current view controller from the app delegate

参考:http://stackoverflow.com/questions/24825123/get-the-current-view-controller-from-the-app-delegate%EF%BC%89

扩展一个方法:

UIViewController+Utils.h

#import <UIKit/UIKit.h>
+
+@interface UIViewController (Utils)
+
++(UIViewController*) currentViewController;
+
+@end

UIViewController+Utils.m

#import

+@implementation UIViewController (Utils)
+
++(UIViewController*) findBestViewController:(UIViewController*)vc {
+
+    if (vc.presentedViewController) {
+
+        // Return presented view controller
+        return [UIViewController findBestViewController:vc.presentedViewController];
+
+    } else if ([vc isKindOfClass:[UISplitViewController class]]) {
+
+        // Return right hand side
+        UISplitViewController* svc = (UISplitViewController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.viewControllers.lastObject];
+        else
+            return vc;
+
+    } else if ([vc isKindOfClass:[UINavigationController class]]) {
+
+        // Return top view
+        UINavigationController* svc = (UINavigationController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.topViewController];
+        else
+            return vc;
+
+    } else if ([vc isKindOfClass:[UITabBarController class]]) {
+
+        // Return visible view
+        UITabBarController* svc = (UITabBarController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.selectedViewController];
+        else
+            return vc;
+
+    } else {
+
+        // Unknown view controller type, return last child view controller
+        return vc;
+
+    }
+
+}
+
++(UIViewController*) currentViewController {
+
+    // Find best view controller
+    UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
+    return [UIViewController findBestViewController:viewController];
+
+}
+
+@end

date: 2017-04-07 author: "Gao Fei"

`,10)]))}const v=s(l,[["render",t]]);export{C as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.lean.js new file mode 100644 index 0000000..cabc9cf --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-current-controller.md.B-9NYLT_.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const C=JSON.parse('{"title":"Get Current ViewController","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-current-controller.md","filePath":"frontend/ios/post-current-controller.md"}'),l={name:"frontend/ios/post-current-controller.md"};function t(r,n,i,o,c,d){return e(),a("div",null,n[0]||(n[0]=[p("",10)]))}const v=s(l,[["render",t]]);export{C as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.js b/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.js new file mode 100644 index 0000000..756ebae --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.js @@ -0,0 +1,55 @@ +import{_ as a,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"\\"Dispatch Group\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-dispatch-group.md","filePath":"frontend/ios/post-dispatch-group.md"}'),t={name:"frontend/ios/post-dispatch-group.md"};function l(i,s,o,c,r,u){return p(),n("div",null,s[0]||(s[0]=[e(`

"Dispatch Group"

dispatch_group 日常使用

#1.常见书写方式

dispatch_group_t group = dispatch_group_create();   
+dispatch_queue_t queue = dispatch_queue_create("com.formssi.get_product_detail", NULL);
+dispatch_group_async(group,queue, ^{
+         <!--do work-->
+    });
+dispatch_group_async(group,queue, ^{
+         <!--do work-->
+    });
+    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+     <!--main thread-->
+     <!--do work-->
+      
+    });

#2.如果做的事包含block任务,就需要给没个block任务添加入组与出组的操作

dispatch_group_t group = dispatch_group_create();   
+dispatch_queue_t queue = dispatch_queue_create("com.baidu.detail", NULL);
+dispatch_group_enter(group);
+dispatch_group_async(group,queue, ^{
+         <!--do block work-->
+        dispatch_group_leave(group);
+    });
+    dispatch_group_enter(group);
+dispatch_group_async(group,queue, ^{
+         <!--do block work-->
+        dispatch_group_leave(group);
+    });
+    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+      <!--main thread-->
+      <!--do work-->
+    });

#3.当我们使用其他的三方库做网络请求或则图片下载时,而请求的任务包含多个,需要 等待这些任务都执行完成之后,再返回结果,如下列子:

dispatch_group_t group = dispatch_group_create();
+    __block BOOL isSuccess = NO;
+    for (CellModel *cellModel in modelArray) {
+         <!--异步下载图片-->
+        dispatch_group_enter(group);
+        [[SDWebImageManager sharedManager] downloadImageWithURL:cellModel.url options:SDWebImageRetryFailed | SDWebImageLowPriority progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
+            NSLog(@"downloadError = %@-%@",error,[NSThread currentThread]);
+            if (error) {
+                isSuccess = NO;
+            }else{
+                isSuccess = YES;
+                <!-- 获取图片大小-->
+                cellModel.cellHeight = WidthOfWindow * image.size.height / image.size.width;
+            }
+            dispatch_group_leave(group);
+        }];
+    }
+    
+
+dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+         <!-- more -->
+        if (isSuccess) {
+            completion(NetWorkingResultTypeSuccess,@"success");
+        }else{
+            completion(NetWorkingResultTypeNoData, @"error");
+        }
+        
+    });

date: 2017-03-17 16:00:00 author: "Gao Fei"

`,9)]))}const h=a(t,[["render",l]]);export{g as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.lean.js new file mode 100644 index 0000000..33acb79 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-dispatch-group.md.BPC5tDy_.lean.js @@ -0,0 +1 @@ +import{_ as a,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"\\"Dispatch Group\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-dispatch-group.md","filePath":"frontend/ios/post-dispatch-group.md"}'),t={name:"frontend/ios/post-dispatch-group.md"};function l(i,s,o,c,r,u){return p(),n("div",null,s[0]||(s[0]=[e("",9)]))}const h=a(t,[["render",l]]);export{g as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.js b/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.js new file mode 100644 index 0000000..1827b02 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.js @@ -0,0 +1,100 @@ +import{_ as a,c as s,o as p,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Facebook 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-facebook-share.md","filePath":"frontend/ios/post-facebook-share.md"}'),e={name:"frontend/ios/post-facebook-share.md"};function i(l,n,o,c,r,g){return p(),s("div",null,n[0]||(n[0]=[t(`

Facebook 分享

官方文档: https://developers.facebook.com/docs/sharing/overview

在移动平台上分享 — 分步指南

  • “分享”按钮:显示的时候没有分享计数器。用户轻触“分享”按钮将打开一个新窗口(也称为快速应用切换)。

  • 分享对话框:窗口将显示帖子编辑器,其中包含分享链接的预览。如果用户安装了 iOS 版 Facebook 应用,分享对话框将由 Facebook 应用提供,否则将由 Safari 浏览器提供。轻触“分享”按钮即表示用户确认分享,然后系统将切换回您的应用。

  • 现在,SDK 将自动检查设备上是否安装了原生 Facebook 应用。如果未安装,SDK 会将用户切换到默认浏览器并打开动态发布对话框。如果用户想要分享开放图谱动态,SDK 会打开网页分享对话框。

  • 如果安装了原生 Facebook 应用,4.0-4.4 版的 SDK 会切换到原生 iOS 版 Facebook 应用,并在发布帖子后将控制权交还您的应用。如果使用 4.5+ 版 SDK,除非分享内容是开放图谱动态,否则用户会看到 iOS 分享表,而不会切换到原生 iOS 版 Facebook 应用。 说明: 目前下载的最新SDK版本为4.21.0,想要使用跳转到Facebook应用分享,需要申请public-action权限,才能使用图谱,否则只能使用web显示分享,目前还没申请下来该权限,只能做到web分享

第一步:info.plist 文件配置

将以下 XML 代码片段插入文件正文,位于最后的 ==</dict>== 元素前

<key>CFBundleURLTypes</key>
+<array>
+  <dict>
+    <key>CFBundleURLSchemes</key>
+    <array>
+      <string>fb{your-app-id}</string>
+    </array>
+  </dict>
+</array>
+<key>FacebookAppID</key>
+<string>{your-app-id}</string>
+<key>FacebookDisplayName</key>
+<string>{your-app-name}</string>
+<!-- URL Scheme , 返回应用-->
+<key>LSApplicationQueriesSchemes</key>
+	<array>
+        <!--Facebook URL Scheme-->
+		<string>fbapi</string>
+		<string>fb-messenger-api</string>
+		<string>fbauth2</string>
+		<string>fbshareextension</string>
+        <!-- whatsapp URL Scheme 白名单-->
+		<string>whatsapp</string>
+        <!-- instagram URL Scheme 白名单-->
+		<string>instagram</string>
+        <!-- wechat URL Scheme 白名单-->
+		<string>wechat</string>
+		<string>weixin</string>
+	</array>
+<key>NSPhotoLibraryUsageDescription</key>
+  <string>{human-readable reason for photo access}</string>

info.plist 配置说明 (1)将 ==fb{your-app-id}== 替换为 Facebook 应用编号,加上前缀 ==fb==。例如,==fb1767503776894317==。您可以通过 Facebook 应用面板找到应用编号。 (2)使用应用编号替换 =={your-app-id}==。 (3)使用您在应用面板中指定的显示名称替换 =={your-app-name}==。 (4)将 =={human-readable reason for photo access}== 替换为您的应用需要获取照片访问权限的理由

第二步:注册Facebook

AppDelegate.m 文件的实现 #import <FBSDKCoreKit/FBSDKCoreKit.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+    
+    [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
+    
+    return YES;
+}
+// 仅支持iOS9以上系统,iOS8及以下系统不会回调
+-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
+    NSLog(@"%s,load app options = %@", __func__, options);
+    BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
+    return result;
+}
+
+// 所有平台,但ios9以后不推荐使用
+- (BOOL)application:(UIApplication *)application
+            openURL:(NSURL *)url
+  sourceApplication:(NSString *)sourceApplication
+         annotation:(id)annotation {
+    NSLog(@"%s,load app sourceApplication = %@",__func__,sourceApplication);
+    BOOL isSuccess = [[FBSDKApplicationDelegate sharedInstance] application:application
+                                                          openURL:url
+                                                sourceApplication:sourceApplication
+                                                       annotation:annotation];
+    return isSuccess;
+}

第三步:实现分享功能

3.1 使用SDK中的分享按钮FBSDKShareButton 需要==public_profile==,默认已通过 创建如下:

FBSDKShareButton *shareButton = [[FBSDKShareButton alloc] init];
+shareButton.shareContent = content;  
+shareButton.center = self.view.center;
+  [self.view addSubview:shareButton];

3.2 对于分享的内容content 可以使用分为

  • FBSDKShareLinkContent 链接:大部分内容为引用 HTML 页面的网址。要提供最相关的信息,您应使用 Facebook 特定元标签标记您的页面

  • FBSDKSharePhotoContent
    照片:直接上传一张或多张由用户拍摄的照片

  • FBSDKShareVideoContent
    视频:直接上传由用户拍摄的视频

  • FBSDKShareMediaContent 多媒体:直接上传同时包含照片和视频的内容

创建方式:

FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
+content.contentURL = [NSURL URLWithString:@"https://developers.facebook.com"];

SDK中定义的分享按钮如下图:

3.3 使用自定义的分享按钮

要使用专属分享界面,您需要:

  • 构建发布到图谱 API 端点 ==/me/feed== 的自定义界面
  • 将 Facebook 登录功能添加至您的应用
  • 请求 ==publish_actions== 权限,需要申请

对自定义的分享按钮的样式的说明:

申请权限需要注意的事项:

上传视频的注意事项如图所示:

3.4 自定义分享内容

  • 使用开放图谱标签。
  • 调整 FBSDKShareLinkContent 选择器

图谱示例

if ([[FBSDKAccessToken currentAccessToken] hasGranted:@"publish_actions"]) {
+        [[[FBSDKGraphRequest alloc]initWithGraphPath:@"me/feed" parameters:@{@"message":@"hello world!"} HTTPMethod:@"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
+            NSLog(@"result=%@",result);
+        }];
+    }else{
+        NSLog(@"did not have publish_actions");
+    }

FBSDKShareLinkContent 示例

NSURL *contentURL = [[NSURL alloc] initWithString:
+  @"http://en.wikipedia.org/wiki/Facebook"];
+
+NSURL *imageURL = 
+  [NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Facebook_Headquarters_Menlo_Park.jpg/2880px-Facebook_Headquarters_Menlo_Park.jpg"];
+  
+button.shareContent = [[FBSDKShareLinkContent alloc]
+  initWithContentURL: contentURL
+  contentTitle: @"My Share Title"
+  contentDescription: @"Lorem ipsum dolor sit amet."
+  imageURL: imageURL
+  peopleIDs: @[@"1561082740838259"]
+  placeID: @"166793820034304"
+  ref: @"myRefId"
+];

3.5 分享对话框

  • 在移动平台上,当用户使用分享对话框分享内容时,对话框会执行快速应用切换操作,切换到设备上的 Facebook 应用。我们还提供网页对话框作为回退选项,以防用户未安装原生 Facebook 应用
  • 使用原生 Facebook 对话框时,无需添加 Facebook 登录即可启用分享
- (void)facebookShareWithMessage:(NSDictionary *)dictionary {
+    NSString *contentUrlString = dictionary[@"content_url"];
+    NSString *imageUrlString = dictionary[@"image_url"];
+    NSString *description = dictionary[@"description"];
+    NSString *title = dictionary[@"title"];
+    NSString *quote = dictionary[@"quote"];
+    
+    FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
+    content.contentURL = [NSURL URLWithString:contentUrlString];
+    content.imageURL = [NSURL URLWithString:imageUrlString];
+    content.contentDescription = description;
+    content.contentTitle = title;
+    content.quote = quote;
+    
+    FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
+    dialog.shareContent = content;
+    dialog.fromViewController = self;
+    dialog.delegate = self;
+    dialog.mode = FBSDKShareDialogModeBrowser;
+    [dialog show];
+}

3.6 自定义分享界面 可以使用自定义按钮和调用图谱 API 的自定义对话框

                                    2017-04-19 高飞
+
`,36)]))}const d=a(e,[["render",i]]);export{h as __pageData,d as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.lean.js new file mode 100644 index 0000000..b2854f1 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-facebook-share.md.o1afdPes.lean.js @@ -0,0 +1 @@ +import{_ as a,c as s,o as p,ag as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Facebook 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-facebook-share.md","filePath":"frontend/ios/post-facebook-share.md"}'),e={name:"frontend/ios/post-facebook-share.md"};function i(l,n,o,c,r,g){return p(),s("div",null,n[0]||(n[0]=[t("",36)]))}const d=a(e,[["render",i]]);export{h as __pageData,d as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.js b/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.js new file mode 100644 index 0000000..66b68f9 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.js @@ -0,0 +1,79 @@ +import{_ as a,c as s,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const t="/img/in-post/media/14926785184639/14926786938908.jpg",i="/img/in-post/media/14926785184639/14926788159747.jpg",l="/img/in-post/media/14926785184639/14926813444655.jpg",o="/img/in-post/media/14926785184639/14926788445548.jpg",r="/img/in-post/media/14926785184639/14926788538614.jpg",c="/img/in-post/media/14926785184639/14926788643833.jpg",m="/img/in-post/media/14926785184639/14926792525999.jpg",g="/img/in-post/media/14926785184639/14926791330965.jpg",N=JSON.parse('{"title":"Instagram 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-instagram-share.md","filePath":"frontend/ios/post-instagram-share.md"}'),d={name:"frontend/ios/post-instagram-share.md"};function u(h,n,S,I,_,U){return p(),s("div",null,n[0]||(n[0]=[e('

Instagram 分享

大概流程如下:

分享:无需获取权限,通过Custom URL Scheme或者Document Interaction 分享出去后停留在Instagram,无回调(返回值)。

另外:通过授权(账号和密码)的方式,可以获取用户的公开内容。

登陆权限有如下几种:

获取较高权限,比如:public_content可以拿到用户发布的图片和视频内容。 备注:

客服端申请权限,目前只申请下来basic权限,public_content权限没申请下来,没能继续测试是否能拿到用户发布的内容,但是理论上是可以的,且看下面的介绍)

根据官方文档的介绍: 第一步:授权,获取access_token;

第二步:get用户最新发布的media。

请求的url及参数如上图所示,返回的结果如下图所示。

结论:可以先请求用户授权,然后分享照片,最后获取最新发布的信息。

分享文档:https://www.instagram.com/developer/mobile-sharing/iphone-hooks/

通过 URL Scheme 分享,截图如下:

-(void)loadInstagram{
+    NSURL *url = [NSURL URLWithString:@"instagram://app"];
+    if ([[UIApplication sharedApplication] canOpenURL:url]) {
+        [[UIApplication sharedApplication] openURL:url];
+    }else{
+        NSLog(@"did not install instagram");
+        [self showAlterWithStr:@"did not install instagram"];
+    }
+    
+}

通过UIDocumentInteractionController,原文档说明如下: 示例代码:

-(void)shareToInstagramByDocumentImage:(NSString *)imageStr{
+    
+    NSURL *instagramURL = [NSURL URLWithString:@"instagram://app"];
+    
+    if ([[UIApplication sharedApplication] canOpenURL:instagramURL]){
+        
+        dispatch_async(dispatch_get_global_queue(0, 0), ^{
+            
+            UIImage *image = [UIImage imageNamed:imageStr];
+            NSString *name = [NSString stringWithFormat:@"%f%u.igo",[NSDate timeIntervalSinceReferenceDate],arc4random_uniform(1000)];
+            NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:name];
+            
+            [UIImagePNGRepresentation(image) writeToFile:savePath atomically:YES];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+                self.documentInteractionController.UTI = @"com.instagram.exclusivegram";
+                self.documentInteractionController.delegate = self;
+                [self.documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
+            });
+        });
+
+    }else{
+        NSLog(@"did not install instagram");
+        [self showAlterWithStr:@"did not install instagram"];
+    }
+}
-(void)shareToInstagramByImage:(NSString *)imageStr{
+    
+    NSURL *instagramURL = [NSURL URLWithString:@"instagram://app"];
+    
+    if ([[UIApplication sharedApplication] canOpenURL:instagramURL]){
+        
+        dispatch_async(dispatch_get_global_queue(0, 0), ^{
+            
+            UIImage *image = [UIImage imageNamed:imageStr];
+            NSString *name = [NSString stringWithFormat:@"%f%u.ig",[NSDate timeIntervalSinceReferenceDate],arc4random_uniform(1000)];
+            NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:name];
+            
+            [UIImagePNGRepresentation(image) writeToFile:savePath atomically:YES];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+                self.documentInteractionController.UTI = @"com.instagram.photo";
+                self.documentInteractionController.delegate = self;
+                [self.documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
+            });
+        });
+        
+    }else{
+        NSLog(@"did not install instagram");
+        [self showAlterWithStr:@"did not install instagram"];
+    }
+}
-(void)shareToInstagramByDocumentnNameWith:(NSString *)imageName{
+    
+    NSURL *instagramUrl = [NSURL URLWithString:@"instagram://app"];
+    
+    
+    if ([[UIApplication sharedApplication] canOpenURL:instagramUrl]){
+        
+        NSString  *jpgPath = [[NSBundle mainBundle] pathForResource:imageName ofType:nil];
+        NSURL *imageUrl = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"file://%@", jpgPath]];
+        
+        self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:imageUrl];
+        self.documentInteractionController.UTI = @"com.instagram.photo";
+        self.documentInteractionController.delegate = self;
+        
+        [self.documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
+    }else{
+        NSLog(@"did not install instagram");
+        [self showAlterWithStr:@"did not install instagram"];
+    }
+}

date: 2017-04-20 16:00:00 author: "Gao Fei"

`,19)]))}const q=a(d,[["render",u]]);export{N as __pageData,q as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.lean.js new file mode 100644 index 0000000..522db2d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-instagram-share.md.CmIhBWP1.lean.js @@ -0,0 +1 @@ +import{_ as a,c as s,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const t="/img/in-post/media/14926785184639/14926786938908.jpg",i="/img/in-post/media/14926785184639/14926788159747.jpg",l="/img/in-post/media/14926785184639/14926813444655.jpg",o="/img/in-post/media/14926785184639/14926788445548.jpg",r="/img/in-post/media/14926785184639/14926788538614.jpg",c="/img/in-post/media/14926785184639/14926788643833.jpg",m="/img/in-post/media/14926785184639/14926792525999.jpg",g="/img/in-post/media/14926785184639/14926791330965.jpg",N=JSON.parse('{"title":"Instagram 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-instagram-share.md","filePath":"frontend/ios/post-instagram-share.md"}'),d={name:"frontend/ios/post-instagram-share.md"};function u(h,n,S,I,_,U){return p(),s("div",null,n[0]||(n[0]=[e("",19)]))}const q=a(d,[["render",u]]);export{N as __pageData,q as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.js b/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.js new file mode 100644 index 0000000..f439d55 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.js @@ -0,0 +1,55 @@ +import{_ as a,c as n,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"\\"Twitter share\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-twitter-share.md","filePath":"frontend/ios/post-twitter-share.md"}'),t={name:"frontend/ios/post-twitter-share.md"};function i(o,s,l,r,c,d){return e(),n("div",null,s[0]||(s[0]=[p(`

"Twitter share"

Twitter 分享

参考文档:https://fabric.io/kits/ios/twitterkit/installhttps://fabric.io/kits/ios/twitterkit/manual-install

1 开发者账号申请注意事项:

![]/img/in-post/media/14925836417059/14925860141113.jpg)

2 安装步骤:

2.1 Download, unzip, and drag 下载,解压,拖拽到工程文件 2.2 Add a Run Script Build Phase

2.3 Add API Key to Info.plist

2.4 Initialize Twitter and Run

3 重要注解:

4 twitter 分享文档:

https://docs.fabric.io/apple/twitter/compose-tweets.html 分享参考:

- (void)showTwitterCompose{
+    TWTRComposer *composer = [[TWTRComposer alloc] init];
+    
+    [composer setText:@"I am big big man"];
+    [composer setURL:[NSURL URLWithString:@"https//:www.baidu.com"]];
+    if (composer) {
+        NSLog(@"composer = %@",composer);
+        [composer showFromViewController:self completion:^(TWTRComposerResult result) {
+            if (result == TWTRComposerResultDone) {
+                NSLog(@"twitter share done");
+            }else if (result == TWTRComposerResultCancelled){
+                NSLog(@"twitter share cancell");
+            }
+        }];
+    }
+
+}
+
+- (void)showTwitterSessionShare{
+    // Objective-C
+    // Users must be logged-in to compose Tweets
+    TWTRSession *session = [Twitter sharedInstance].sessionStore.session;
+    
+    // User generated image
+    UIImage *image = [UIImage imageNamed:@"XXXXX"];
+    
+    // Create the card and composer
+    TWTRCardConfiguration *card = [TWTRCardConfiguration appCardConfigurationWithPromoImage:image iPhoneAppID:nil iPadAppID:nil googlePlayAppID:nil];
+    TWTRComposerViewController *composer = [[TWTRComposerViewController alloc] initWithUserID:session.userID cardConfiguration:card];
+    
+    // Optionally set yourself as the delegate
+    composer.delegate = self;
+    
+    // Show the view controller
+    [self presentViewController:composer animated:YES completion:nil];
+}

5 问题:

在ios 9.2.1 上测试,如果用户没登录Twitter账号,点击Twitter分享会崩溃。 出现的错误日志如下:

***
*** First throw call stack:
+(0x239ab91b 0x23146e17 0x28294ab1 0x28296d25 0x28296f91 0x2801ddb9 0x1928b5 0x906e5 0x9057b 0x27f5c755 0x27f5c6e1 0x27f446d3 0x27f5c005 0x27f5bc7f 0x27f5468f 0x27f25125 0x27f236d3 0x2396ddff 0x2396d9ed 0x2396bd5b 0x238bb229 0x238bb015 0x24eabac9 0x27f8d189 0x92def 0x23563873)
+libc++abi.dylib: terminating with uncaught exception of type NSException

暂时的解决方式:

  1. 申请访问Account权限(ios 10,要添加到info.plist中);
  2. 访问Account的实现代码:
// ios 10 在info.plist添加访问权限
+    ACAccountStore *store = [[ACAccountStore alloc]init];
+    ACAccountType *twitterType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
+    [store requestAccessToAccountsWithType:twitterType options:nil completion:^(BOOL granted, NSError *error) {
+        if (granted){
+         NSArray *array =   [store accountsWithAccountType:twitterType];
+            NSLog(@"accounts = %@",array);
+            if (array.count > 0) {// 显示Twitter分享功能
+                [self showTwitterCompose];
+            }else{
+                // 提示用户添加账号信息
+            }
+        }else{
+            NSLog(@"----no----");
+        
+            // 提示用户允许访问账号信息
+        }
+    }];

2017-04-20 高飞

`,20)]))}const m=a(t,[["render",i]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.lean.js new file mode 100644 index 0000000..d9e2328 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-twitter-share.md.D8KqUT6F.lean.js @@ -0,0 +1 @@ +import{_ as a,c as n,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"\\"Twitter share\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-twitter-share.md","filePath":"frontend/ios/post-twitter-share.md"}'),t={name:"frontend/ios/post-twitter-share.md"};function i(o,s,l,r,c,d){return e(),n("div",null,s[0]||(s[0]=[p("",20)]))}const m=a(t,[["render",i]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.js b/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.js new file mode 100644 index 0000000..7c2ef62 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.js @@ -0,0 +1,13 @@ +import{_ as a,c as e,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"View Tips","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-view-tips.md","filePath":"frontend/ios/post-view-tips.md"}'),p={name:"frontend/ios/post-view-tips.md"};function i(l,s,o,c,r,d){return n(),e("div",null,s[0]||(s[0]=[t(`

View Tips

将视图显示在最前方

[self.view addSubview:view];
+[self.view bringSubviewToFront:view];

下拉取消回弹效果

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
+    
+    //限制下拉没有回弹效果
+    if (scrollView.contentOffset.y <= 0){
+        
+        CGPoint point = scrollView.contentOffset;
+        point.y = 0;
+        [scrollView setContentOffset:point];
+    }
+}

检测某个API是否可用

1.使用respondsToSelector:方法检测是否有某个方法;

respondsToSelector:@selector(method)

  1. 使用<objc/runtime.h>检测是否有某个属性;
    if (class_getProperty([ClassName class], "propertyName")) {
+        // it has that property!
+    }

date: 2017-03-28 author: "Gao Fei"

`,11)]))}const v=a(p,[["render",i]]);export{u as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.lean.js new file mode 100644 index 0000000..ebd2f08 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-view-tips.md.CEBmkpZm.lean.js @@ -0,0 +1 @@ +import{_ as a,c as e,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"View Tips","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-view-tips.md","filePath":"frontend/ios/post-view-tips.md"}'),p={name:"frontend/ios/post-view-tips.md"};function i(l,s,o,c,r,d){return n(),e("div",null,s[0]||(s[0]=[t("",11)]))}const v=a(p,[["render",i]]);export{u as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.js b/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.js new file mode 100644 index 0000000..5c1320d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.js @@ -0,0 +1,48 @@ +import{_ as s,c as a,o as p,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"WhatsApp 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-whatsapp-share.md","filePath":"frontend/ios/post-whatsapp-share.md"}'),e={name:"frontend/ios/post-whatsapp-share.md"};function l(i,n,o,r,c,h){return p(),a("div",null,n[0]||(n[0]=[t(`

WhatsApp 分享

没有开发者平台,分享通过系统自带的

1 添加URL Scheme 白名单

<key>LSApplicationQueriesSchemes</key>
+	<array>
+		<string>whatsapp</string>
+	</array>

2 分享文字:使用open URL Scheme

- (void)shareToWhatsAppWithTxt:(NSString *)txt{
+   
+    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"whatsapp://"]]) {
+        NSString *str = [NSString stringWithFormat:@"whatsapp://send?text=%@",[txt stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]];
+        NSURL *msgUrl = [NSURL URLWithString:str];
+        [[UIApplication sharedApplication] openURL:msgUrl];
+    }else{
+        NSLog(@"no whatsapp install");
+        [self showAlterWithStr:@"no whatsapp install"];
+    }
+}

3 分享照片与视频 使用UIDocumentInteractionController

- (void)shareToWhatsAppWithImg:(UIImage *)img{
+    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"whatsapp://app"]]) {
+        
+        dispatch_async(dispatch_get_global_queue(0, 0), ^{
+            
+            NSString *name = [NSString stringWithFormat:@"%f%u.png",[NSDate timeIntervalSinceReferenceDate],arc4random_uniform(1000)];
+            NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:name];
+            BOOL result = [UIImagePNGRepresentation(img) writeToFile:savePath atomically:YES];
+            if (result) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    UIDocumentInteractionController *intent = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+                    intent.UTI = @"net.whatsapp.image";
+                    intent.delegate = self;
+                    [intent presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
+                });
+            }else{
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [self showAlterWithStr:@"error"];
+                
+                });
+            }
+            
+            
+        });
+   
+    }else{
+        [self showAlterWithStr:@"no whatsapp install"];
+    }
+}
- (void)showAlterWithStr:(NSString *)str{
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:str preferredStyle:UIAlertControllerStyleAlert];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
+    [alertController addAction:cancelAction];
+    
+    [self presentViewController:alertController animated:YES completion:nil];
+}

2017-04-20 高飞

`,10)]))}const u=s(e,[["render",l]]);export{g as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.lean.js b/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.lean.js new file mode 100644 index 0000000..8c2b0de --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_post-whatsapp-share.md.DXPe5cbb.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as p,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"WhatsApp 分享","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/post-whatsapp-share.md","filePath":"frontend/ios/post-whatsapp-share.md"}'),e={name:"frontend/ios/post-whatsapp-share.md"};function l(i,n,o,r,c,h){return p(),a("div",null,n[0]||(n[0]=[t("",10)]))}const u=s(e,[["render",l]]);export{g as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.js b/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.js new file mode 100644 index 0000000..ceff587 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.js @@ -0,0 +1,19 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/reactnative.md","filePath":"frontend/ios/reactnative.md"}'),p={name:"frontend/ios/reactnative.md"};function i(l,a,o,c,d,r){return e(),n("div",null,a[0]||(a[0]=[t(`

React Native 入门

1. 配置环境

特点

1.1 切换淘宝镜像

# 如果安装下载速度过慢,可以设置使用国内淘宝提供的镜像
+$ npm config set registry https://registry.npm.taobao.org --global
+$ npm config set disturl https://npm.taobao.org/dist --global
+
+# Yarn是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载
+$ sudo npm install -g yarn
#官方提供了一键生成项目初始结构的脚手架react-native-cli
+$ sudo npm install -g react-native-cli
+
+# 安装指定版本的 react native
+$ sudo npm install -save react-native@0.60

1.2 CocoaPods 镜像使用帮助

若果cocoapods 安装太慢,可以尝试切换到清华站点

下面示例的创建 本地名为 tuna 的仓库

$ pod repo add tuna https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git
+$ pod repo update tuna

最后进入自己的工程,在自己工程的podFile第一行加上:

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

2. 初始化项目

cd 到需要创建项目的目录下
+$ react-native init demo
+$ cd demo
+#运行
+$ react-native run-ios
+# 如果运行失败,直接找到 iOS 文件夹,使用xcode 直接编译工程,如果发现第三方库没有安装,则先使用pod install
+$ pod install

3.使用

导入定时器
+#在项目文件夹 安装定时器
+$  npm i react-timer-mixin --save
`,16)]))}const g=s(p,[["render",i]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.lean.js b/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.lean.js new file mode 100644 index 0000000..496fe06 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_reactnative.md.MxIQB3HJ.lean.js @@ -0,0 +1 @@ +import{_ as s,c as n,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/reactnative.md","filePath":"frontend/ios/reactnative.md"}'),p={name:"frontend/ios/reactnative.md"};function i(l,a,o,c,d,r){return e(),n("div",null,a[0]||(a[0]=[t("",16)]))}const g=s(p,[["render",i]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.js b/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.js new file mode 100644 index 0000000..0e3e7eb --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.js @@ -0,0 +1,10 @@ +import{_ as n,c as t,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"\\"Url Coding\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/url-codeing.md","filePath":"frontend/ios/url-codeing.md"}'),s={name:"frontend/ios/url-codeing.md"};function p(r,e,i,c,l,d){return a(),t("div",null,e[0]||(e[0]=[o(`

"Url Coding"

subtitle: "与url相关的处理"

#Encoding and Decoding URL Data

To percent-encode part of a URL string, use the ==NSString== method ==stringByAddingPercentEncodingWithAllowedCharacters==:, passing the appropriate character set for the URL component or subcomponent: • User: ==URLUserAllowedCharacterSet== • Password: ==URLPasswordAllowedCharacterSet== • Host: ==URLHostAllowedCharacterSet== • Path: ==URLPathAllowedCharacterSet== • Fragment: ==URLFragmentAllowedCharacterSet== • Query: ==URLQueryAllowedCharacterSet==

Important: Don’t use stringByAddingPercentEncodingWithAllowedCharacters: to encode an entire URL string, because each URL component or subcomponent has different rules for what characters are valid.

For example, to percent-encode a UTF-8 string for inclusion in a URL path, you do the following:

  NSString *str = @"http://192.168.2.123:80/u=142020185,2790987080&fm=26&gp=0的副本.jpg";
+    NSString *urlStr = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+    [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
+    NSURL *url = [NSURL URLWithString:urlStr];

If you want to decode a percent-encoded URL component, use NSURLComponents to split the URL into its constituent parts and access the corresponding property. For example, to get the UTF-8 string value for a percent-encoded URL path, you do the following:

NSString *encodeStr = @"http://192.168.2.123:80/u=142020185,2790987080&fm=26&gp=0%E7%9A%84%E5%89%AF%E6%9C%AC.jpg";
+
+//   NSURL *url2 = [NSURL URLWithString:encodeStr];
+//    NSURLComponents *component = [NSURLComponents componentsWithURL:url2 resolvingAgainstBaseURL:NO];
+    NSURLComponents *component = [NSURLComponents componentsWithString:encodeStr];
+    NSString *path = component.path;
+    NSLog(@"path=%@",path);

The user component of a URL is an optional component that precedes the host component, and ends at either a colon (if a password is specified) or an @ sign (if no password is specified). For example, in the URL http://username:password@www.example.com/index.html#jumpLocation, the user component is username the pass component is password the host component is www.example.com the path component is /index.html the fragment is jumpLocation

date: 2017-06-06 16:00:00 author: "Gao Fei"

`,11)]))}const g=n(s,[["render",p]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.lean.js b/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.lean.js new file mode 100644 index 0000000..90f82be --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_url-codeing.md.BiysPrsl.lean.js @@ -0,0 +1 @@ +import{_ as n,c as t,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"\\"Url Coding\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/url-codeing.md","filePath":"frontend/ios/url-codeing.md"}'),s={name:"frontend/ios/url-codeing.md"};function p(r,e,i,c,l,d){return a(),t("div",null,e[0]||(e[0]=[o("",11)]))}const g=n(s,[["render",p]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.js b/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.js new file mode 100644 index 0000000..7796992 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.js @@ -0,0 +1 @@ +import{_ as t,c as n,o as s,j as e,a as r}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"Version","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/version-share.md","filePath":"frontend/ios/version-share.md"}'),o={name:"frontend/ios/version-share.md"};function i(l,a,d,c,m,p){return s(),n("div",null,a[0]||(a[0]=[e("h1",{id:"version",tabindex:"-1"},[r("Version "),e("a",{class:"header-anchor",href:"#version","aria-label":'Permalink to "Version"'},"​")],-1),e("h2",{id:"开发版本对比",tabindex:"-1"},[r("开发版本对比 "),e("a",{class:"header-anchor",href:"#开发版本对比","aria-label":'Permalink to "开发版本对比"'},"​")],-1),e("p",null,"DEV : Development System 开发 SIT : System Integration Testing 系统集成 UAT : User Acceptance Testing 用户测试 QAS : Quality Assurance System 质量保证体系 PRD : Production System 生产系统",-1),e("p",null,"Load Testing 负载测试 Stress Testing 压力测试 Performance Evaluation Testing(PET)性能测试",-1),e("p",null,'date: 2017-09-18 16:00:00 author: "Gao Fei"',-1)]))}const u=t(o,[["render",i]]);export{f as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.lean.js b/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.lean.js new file mode 100644 index 0000000..7796992 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_version-share.md.CPKtn0IM.lean.js @@ -0,0 +1 @@ +import{_ as t,c as n,o as s,j as e,a as r}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"Version","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/version-share.md","filePath":"frontend/ios/version-share.md"}'),o={name:"frontend/ios/version-share.md"};function i(l,a,d,c,m,p){return s(),n("div",null,a[0]||(a[0]=[e("h1",{id:"version",tabindex:"-1"},[r("Version "),e("a",{class:"header-anchor",href:"#version","aria-label":'Permalink to "Version"'},"​")],-1),e("h2",{id:"开发版本对比",tabindex:"-1"},[r("开发版本对比 "),e("a",{class:"header-anchor",href:"#开发版本对比","aria-label":'Permalink to "开发版本对比"'},"​")],-1),e("p",null,"DEV : Development System 开发 SIT : System Integration Testing 系统集成 UAT : User Acceptance Testing 用户测试 QAS : Quality Assurance System 质量保证体系 PRD : Production System 生产系统",-1),e("p",null,"Load Testing 负载测试 Stress Testing 压力测试 Performance Evaluation Testing(PET)性能测试",-1),e("p",null,'date: 2017-09-18 16:00:00 author: "Gao Fei"',-1)]))}const u=t(o,[["render",i]]);export{f as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.js b/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.js new file mode 100644 index 0000000..261b1ae --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.js @@ -0,0 +1,404 @@ +import{_ as s,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"WebScoket Introduction","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/webScoket.md","filePath":"frontend/ios/webScoket.md"}'),l={name:"frontend/ios/webScoket.md"};function t(i,n,c,o,r,d){return p(),a("div",null,n[0]||(n[0]=[e(`

WebScoket Introduction

WebScoket

ios示例:

SocketManager.h 文件

#import <Foundation/Foundation.h>
+// 替换为自己的IP地址
+static NSString *kHost = @"192.168.2.22";
+static NSInteger kPort = 8080;
+static NSString *kAdress = @"/websocket/message";
+
+typedef enum : NSUInteger {
+    disConnectByUser ,
+    disConnectByServer,
+} DisConnectType;
+
+
+@interface SocketManager : NSObject
+
++ (instancetype)shared;
+
+- (void)connect;
+- (void)disConnect;
+
+- (void)sendMessage:(NSString *)message;
+
+- (void)receiveMessage:(void(^)(NSString *str))measge;
+
+- (void)ping;
+
+@end

SocketManager.m 文件

#import "SocketManager.h"
+#import <SocketRocket/SocketRocket.h>
+
+
+#define dispatch_main_async_safe(block)\\
+        if ([NSThread isMainThread]) {\\
+        block();\\
+        }else{\\
+            dispatch_async(dispatch_get_main_queue(), block);\\
+        }
+
+
+@interface SocketManager()<SRWebSocketDelegate>
+
+@property(nonatomic,strong)SRWebSocket *webSocket;
+@property(nonatomic,strong)NSTimer *heartBeat;
+@property(nonatomic,assign)NSTimeInterval reConnectTime;
+@property(nonatomic,copy)void(^receiveMsg)(NSString *str);
+@end
+
+
+@implementation SocketManager
+
++(instancetype)shared
+{
+    static SocketManager *instance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        instance = [[self alloc] init];
+        
+    });
+    return instance;
+}
+
+- (void)initSocket
+{
+    if (self.webSocket) {
+        return;
+    }
+    
+    self.webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"ws://%@:%ld%@",kHost,(long)kPort,kAdress]]];
+    self.webSocket.delegate = self;
+    
+    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+    queue.maxConcurrentOperationCount = 1;
+    
+    [self.webSocket setDelegateOperationQueue:queue];
+    
+    [_webSocket open];
+    
+    
+    
+}
+
+
+- (void)initHeartBeat
+{
+    dispatch_main_async_safe(^{
+        [self destoryHeartBeat];
+        
+        self.heartBeat = [NSTimer scheduledTimerWithTimeInterval:3*60 target:self selector:@selector(sendHeartMessage) userInfo:nil repeats:YES];
+        [[NSRunLoop currentRunLoop] addTimer:self.heartBeat forMode:NSRunLoopCommonModes];
+    })
+}
+
+- (void)sendHeartMessage
+{
+//    [self sendMessage:@"heart"];
+    [self ping];
+}
+
+
+- (void)destoryHeartBeat
+{
+    dispatch_main_async_safe(^{
+        if (self.heartBeat) {
+            [self.heartBeat invalidate];
+            self.heartBeat = nil;
+        }
+    })
+}
+
+// 建立连接
+- (void)connect
+{
+    [self initSocket];
+    
+    self.reConnectTime = 0;
+}
+
+//重连机制
+- (void)reConnect
+{
+    [self disConnect];
+    
+    if (_reConnectTime >64) {
+        return;
+    }
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        self.webSocket = nil;
+        [self initSocket];
+    });
+    
+    if (_reConnectTime == 0) {
+        _reConnectTime = 2;
+    }else
+    {
+        _reConnectTime *= 2;
+    }
+    
+    
+}
+
+- (void)disConnect
+{
+    if (self.webSocket) {
+        [self.webSocket close];
+        _webSocket = nil;
+    }
+}
+
+- (void)sendMessage:(NSString *)message
+{
+    
+    NSLog(@"readyState=%ld",(long)self.webSocket.readyState);
+    // 发送文本数据
+    [self.webSocket send:message];
+    // 发送二进制数据
+//    [self.webSocket send:[message dataUsingEncoding:NSUTF8StringEncoding]];
+  
+}
+
+- (void)ping
+{
+    NSError *error = nil;
+    
+    [self.webSocket sendPing:nil];
+    NSLog(@"sendpingError=%@",error);
+}
+
+- (void)receiveMessage:(void (^)(NSString *))measge
+{
+    self.receiveMsg = measge;
+}
+
+#pragma mark - SRWebSocketDelegate
+- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
+{
+    NSLog(@"服务器返回收到消息:%@",message);
+    dispatch_main_async_safe(^{
+        if (message) {
+            self.receiveMsg(message);
+//            [self receiveMessage:(message)];
+        }
+ 
+    }
+    )
+    
+}
+
+- (void)webSocketDidOpen:(SRWebSocket *)webSocket
+{
+    NSLog(@"连接成功");
+    
+    //连接成功了开始发送心跳
+    [self initHeartBeat];
+}
+
+//open失败的时候调用
+-(void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
+{
+    NSLog(@"连接失败.....\\n%@",error);
+    
+    //失败了就去重连
+    [self reConnect];
+}
+
+//网络连接中断被调用
+- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean
+{
+    NSLog(@"被关闭连接,code:%ld,reason:%@,wasClean:%d",code,reason,wasClean);
+    
+    //如果是被用户自己中断的那么直接断开连接,否则开始重连
+    if (code == disConnectByUser) {
+        [self disConnect];
+    }else{
+        
+        [self reConnect];
+    }
+    //断开连接时销毁心跳
+    [self destoryHeartBeat];
+    
+}
+
+//sendPing的时候,如果网络通的话,则会收到回调,但是必须保证ScoketOpen,否则会crash
+- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload
+{
+    NSLog(@"收到pong回调");
+    
+}
+
+
+@end

本例使用Tomcat7作为服务器容器 java 服务端示例

创建Message类来接受客户端发来的websocket请求

import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.PongMessage;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+@ServerEndpoint("/message")
+public class Message {
+
+	
+	private static Set<Client> clientSet = new CopyOnWriteArraySet<>();
+	
+	
+	@OnOpen
+	public void onOpen(Session session) {
+		String id = session.getId();
+		System.out.println("onOpen,id:"+session.getId());
+		Client client = new Client(session, id);
+		clientSet.add(client);
+		
+		System.out.println(clientSet);
+	}
+	
+	@OnClose
+	public void onClose(Session session) {
+		System.out.println("onClose,id:"+session.getId());
+		for(Client client:clientSet) {
+			if(client.getSession().equals(session))
+			{
+				clientSet.remove(client);
+				break;
+			}
+		}
+	}
+	// 文本消息 String 类型
+	@OnMessage
+	public void onMessage(Session session, String msg,boolean last) {
+		System.out.println("onMessage,id="+session.getId()+",msg="+msg);
+		
+		try {
+			if(session.isOpen()) {
+				broadcast(session, msg);
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+		
+	}
+	// 对于二进制数据 使用byte[]或ByteBuffer
+	@OnMessage
+	public void onMesasge(Session session,byte[] data,boolean isLast) {
+//	public void onMesasge(Session session,ByteBuffer buf,boolean isLast) {
+		
+		String msg = new String(data);
+		System.out.println("dataOnMessage,id="+session.getId()+",msg="+msg);
+		try {
+			if(session.isOpen()) {
+				broadcast(session, msg);
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+	}
+
+	// 使用PongMessage接受pong消息
+	@OnMessage
+	public void onMessage(Session session,PongMessage pong) {
+		System.out.println("pong:"+pong.toString());
+		ByteBuffer buf = pong.getApplicationData();
+		Charset charset = Charset.forName("UTF-8");
+		CharsetDecoder decoder = charset.newDecoder();
+		try {
+			CharBuffer charBuffer = decoder.decode(buf.asReadOnlyBuffer());
+			String pon = charBuffer.toString();
+			System.out.println("pong:"+pon);
+		} catch (CharacterCodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		
+	}
+//	
+	@OnError
+	public void onError(Throwable t) throws Throwable
+    {
+        System.out.println("WebSocket 服务端错误" + t);
+    }
+	
+	private static void broadcast(Session currentSession,String msg) {
+		for(Client client:clientSet) {
+			if(client.getSession().equals(currentSession)) {
+				continue;
+			}
+			
+			try {
+				synchronized (client) {
+					client.getSession().getBasicRemote().sendText(msg);
+					
+				}
+			} catch (Exception e) {
+				// TODO: handle exception
+				System.out.println("向客户端"+client.getClientID()+"发送消息错误");
+				clientSet.remove(client);
+				try {
+					client.getSession().close();
+				} catch (IOException e1) {
+					// TODO Auto-generated catch block
+					e1.printStackTrace();
+					
+				}
+			}
+		}
+	}
+
+}

使用浏览器模拟客户端的文件如下: jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+服务器返回的信息:  
+<input type="text" id="show"/>  
+  
+浏览器发送的信息:  
+<input type="text" id="msg"/>  
+<input type="button" value="send" id="send" onclick="q()"/>  
+
+<script>  
+    var ws = null ;  
+    // 替换为自己的IP地址
+    var target="ws://192.168.2.22:8080/websocket/message";  
+    if ('WebSocket' in window) {  
+        ws = new WebSocket(target);  
+    } else if ('MozWebSocket' in window) {  
+        ws = new MozWebSocket(target);  
+    } else {  
+        alert('WebSocket is not supported by this browser.');  
+    }  
+  
+    ws.onopen = function(obj){  
+        console.info('open') ;  
+        console.info(obj) ;  
+    } ;  
+      
+    ws.onclose = function (obj) {  
+        console.info('close') ;  
+        console.info(obj) ;  
+    } ;  
+    ws.onmessage = function(obj){  
+        console.info(obj) ;  
+        document.getElementById('show').value=obj.data;  
+    } ;  
+    function q(){  
+        ws.send(document.getElementById('msg').value);  
+    }  
+</script>  
+</body>
+</html>

date: 2017-11-27 16:00:00 author: "Gao Fei"

`,13)]))}const S=s(l,[["render",t]]);export{g as __pageData,S as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.lean.js b/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.lean.js new file mode 100644 index 0000000..27707ad --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_webScoket.md.D5yGxqO5.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"WebScoket Introduction","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/webScoket.md","filePath":"frontend/ios/webScoket.md"}'),l={name:"frontend/ios/webScoket.md"};function t(i,n,c,o,r,d){return p(),a("div",null,n[0]||(n[0]=[e("",13)]))}const S=s(l,[["render",t]]);export{g as __pageData,S as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.js b/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.js new file mode 100644 index 0000000..a32eab2 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.js @@ -0,0 +1,54 @@ +import{_ as n,c as a,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const b=JSON.parse('{"title":"\\"WebView\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/webview-share.md","filePath":"frontend/ios/webview-share.md"}'),t={name:"frontend/ios/webview-share.md"};function i(l,s,o,r,c,u){return e(),a("div",null,s[0]||(s[0]=[p(`

"WebView"

WKWebView 发送Post请求

在ios8中 使用如下代码 设置请求体仅在UIWebView中好使,在WKWebView中设置的Content-Length始终为0;也就是发送请求的时候,请求体的内容并没携带一起发送给服务器。 备注:在UIWebView中Content-Length与Content-Type默认会自动创建出来

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
+    NSData *bodyData = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
+    
+    [request setHTTPMethod:@"POST"];
+    [request setValue:[NSString stringWithFormat:@"%ld",bodyData.length] forHTTPHeaderField:@"Content-Length"];
+    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
+    
+    [request setHTTPBody:bodyData];

在WKWebView中需要换种方式处理,即使用js发送post请求,而当webView已经创建的时候,即可执行js。 所以在viewDidLoad方法中调用执行js的方法

js的宏定义如下:

#define POST_JS @"function postWebRequest(path, params) {\\
+var method = \\"POST\\";\\
+var form = document.createElement(\\"form\\");\\
+form.setAttribute(\\"method\\", method);\\
+form.setAttribute(\\"action\\", path);\\
+for(var key in params){\\
+if (params.hasOwnProperty(key)) {\\
+var hiddenFild = document.createElement(\\"input\\");\\
+hiddenFild.setAttribute(\\"type\\", \\"hidden\\");\\
+hiddenFild.setAttribute(\\"name\\", key);\\
+hiddenFild.setAttribute(\\"value\\", params[key]);\\
+}\\
+form.appendChild(hiddenFild);\\
+}\\
+document.body.appendChild(form);\\
+form.submit();\\
+}"
- (WKWebView *)wkWebView
+{
+    if (!_wkWebView){
+        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
+        WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
+        webView.navigationDelegate = self;
+
+        [self.view addSubview:webView];
+        
+        _wkWebView = webView;
+    }
+    return _wkWebView;
+}
+
+- (void)makeWKWebViewPostRequestWithUrl:(NSString *)url param:(NSString *)bodyStr
+{
+
+    
+    NSString *js = [NSString stringWithFormat:@"%@postWebRequest('%@',%@)",POST_JS,url,bodyStr];
+    [self.wkWebView evaluateJavaScript:js completionHandler:^(id _Nullable msg, NSError * _Nullable error) {
+        DLog(@"JavaScriptError=%@",error);
+        
+    }];
+}
- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    NSString *url = @"http://www.xxx.com";
+    NSString *bodyStr = [NSString stringWithFormat:@"{'username':'%@','password':'%@'}",@"zhangsan",@"12345678"];
+    
+   [self makeWKWebViewPostRequestWithUrl:url param:bodyStr];
+}
`,9)]))}const h=n(t,[["render",i]]);export{b as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.lean.js b/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.lean.js new file mode 100644 index 0000000..7214094 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_webview-share.md.BNnvsgQ0.lean.js @@ -0,0 +1 @@ +import{_ as n,c as a,o as e,ag as p}from"./chunks/framework.BHpayLOB.js";const b=JSON.parse('{"title":"\\"WebView\\"","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/webview-share.md","filePath":"frontend/ios/webview-share.md"}'),t={name:"frontend/ios/webview-share.md"};function i(l,s,o,r,c,u){return e(),a("div",null,s[0]||(s[0]=[p("",9)]))}const h=n(t,[["render",i]]);export{b as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.js b/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.js new file mode 100644 index 0000000..85997de --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.js @@ -0,0 +1,147 @@ +import{_ as n,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"ios 自动打包脚本","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/xcode build.md","filePath":"frontend/ios/xcode build.md"}'),l={name:"frontend/ios/xcode build.md"};function t(i,s,c,o,r,h){return p(),a("div",null,s[0]||(s[0]=[e(`

ios 自动打包脚本

1. 配置导出plist文件

在项目工程相同的目录下创建 ExportOptions_UAT.plist 文件,文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>compileBitcode</key>
+	<false/>
+	<key>destination</key>
+	<string>export</string>
+	<key>method</key>
+	<!-- 企业证书打包 -->
+	<string>enterprise</string>
+	<key>provisioningProfiles</key>
+	<dict>
+		<!-- bundle id -->
+		<key>com.xxx.xxxx.xxxx.uat</key>
+		<!-- 描述文件的名称 -->
+		<string>DemoUAT_Distribution</string>
+	</dict>
+	<key>signingCertificate</key>
+	<string>iPhone Distribution</string>
+	<key>signingStyle</key>
+	<string>manual</string>
+	<key>stripSwiftSymbols</key>
+	<true/>
+	<key>teamID</key>
+	<string>P*******3X</string>
+</dict>
+</plist>

1. 配置shell脚本

在项目工程相同的目录下创建 uat_shell.sh 文件,文件的内容如下:

#使用方法
+
+if [ ! -d ./IPADir ];
+then
+mkdir -p IPADir;
+fi
+
+#工程绝对路径
+project_path=$(cd \`dirname $0\`; pwd)
+
+#工程名 将XXX替换成自己的工程名,比如 Demo
+project_name=XXX
+
+#scheme名 将XXX替换成自己的工程的sheme名, 为 target name,比如 Demo_Uat
+scheme_name=XXX
+
+#打包模式 Debug/Release
+development_mode=Release
+
+#build文件夹路径
+build_path=\${project_path}/build
+
+#plist文件所在路径
+exportOptionsPlistPath=\${project_path}/ExportOptions_UAT.plist
+
+#导出.ipa文件所在路径
+exportIpaPath=\${project_path}/IPADir/\${development_mode}
+
+
+echo "Place enter the number you want to export ? [ 1:app-store 2:enterprise] "
+
+##
+read number
+while([[ $number != 1 ]] && [[ $number != 2 ]])
+do
+echo "Error! Should enter 1 or 2"
+echo "Place enter the number you want to export ? [ 1:app-store 2:enterprise] "
+read number
+done
+
+if [ $number == 1 ];then
+development_mode=Release
+exportOptionsPlistPath=\${project_path}/exportAppstore.plist
+else
+development_mode=Release
+exportOptionsPlistPath=\${project_path}/ExportOptions_UAT.plist
+fi
+
+
+echo '///-----------'
+echo '/// 正在清理工程'
+echo '///-----------'
+xcodebuild \\
+clean -configuration \${development_mode} -quiet  || exit
+
+
+echo '///--------'
+echo '/// 清理完成'
+echo '///--------'
+echo ''
+
+echo '///-----------'
+echo '/// 正在编译工程:'\${development_mode}
+echo '///-----------'
+xcodebuild \\
+archive -workspace \${project_path}/\${project_name}.xcworkspace \\
+-scheme \${scheme_name} \\
+-configuration \${development_mode} \\
+-archivePath \${build_path}/\${project_name}.xcarchive  -quiet  || exit
+
+echo '///--------'
+echo '/// 编译完成'
+echo '///--------'
+echo ''
+
+echo '///----------'
+echo '/// 开始ipa打包'
+echo '///----------'
+xcodebuild -exportArchive -archivePath \${build_path}/\${project_name}.xcarchive \\
+-configuration \${development_mode} \\
+-exportPath \${exportIpaPath} \\
+-exportOptionsPlist \${exportOptionsPlistPath} \\
+-quiet || exit
+
+if [ -e $exportIpaPath/$scheme_name.ipa ]; then
+echo '///----------'
+echo '/// ipa包已导出'
+echo '///----------'
+open $exportIpaPath
+else
+echo '///-------------'
+echo '/// ipa包导出失败 '
+echo '///-------------'
+fi
+echo '///------------'
+echo '/// 打包ipa完成  '
+echo '///-----------='
+echo ''
+
+echo '///-------------'
+echo '/// 开始发布ipa包 '
+echo '///-------------'
+
+if [ $number == 1 ];then
+
+#验证并上传到App Store
+# 将-u 后面的XXX替换成自己的AppleID的账号,-p后面的XXX替换成自己的密码
+altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
+"$altoolPath" --validate-app -f \${exportIpaPath}/\${scheme_name}.ipa -u XXX -p XXX -t ios --output-format xml
+"$altoolPath" --upload-app -f \${exportIpaPath}/\${scheme_name}.ipa -u  XXX -p XXX -t ios --output-format xml
+else
+
+#上传到Fir
+# 将XXX替换成自己的Fir平台的token
+fir login -T XXX
+fir publish $exportIpaPath/$scheme_name.ipa
+
+fi
+
+exit 0

date: 2020-12-17 14:00:00 author: "Gao Fei"

`,8)]))}const g=n(l,[["render",t]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.lean.js b/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.lean.js new file mode 100644 index 0000000..efa8e10 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_ios_xcode build.md.D8nyWHzf.lean.js @@ -0,0 +1 @@ +import{_ as n,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"ios 自动打包脚本","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/ios/xcode build.md","filePath":"frontend/ios/xcode build.md"}'),l={name:"frontend/ios/xcode build.md"};function t(i,s,c,o,r,h){return p(),a("div",null,s[0]||(s[0]=[e("",8)]))}const g=n(l,[["render",t]]);export{u as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.js b/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.js new file mode 100644 index 0000000..aeec2ae --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.js @@ -0,0 +1 @@ +import{_ as a,c as l,o as i,ag as t}from"./chunks/framework.BHpayLOB.js";const p=JSON.parse('{"title":"JS 的使用","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/js/index.md","filePath":"frontend/js/index.md"}'),r={name:"frontend/js/index.md"};function o(n,e,s,d,c,u){return i(),l("div",null,e[0]||(e[0]=[t('

JS 的使用

Web JS的组成

ECMAScript + DOM + BOM

  • ECMAScript(前身为欧洲计算机制造商协会)
  • JavaScript的语法规范
  • DOM(Document Object Model 的简称)
  • JavaScript操作网页上元素的API
  • BOM(Browser Object Model 的简称)
  • JavaScript操作浏览器部分功能的API

输出语句

  • console.log(“内容”)在控制台打印输出内容
  • console.error(“错误”)在控制台打印输出错误内容
  • console.warn(“警告”)在控制台打印输出警告内容
  • alert(“内容”)弹窗显示内容
  • document.write(“内容”)在页面书写内容
  • prompt(“输入”)
  • confirm(“”)

数据类型

  1. 值类型
  • 字符串 数字 布尔 未定义
  • String Number Boolean undefined
  1. 引用类型
    • Object function Array Date null ...

3.1. 值类型介绍

函数

js中没有方法重载 函数也是一种类型

date: 2018-10-05 14:00:00 author: "Gao Fei"

',14)]))}const _=a(r,[["render",o]]);export{p as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.lean.js b/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.lean.js new file mode 100644 index 0000000..dd976e8 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_js_index.md.DIBkZ4Z0.lean.js @@ -0,0 +1 @@ +import{_ as a,c as l,o as i,ag as t}from"./chunks/framework.BHpayLOB.js";const p=JSON.parse('{"title":"JS 的使用","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/js/index.md","filePath":"frontend/js/index.md"}'),r={name:"frontend/js/index.md"};function o(n,e,s,d,c,u){return i(),l("div",null,e[0]||(e[0]=[t("",14)]))}const _=a(r,[["render",o]]);export{p as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.js b/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.js new file mode 100644 index 0000000..31dc0c1 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.js @@ -0,0 +1,34 @@ +import{_ as a,c as s,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"ionic 入门","description":"","frontmatter":{"layout":"post","title":"ionic 入门","subtitle":"基础","date":"2020-03-12T14:00:00.000Z","author":"Gao Fei","header-img":"img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/2020-03-12-ionic.md","filePath":"frontend/other/2020-03-12-ionic.md"}'),i={name:"frontend/other/2020-03-12-ionic.md"};function t(l,n,o,c,r,d){return p(),s("div",null,n[0]||(n[0]=[e(`

ionic 入门

1. 通过npm搭建开发环境

# 安装ionic 命令行工具
+$ sudo npm install -g @ionic/cli

2. 初始化项目


+$ ionic start <name> <template> [options]
+
+Inputs:
+
+    name ..... The name of your new project (e.g. myApp,
+                                      "My App")
+    template ..... The starter template to use (e.g. blank,
+                                      tabs; use --list to see all)
+
+  Options:
+
+    --list, -l .... List available starter templates
+    --type=<type> ..... Type of project to start (e.g. angular,
+                                      react, ionic-angular, ionic1)
+    --cordova ... Include Cordova integration
+    --capacitor ... (experimental) Include Capacitor
+                                      integration
+    --id=<id> ...... Specify an Ionic App ID to link
+
+  Advanced Options:
+
+    --no-deps ..... Do not install npm/yarn dependencies
+    --no-git .... Do not initialize a git repo
+    --link ...... Connect your new app to Ionic
+    --project-id=<slug> ... Specify a slug for your app (used for the
+                                      directory name and package name)
+    --package-id=<id> ..... Specify the bundle ID/application ID for
+                                      your app (reverse-DNS notation)
+                                      
+#创建名为myApp的工程 使用v4 TLS 版本
+$ ionic start myApp sidemenu --V4
+$ ionic start myApp tabs
`,5)]))}const h=a(i,[["render",t]]);export{g as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.lean.js b/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.lean.js new file mode 100644 index 0000000..f2fe9e5 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_2020-03-12-ionic.md.5dqZ3YTS.lean.js @@ -0,0 +1 @@ +import{_ as a,c as s,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"ionic 入门","description":"","frontmatter":{"layout":"post","title":"ionic 入门","subtitle":"基础","date":"2020-03-12T14:00:00.000Z","author":"Gao Fei","header-img":"img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/2020-03-12-ionic.md","filePath":"frontend/other/2020-03-12-ionic.md"}'),i={name:"frontend/other/2020-03-12-ionic.md"};function t(l,n,o,c,r,d){return p(),s("div",null,n[0]||(n[0]=[e("",5)]))}const h=a(i,[["render",t]]);export{g as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.js b/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.js new file mode 100644 index 0000000..ca8f4f5 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.js @@ -0,0 +1,64 @@ +import{_ as s,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"angular 入门","description":"","frontmatter":{"layout":"post","title":"angular 入门","subtitle":"基础","date":"2020-03-12T14:00:00.000Z","author":"Gao Fei","header-img":"/img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/2020-03-22-angular.md","filePath":"frontend/other/2020-03-22-angular.md"}'),l={name:"frontend/other/2020-03-22-angular.md"};function i(t,a,o,c,r,d){return p(),n("div",null,a[0]||(a[0]=[e(`

angular 入门

1. angular

特点

# 安装ionic 命令行工具
+$ sudo npm install -g @angular/cli

2. 初始化项目

cd 到需要创建项目的目录下
+$ ng new <projectname>
+# 1. 先创建,再安装
+$ ng new <projectname> --skip-install
+$ cd <projectname>
+$ cnpm install
+
+#运行
+$ ng serve --open
+
+#创建组件,在app目录下,创建components目录并创建home组件
+$ ng g component components/home

2.1 安装插件

cd 到需要创建项目的目录下
+配置在生产环境
+$ cnpm install xxx --save
+配置在开发环境
+$ cnpm install xxx --save-dev

3. 组件

3.1 插值语法和表达式

# 1. 绑定数据
+{{xxx}}
+本地图片数据
+src = 'assets/images/xx.png'

3.2 绑定

值绑定 [],
+事件绑定 (),
+双向绑定[()]
+
+值绑定
+[innerHTML]= "xxxxx"
+[src]="属性"
+
+事件绑定
+ (click)="action()"
+ (keydown)="action($event)"
+ 
+ 双向绑定,用于表单元素
+ import { FormsModule} from '@angular/forms';
+ imports: [
+    FormsModule
+  ],
+  [(ngModel)]="binding"
action(e){
+console.log(e.target.value)
+}

3.3 内置结构型指令用法

循环数据

*ngFor ="let item of list"

条件判断

*ngIf ="flag"

选择

*ngSwitch
+
+<div [ngSwitch]="conditionExpression">
+    <div *ngSwitchCase="expression">output</div>
+    <div *ngSwitchDefault>output2</div>
+</div>

3.3 内置属性型指令用法

ngCalss,ngStyle,ngModel

管道 使用 |

安全取值 使用 ?

4. 组件间通讯

父子组件之间的交互 @Input/@Output/模板变量/@ViewChild

@ViewChild
+1.在dom中命名
+
+2. 在业务逻辑里面引入ViewChild
+3. 写在类里面
+4. ngAfterViewInit生命周期函数里面获取dom
+5.

非父子组件之间的交互 service/localStorage

1. ng g service services/storge
+2. app.modules.ts 中引入刚才创建的服务
+	import {StorgeService} from './services/storge.service';
+	providers: [StorgeService],
+3. 在使用的组件中导入
+	// 引入服务
+	import {StorgeService} from '../../services/storge.service';
+	// 初始化方法中申明
+	constructor( public storge:StorgeService) { 
+    this.storge.get();
+
+  }

利用session、路由参数来进行通讯

生命周期函数

ngOninit()
+在angular
+ngAfterviewInit()
+ngOnDestroy()

常见异步编程 回调函数 事件监听/发布订阅 Promise Rxjs 一种针对异步编程工具,或者叫响应式扩展编程

UI libraries PrimeNG :最完善的开源库 NG-Zorro: 阿里云开源库 Jigsaw: 中兴通讯 Clarity 来自vmware ionic: 移动端组件库

ng2-admin JHipster 基于springMVC

vs code debug angular

font awesome

插值语法和表达式

5. 路由

`,40)]))}const u=s(l,[["render",i]]);export{g as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.lean.js b/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.lean.js new file mode 100644 index 0000000..5680f6d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_2020-03-22-angular.md.BZyIkX6a.lean.js @@ -0,0 +1 @@ +import{_ as s,c as n,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"angular 入门","description":"","frontmatter":{"layout":"post","title":"angular 入门","subtitle":"基础","date":"2020-03-12T14:00:00.000Z","author":"Gao Fei","header-img":"/img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/2020-03-22-angular.md","filePath":"frontend/other/2020-03-22-angular.md"}'),l={name:"frontend/other/2020-03-22-angular.md"};function i(t,a,o,c,r,d){return p(),n("div",null,a[0]||(a[0]=[e("",40)]))}const u=s(l,[["render",i]]);export{g as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.js b/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.js new file mode 100644 index 0000000..3fbd519 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.js @@ -0,0 +1,24 @@ +import{_ as e,c as s,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"react 入门","description":"","frontmatter":{"layout":"post","title":"react 入门","subtitle":"基础","date":"2020-03-08T14:00:00.000Z","author":"Gao Fei","header-img":"/img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/index.md","filePath":"frontend/other/index.md"}'),p={name:"frontend/other/index.md"};function l(i,a,o,r,c,d){return n(),s("div",null,a[0]||(a[0]=[t(`

React 入门

1. 通过npm搭建开发环境

$ npm install babel -g
+$ npm install webpack -g
+$ npm install webpack-dev-server -g
+
+如果使用以上命令报错
+可以更换如下
+# 增加了访问本地目录的权限
+$ sudo npm install webpack -g --unsafe-perm=true --allow-root
+$ sudo npm install webpack-cli -g --unsafe-perm=true --allow-root
+$ sudo npm install webpack-dev-server -g --unsafe-perm=true --allow-root
+# 切换到工程目录下
+$ npm install @babel/preset-env --save-dev

2. 初始化项目

# npm 6 以上的版本
+$ npm init react-app my-app
+#低版本的npm
+$ npx create-react-app my-app
+$ cd my-app
+$ yarn start
+$ npm start

3.JSX 语法

使用jsx 来替代常规的js语法 javascript + XML语法(HTML)

组件

声明

函数组件

function Welcome(props) {
+  return <h1>Hello, {props.name}</h1>;
+}

class 组件

class Welcome extends React.Component {
+  render() {
+    return <h1>Hello, {this.props.name}</h1>;
+  }
+}

调用赋值

<Welcome name="Sara" />

props 属性

通过props 属性 添加

事件处理

this 向事件传递参数

state

生命周期函数

组件的生命周期可分成三个状态:

  • Mounting:已插入真实 DOM;
  • Updating:正在被重新渲染;
  • Unmounting:已移出真实 DOM.

生命周期的方法有:

  • componentWillMount 在渲染前调用,在客户端也在服务端。
  • componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
  • componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
  • shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
  • componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
  • componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
  • componentWillUnmount在组件从 DOM 中移除之前立刻被调用

子传父 传值 父传子 传值

setState 更新时同步还是异步

  1. setState 会引起视图的重绘
  2. 组件

条件渲染

列表 & key

导入 antd

Fetch

get/post 跨域的问题 package 配置

Router

安装

$ npm install react-router-dom --save

路由的作用 单页面 应用(SPA),路由的作用为切换视图、删除视图

Redux

`,38)]))}const m=e(p,[["render",l]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.lean.js b/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.lean.js new file mode 100644 index 0000000..0295b39 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_other_index.md.C6cSlaNs.lean.js @@ -0,0 +1 @@ +import{_ as e,c as s,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"react 入门","description":"","frontmatter":{"layout":"post","title":"react 入门","subtitle":"基础","date":"2020-03-08T14:00:00.000Z","author":"Gao Fei","header-img":"/img/post-bg-ios9-web.jpg","tags":["git"]},"headers":[],"relativePath":"frontend/other/index.md","filePath":"frontend/other/index.md"}'),p={name:"frontend/other/index.md"};function l(i,a,o,r,c,d){return n(),s("div",null,a[0]||(a[0]=[t("",38)]))}const m=e(p,[["render",l]]);export{u as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.js b/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.js new file mode 100644 index 0000000..f4b16cd --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.js @@ -0,0 +1 @@ +import{_ as e,c as i,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const c="/assets/newproject_2x.E4tz2V26.png",w=JSON.parse('{"title":"基本设置","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/01-Getting Started/Basic Setup.md","filePath":"frontend/swift/01-Getting Started/Basic Setup.md"}'),n={name:"frontend/swift/01-Getting Started/Basic Setup.md"};function d(r,t,s,l,p,f){return a(),i("div",null,t[0]||(t[0]=[o('

基本设置

Swift 可无缝兼容 Cocoa 和 Objective-C。在 Swift,可以使用 Objective-C API,也可以在 Objective-C 中使用 Swift API。这种兼容性能让 Swift 作为一个简洁、易用、强大的工具集成到你的 Cocoa 应用开发流程中。

这篇指南包括了三个有关兼容性的重要方面,能够帮你更好地利用这种兼容性来开发 Cocoa 应用:

  • 交互 可以将 Swift 和 Objective-C 相接合,在 Objective-C 中使用 Swift 类,并利用熟悉的 Cocoa 类、设计模式以及各种实践经验。
  • 混搭 可以创建结合了 Swift 和 Objective-C 文件的混合语言应用,并且它们能跟彼此进行通信。
  • 迁移 由于以上两点,从现有的 Objective-C 代码迁移到 Swift 会非常简单,这使运用最新的 Swift 特性取代你的 Objective-C 应用中的部分内容成为了可能。

在开始学习这些特性前,需要对如何搭建 Swift 环境来使用 Cocoa 系统框架有个大致了解。

搭建 Swift 环境

为了开始体验在 Swift 中访问 Cocoa 框架,使用 Xcode 的一个模板来创建一个基于 Swift 的应用。

在 Xcode 中创建一个 Swift 项目

1.选择File > New > Project > (iOS,watchOS,tvOS 或 OS X) > Application,然后选择一个模板。

2.点击Language下拉菜单并选择 Swift。

Swift 项目的结构几乎和 Objective-C 项目一模一样,只有一个重要的区别:Swift 没有头文件。在接口和实现之间没有显式划分,一个类中的所有信息都在一个单独的.swift文件中,详情请参阅 在项目中同时使用 Swift 和 Objective-C 章节。

现在可以开始尝试在AppDelegate中编写 Swift 代码,或者可以选择File > New > File > (iOS,watchOS,tvOS 或 OS X) > Source > Swift来创建一个新的 Swift 文件。

要求

使用 Swift 3.0 创建应用需要使用 Xcode 8.0 或更高版本,而且使用的 SDK 有如下要求:

平台SDK 要求
macOS10.12
iOS10.0
watchOS3.0
tvOS10.0

Swift 编译器和 Xcode 强制要求最低部署版本为iOS 7macOS 10.9,设置更早的部署版本会导致编译错误。

注意
由命令行构建的 Swift 可执行文件必须能在它的@rpath下找到 Swift 标准库,因此发布时需要同时包含 Swift 动态库。由 Xcode 构建的 Swift 可执行文件则自带静态链接的运行时库。

理解 Swift 导入过程

在你建立 Xcode 项目后,可以在 Swift 里导入任何 Cocoa 或者 Cocoa Touch 的框架。

任何 Objective-C 框架或 C 语言类库,都将作为一个module直接导入到 Swift 中。这包括了所有 Objective-C 系统框架——比如 Foundation、UIKit 和 SpriteKit,以及系统支持的 C 语言类库。例如,想导入 Foundation,只要简单地添加导入语句到 Swift 文件的顶部:

swift
import Foundation

通过这个导入语句,Swift 文件现在可以访问所有 Foundation 中的类、协议、方法、属性以及常量。

导入过程非常简单。Objective-C 框架在头文件中公开 API。在 Swift,那些头文件被编译成 Objective-C 模块,接着被导入到 Swift 作为 Swift 的 API。导入过程决定了 Objective-C 代码中的函数、类、方法以及声明的类型如何在 Swift 中呈现。对于函数和方法,这个过程将影响它们的参数和返回值的类型。对于类型来说,导入过程会做以下处理:

  • 重映射 Objective-C 类型到 Swift 中的同等类型,例如id映射为Any
  • 重映射 Objective-C 核心类型到 Swift 中的替代类型,例如NSString映射为String
  • 重映射 Objective-C 概念到 Swift 中相对应的概念,例如指针映射为可选类型

想了解更多信息,请参阅 与 Objective-C API 交互 章节。

注意
C++ 代码无法直接导入 Swift,必须为其创建 Objective-C 或者 C 的封装。

导入 Swift 模块到 Objective-C 和上述过程非常相似。Swift 公开它的 API,例如来自系统框架的 API,作为 Swift 模块。随着这些 Swift 模块还会生成 Objective-C 头文件。这些头文件公开了那些可以映射回 Objective-C 的 API。一些 Swift API 无法映射回 Objective-C,因为它们使用了 Objective-C 中不存在的语言特性。

想了解更多信息,请参阅 在项目中同时使用 Swift 和 Objective-C 章节。

',32)]))}const h=e(n,[["render",d]]);export{w as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.lean.js b/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.lean.js new file mode 100644 index 0000000..edbb96b --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_01-Getting Started_Basic Setup.md.BLffIB_N.lean.js @@ -0,0 +1 @@ +import{_ as e,c as i,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const c="/assets/newproject_2x.E4tz2V26.png",w=JSON.parse('{"title":"基本设置","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/01-Getting Started/Basic Setup.md","filePath":"frontend/swift/01-Getting Started/Basic Setup.md"}'),n={name:"frontend/swift/01-Getting Started/Basic Setup.md"};function d(r,t,s,l,p,f){return a(),i("div",null,t[0]||(t[0]=[o("",32)]))}const h=e(n,[["render",d]]);export{w as __pageData,h as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.js new file mode 100644 index 0000000..6bbc574 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.js @@ -0,0 +1,237 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"与 Objective-C API 交互","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md","filePath":"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md"}'),h={name:"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md"};function l(e,s,k,p,d,E){return n(),a("div",null,s[0]||(s[0]=[t(`

与 Objective-C API 交互

互用性是能让 Swift 和 Objective-C 相接合的特性,这使你能够在一种语言编写的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,学会如何利用互用性来重新定义、改善并提高你编写 Cocoa 应用的方法,不失为一个好主意。

互用性很重要的一点就是允许你在编写 Swift 代码时使用 Objective-C API。导入一个 Objective-C 框架后,可以使用原生的 Swift 语法实例化这些类并与之交互。

初始化

要在 Swift 中实例化一个 Objective-C 类,你应该使用 Swift 语法调用它的一个构造器。

Objective-C 构造器以init开头,如果它接收参数,则会以initWith开头。Objective-C 构造器导入到 Swift 后,init前缀变为init关键字,以此表明该方法是 Swift 构造方法。如果构造器接收参数,With单词会被移除,方法名的其余部分则会被分配为相应的命名参数。

例如,思考如下 Objective-C 构造器声明:

objective-c
- (instancetype)init;
+- (instancetype)initWithFrame:(CGRect)frame
+                        style:(UITableViewStyle)style;

Swift 中等价的构造器声明如下所示:

swift
init() { /* ... */ }
+init(frame: CGRect, style: UITableViewStyle) { /* ... */ }

Objective-C 和 Swift 构造器语法的区别在实例化对象时将更为明显:

在 Objective-C 这样写:

objective-c
UITableView *myTableView = [[UITableView alloc] initWithFrame:.zero 
+                                                        style:UITableViewStyleGrouped];

在 Swift 则应该这样写:

swift
let myTableView: UITableView = UITableView(frame: .zero, style: .grouped)

注意,你不需要调用alloc,Swift 会为你处理。另外,调用任何 Swift 构造方法时都不会出现init单词。

你可以在赋值时显式地声明类型,也可以省略类型,Swift 能从构造器自动推断出类型。

swift
let myTextField = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 40.0))

此处的UITableViewUITextField对象和你在 Objective-C 中实例化的一样。你可以用同样的方式使用它们,例如访问属性或者调用各自类中的方法。

类工厂方法和便利构造器

为了统一和简洁,Objective-C 中的类工厂方法被导入为 Swift 中的便利构造器,从而能使用同样简洁的构造器语法。

例如,在 Objective-C 像这样调用一个工厂方法:

objective-c
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

在 Swift 应该这样写:

swift
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

可失败初始化

在 Objective-C,构造器会直接返回它们初始化的对象。初始化失败时,为了告知调用者,Objective-C 构造器会返回nil。在 Swift,这种模式被内置到语言特性中,被称为可失败初始化

许多系统框架中的 Objective-C 构造器在导入到 Swift 时会被检查初始化是否会失败。你可以在你的 Objective-C 类中,使用为空性标注来指明初始化是否会失败,请参阅 为空性和可选类型 小节。如果初始化不会失败,这些 Objective-C 构造器会作为init(...)导入,而如果初始化会失败,则会作为init?(...)导入。在没有任何为空性标注的情况下,Objective-C 构造器会作为init!(...)导入。

例如,当指定路径的图片文件不存在时,使用UIImage(contentsOfFile:)构造器初始化UIImage对象便会失败。你可以用可选绑定语法对这种构造器的可选类型的返回值进行解包,从而判断初始化是否成功。

swift
if let image = UIImage(contentsOfFile: "MyImage.png") {
+    // 加载图片成功
+} else {
+    // 无法加载图片
+}

访问属性

在 Objective-C 中使用@property语法声明的属性会以如下方式导入到 Swift:

  • 具有为空性属性特性的属性(nonnullnullablenull_resettable),作为可选类型或者非可选类型的属性导入。请参阅 为空性和可选类型 小节。
  • 具有readonly属性特性的属性,作为只读计算型属性({ get })导入。
  • 具有weak属性特性的属性,作为标记weak关键字(weak var)的属性导入。
  • 具有assigncopystrongunsafe_unretained属性特性的属性,导入后会具有相应的内存管理策略。
  • 具有class属性特性的属性,作为类型属性导入。
  • 原子属性特性(atomicnonatomic)在 Swift 属性声明中并无相应体现,不过 Objective-C 中具有原子性的属性在 Swift 中将保持其原子性。
  • 存取器属性特性(getter=setter=)会被 Swift 忽略。

在 Swift 中使用点语法对属性进行存取,直接使用属性名即可,不需要附加圆括号。

例如,如下代码设置了UITextField对象的textColortext属性:

swift
myTextField.textColor = UIColor.darkGray
+myTextField.text = "Hello world"

在 Objective-C,一个有返回值的无参数方法可以像属性那样使用点语法调用。然而,它们会被导入为 Swift 中的实例方法,只有在 Objective-C 中使用@property声明的属性才会导入为 Swift 中的属性。方法的导入和调用请参阅 方法 小节。

方法

在 Swift 中使用点语法调用方法。

当 Objective-C 方法导入到 Swift 时,Objective-C 选择器的第一部分将会成为基本方法名并出现在圆括号的前面。第一个参数将直接在圆括号中出现,并且没有参数名。选择器的其余部分作为相应的参数名,出现在方法的圆括号内。选择器的所有部分在调用时都必须写上。

例如,在 Objective-C 这样写:

objective-c
[myTableView insertSubview:mySubview atIndex:2];

在 Swift 则应该这样写:

swift
myTableView.insertSubview(mySubview, atIndex: 2)

如果调用一个无参数的方法,仍须在方法名后面跟上一对圆括号:

swift
myTableView.layoutIfNeeded()

id 兼容性

Objective-C 中的id类型会作为 Swift 中的Any类型导入。无论在编译期还是运行期,当 Swift 值或者对象作为id参数传入 Objective-C 时,编译器都会引入一种通用的桥接转换操作。当id类型作为Any类型导入到 Swift 时,运行时会自动处理桥接回相应的 Swift 类类型或值类型的工作。

swift
var x: Any = "hello" as String
+x as? String   // 值为 "hello" 的 String 
+x as? NSString // 值为 "hello" 的 NSString
+
+x = "goodbye" as NSString
+x as? String   // 值为 "goodbye" 的 String
+x as? NSString // 值为 "goodbye" 的 NSString

将 Any 向下转换

使用一个Any类型的对象时,如果其具体类型已知或者可以断定,将其向下转换到具体类型往往会更有用处。然而,由于Any类型可以引用任何类型,因此无法保证向下转换到具体类型一定成功。

可以使用条件转换操作符(as?),这将返回目标类型的可选值:

swift
let userDefaults = UserDefaults.standard
+let lastRefreshDate = userDefaults.object(forKey: "LastRefreshDate") // lastRefreshDate 类型为 Any?
+if let date = lastRefreshDate as? Date {
+    print("\\(date.timeIntervalSinceReferenceDate)")
+}

如果确信对象的类型,可以使用强制下转操作符(as!):

swift
let myDate = lastRefreshDate as! Date
+let timeInterval = myDate.timeIntervalSinceReferenceDate

然而,一旦强制下转失败,将触发一个运行时错误:

swift
let myDate = lastRefreshDate as! String // Error

动态方法查找

Swift 还引入了AnyObject类型来表示一种对象类型,这种对象具有能够动态查找@objc方法的能力。这使你在访问返回值为id类型的 Objective-C 方法时能保持无类型的灵活性。

例如,你可以将任意类型的对象赋值给一个AnyObject类型的常量或者变量,如果是变量,你还可以再用其他类型的对象为其赋值。你还可以在AnyObject类型的值上调用任意 Objective-C 方法以及访问属性,而无需将其转换为具体类型。

swift
var myObject: AnyObject = UITableViewCell()
+myObject = NSDate()
+let futureDate = myObject.addingTimeInterval(10)
+let timeSinceNow = myObject.timeIntervalSinceNow

无法识别的选择器和可选链语法

因为AnyObject类型的值在运行时才能确定其真实类型,所以有可能在不经意间写出不安全代码。在 Swift,和 Objective-C 一样,试图调用不存在的方法将触发未识别的选择器错误。

例如,如下代码在编译时没有任何编译警告,但是会在运行时触发一个错误:

swift
myObject.character(at: 5)
+// 崩溃,myObject 无法响应该方法

Swift 使用可选来防止这种不安全的行为。当用AnyObject类型的值调用一个 Objective-C 方法时,方法调用在行为上类似于隐式解包可选。可以像调用协议中的可选方法那样,使用可选链语法在AnyObject上调用方法。

例如,在下面的代码中,第一和第二行代码不会被执行,因为count属性和character(at:)方法不存在于NSDate对象中。myCount常量会被推断为Int?,并被赋值为nil。你也可以使用if-let语句来有条件地解包这种可能无法被响应的方法的返回值,就像第三行所做的一样。

swift
// myObject 类型为 AnyObject,保存着 NSDate 类型的值
+let myCount = myObject.count // myCount 类型为 Int?,其值为 nil
+let myChar = myObject.character?(at: 5) // myChar 类型为 unichar?,其值为 nil
+if let fifthCharacter = myObject.character?(at: 5) { 
+    print("Found \\(fifthCharacter) at index 5") // 条件分支不会被执行
+}

注意
尽管在使用AnyObject类型的值调用方法时不需要强制解包,但建议使用强制解包的方式来防止一些意想不到的行为。

为空性和可选类型

在 Objective-C,用于操作对象的原始指针的值可能会是NULL(在 Objective-C 中称为nil)。而在 Swift,所有的值,包括结构体与对象的引用,都能确保是非空值。作为替代,可以将可能会值缺失的值包装为该类型的可选类型。当你需要表示值缺失的情况时,你可以将其赋值为nil。请参阅 The Swift Programming Language 中文版 中的 可选类型 小节获取更多关于可选类型的信息。

在 Objective-C 可以使用为空性标注来指明一个参数类型、属性类型或者返回值类型是否可以为NULLnil值。单个类型声明可以使用_Nullable_Nonnull标注,单个属性声明可以使用nullablenonnullnull_resettable属性特性,批量标注可以使用NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END宏。如果一个类型没有任何为空性标注,Swift 就无法辨别它是可选类型还是非可选类型,因此将其作为隐式解包可选类型导入。

  • _Nonnull或者范围宏标注的类型,会作为非可选类型导入到 Swift。
  • _Nullable标注的类型,会作为可选类型导入到 Swift。
  • 没有为空性标注的类型,会作为隐式解包可选类型导入到 Swift。

举个例子,思考如下 Objective-C 声明:

objective-c
@property (nullable) id nullableProperty;
+@property (nonnull) id nonNullProperty;
+@property id unannotatedProperty;
+ 
+NS_ASSUME_NONNULL_BEGIN
+- (id)returnsNonNullValue;
+- (void)takesNonNullParameter:(id)value;
+NS_ASSUME_NONNULL_END
+ 
+- (nullable id)returnsNullableValue;
+- (void)takesNullableParameter:(nullable id)value;
+ 
+- (id)returnsUnannotatedValue;
+- (void)takesUnannotatedParameter:(id)value;

导入到 Swift 后将如下所示:

swift
var nullableProperty: Any?
+var nonNullProperty: Any
+var unannotatedProperty: Any!
+
+func returnsNonNullValue() -> Any
+func takesNonNullParameter(value: Any)
+
+func returnsNullableValue() -> Any?
+func takesNullableParameter(value: Any?)
+
+func returnsUnannotatedValue() -> Any!
+func takesUnannotatedParameter(value: Any!)

大多数 Objective-C 系统框架,包括 Foundation,都已经提供了为空性标注,这使你能以更加类型安全的方式去操作各种值。

将可选值桥接为 NSNull 实例

Swift 会根据可选值是否有值来决定是否将其桥接为 Objective-C 的NSNull实例。如果可选值的值为nil,Swift 会将nil值桥接为NSNull实例。否则,Swift 会将可选值桥接为它所包装的值。例如,当一个可选值传给一个接受非空id类型参数的 Objective-C API 时,或者将一个元素为可选类型的数组([T?])桥接为NSArray时。

如下代码展示了String?实例如何根据它是否有值来桥接到 Objective-C。

objective-c
@implementation OptionalBridging
++ (void)logSomeValue:(nonnull id)valueFromSwift {
+    if ([valueFromSwift isKindOfClass: [NSNull class]]) {
+        os_log(OS_LOG_DEFAULT, "Received an NSNull value.");
+    } else {
+        os_log(OS_LOG_DEFAULT, "%s", [valueFromSwift UTF8String]);
+    }
+}
+@end

因为valueFromSwift参数的类型是id,它会作为Any类型导入到 Swift。由于很少将可选值传递给Any类型,因此在将可选值传递给类方法logSomeValue(_:)时需要将参数显式转换为Any类型,从而消除编译警告。

swift
let someValue: String? = "Bridge me, please."
+let nilValue: String? = nil
+
+OptionalBridging.logSomeValue(someValue as Any)  // Bridge me, please.
+OptionalBridging.logSomeValue(nilValue as Any)   // Received an NSNull value.

协议限定类

Objective-C 中被一个或多个协议限定的类会作为协议组合类型导入到 Swift。例如,如下 Objective-C 属性引用一个视图控制器:

objective-c
@property UIViewController<UITableViewDataSource, UITableViewDelegate> * myController;

该属性会以如下形式导入到 Swift:

swift
var myController: UIViewController & UITableViewDataSource & UITableViewDelegate

Objective-C 中的协议限定元类会作为协议元类导入到 Swift。例如,如下 Objective-C 方法会在指定类上执行一个操作:

objective-c
- (void)doSomethingForClass:(Class<NSCoding>)codingClass;

如下代码展示了 Swift 如何导入它:

swift
func doSomething(for codingClass: NSCoding.Type)

轻量泛型

Objective-C 的NSArrayNSSet以及NSDictionary类型的声明在使用轻量泛型参数化后,被导入到 Swift 时会附带容器中元素的类型信息。

例如,思考如下 Objective-C 属性声明:

objective-c
@property NSArray<NSDate *> *dates;
+@property NSCache<NSObject *, id<NSDiscardableContent>> *cachedData;
+@property NSDictionary <NSString *, NSArray<NSLocale *>> *supportedLocales;

导入到 Swift 后将如下所示:

swift
var dates: [Date]
+var cachedData: NSCache<AnyObject, NSDiscardableContent>
+var supportedLocales: [String: [Locale]]

使用了轻量泛型的 Objective-C 类会作为泛型类导入到 Swift。所有 Objective-C 泛型类型参数导入到 Swift 后,都会带有类型约束来要求该类型必须是一个类类型。如果 Objective-C 泛型参数化带有类限定,导入到 Swift 后,它会带有一个类型约束来要求该类必须是指定类的子类。与之类似,如果带有协议限定,导入到 Swift 后,它会带有一个类型约束来要求该类必须符合指定协议。如果未特别指定类型限定,Swift 会将根据泛型类的类型约束来推断泛型参数化。例如,思考如下 Objective-C 类声明和分类声明:

objective-c
@interface List<T: id<NSCopying>> : NSObject
+- (List<T> *)listByAppendingItemsInList:(List<T> *)otherList;
+@end
+
+@interface ListContainer : NSObject
+- (List<NSValue *> *)listOfValues;
+@end
+
+@interface ListContainer (ObjectList)
+- (List *)listOfObjects;
+@end

上述声明将以如下形式导入到 swift:

swift
class List<T: NSCopying> : NSObject {
+    func listByAppendingItemsInList(otherList: List<T>) -> List<T>
+}
+
+class ListContainer : NSObject {
+    func listOfValues() -> List<NSValue>
+}
+
+extension ListContainer {
+    func listOfObjects() -> List<NSCopying>
+}

扩展

Swift 扩展和 Objective-C 分类相似。扩展可以为既有类,结构和枚举扩充功能,即使它们是在 Objective-C 中定义的。通过导入相应的模块,还可以为系统框架中的类型或者自定义类型定义扩展。

例如,可以扩展UIBezierPath类,基于三角形的边长与起点来创建一个简单的三角形路径。

swift
extension UIBezierPath {
+    convenience init(triangleSideLength: CGFloat, origin: CGPoint) {
+        self.init()
+        let squareRoot = CGFloat(sqrt(3.0))
+        let altitude = (squareRoot * triangleSideLength) / 2
+        move(to: origin)
+        addLine(to: CGPoint(x: origin.x + triangleSideLength, y: origin.y))
+        addLine(to: CGPoint(x: origin.x + triangleSideLength / 2, y: origin.y + altitude))
+        close()
+    }
+}

还可以利用扩展来增加属性(包括类型属性和静态属性)。然而,这些属性必须是计算型属性,因为扩展不能为类,结构体,枚举添加存储型属性。

下面这个例子为CGRect结构增加了一个叫area的计算型属性:

swift
extension CGRect {
+    var area: CGFloat {
+        return width * height
+    }
+}
+let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
+let area = rect.area

甚至可以利用扩展为类添加协议一致性而无需子类化。如果协议是在 Swift 中定义的,还可以为结构或是枚举添加协议一致性,即使它们是在 Objective-C 中定义的。

无法通过扩展覆盖类型中既有的方法与属性。

闭包

Objective-C 的块会作为符合其调用约定的 Swift 闭包导入,通过@convention(block)特性表示。例如,下面是一个 Objective-C 的块变量:

objective-c
void (^completionBlock)(NSData *) = ^(NSData *data) {
+    // ...
+}

它在 Swift 中如下所示:

swift
let completionBlock: (Data) -> Void = { data in
+    // ...
+}

Swift 闭包与 Objective-C 块兼容,因此可以把一个 Swift 闭包传递给一个接受块作为参数的 Objective-C 方法。而且因为 Swift 闭包与函数具有相同类型,因此甚至可以直接传递一个 Swift 函数的函数名。

闭包与块有相似的捕获语义,但有个关键的不同:被捕获的变量可以直接修改,而不是一份值拷贝。换言之,Objective-C __block变量的行为是 Swift 变量的默认行为。

在捕获 self 时避免强引用循环

在 Objective-C,如果块捕获了self,一定要慎重考虑内存管理问题。

块会保持对被捕获对象的强引用,包括self。一旦self也持有对块的强引用,例如通过一个拷贝语义的块属性,就将导致强引用循环。可以通过让块捕获self的弱引用来避免此问题:

objective-c
__weak typeof(self) weakSelf = self;
+self.block = ^{
+    __strong typeof(self) strongSelf = weakSelf;
+    [strongSelf doSomething];
+};

和 Objective-C 块类似,Swift 闭包也会保持对被捕获对象的强引用,包括self。为了避免强引用循环,可以在闭包的捕获列表中指定selfunowned

swift
self.closure = { [unowned self] in
+    self.doSomething()
+}

请参阅 The Swift Programming Language 中文版 中的 解决闭包引起的循环强引用 小节获取更多信息。

对象比较

在 Swift,比较两个对象可以使用两种方式。第一种,使用==运算符,比较两个对象内容是否相同。第二种,使用===运算符,判断常量或者变量是否引用同一对象。

Swift 为源自NSObject的类实现了Equatable协议,并提供了==运算符和===运算符的默认实现。==运算符的默认实现会调用isEqual:方法,===运算符的默认实现则会检查指针是否相同。你不应该为 Objective-C 类型重写这两个运算符。

NSObject类为isEqual:方法提供的基本实现仅仅是比较两个指针是否相同。可以根据需要在子类中重写isEqual:方法,基于对象内容进行比较,而不是比较指针。关于如何实现对象比较逻辑的更多信息,请参阅 Object comparison

注意
Swift 会自动为!=!==运算符提供实现,无需再进行重写。

哈希

如果NSDictionary的键类型不带有类限定,Swift 会将其导入为键类型为AnyHashableDictionary。与之类似,如果NSSet中的元素没有类型限定,Swift 会将其导入为元素类型为AnyHashableSet。如果NSDictionaryNSSet对其键或元素的类型做了参数化,那么 Swift 导入它们时则会使用相应的类型作为键或元素的类型。例如,考虑如下 Objective-C 声明:

objective-c
@property NSDictionary *unqualifiedDictionary;
+@property NSDictionary<NSString *, NSDate *> *qualifiedDictionary;
+
+@property NSSet *unqualifiedSet;
+@property NSSet<NSString *> *qualifiedSet;

Swift 会以如下形式导入它们:

swift
var unqualifiedDictionary: [AnyHashable: Any]
+var qualifiedDictionary: [String: Date]
+
+var unqualifiedSet: Set<AnyHashable>
+var qualifiedSet: Set<String>

Swift 在导入 Objective-C 中未指定的类型或id类型时,如果这种类型必须符合Hashable协议,就会将之导入为AnyHashable类型。AnyHashable由任意Hashable类型隐式转换而来,并可以使用as?as!操作符将其转换为更具体的类型。

Swift 类型兼容性

在 Swift 中继承 Objective-C 类时,该 Swift 子类及其成员,即属性、方法、下标和构造器,只要兼容于 Objective-C,就可在 Objective-C 中直接使用。但这不包括一些 Swift 独有特性,如下列所示:

  • 泛型
  • 元组
  • 原始值类型不是Int类型的枚举
  • 结构体
  • 顶级函数
  • 全局变量
  • 类型别名
  • 可变参数
  • 嵌套类型
  • 柯里化函数

Swift API 转换到 Objective-C 时:

  • Swift 可选类型会被标注__nullable
  • Swift 非可选类型会被标注__nonnull
  • Swift 常量存储属性和计算属性会成为 Objective-C 只读属性。
  • Swift 变量存储属性会成为 Objective-C 读写属性。
  • Swift 类型属性会成为 Objective-C 中具有class特性的属性。
  • Swift 类型方法会成为 Objective-C 类方法。
  • Swift 构造器和实例方法会成为 Objective-C 实例方法。
  • Swift 中抛出错误的方法会成为接受NSError **参数的 Objective-C 方法。如果 Swift 方法没有参数,AndReturnError:会被拼接到 Objective-C 方法名上,否则,error:会被拼接在方法名上。如果 Swift 方法没有指定返回类型,那么相应的 Objective-C 方法会拥有 BOOL 类型的返回值。如果 Swift 方法返回非可选值,那么对应的 Objective-C 方法会返回可选值。

例如,思考如下 Swift 声明:

swift
class Jukebox: NSObject {
+    var library: Set<String>
+
+    var nowPlaying: String?
+
+    var isCurrentlyPlaying: Bool {
+        return nowPlaying != nil
+    }
+
+    class var favoritesPlaylist: [String] {
+        // return an array of song names
+    }
+
+    init(songs: String...) {
+        self.library = Set<String>(songs)
+    }
+
+    func playSong(named name: String) throws {
+        // play song or throw an error if unavailable
+    }
+}

上述声明导入到 Objective-C 后如下所示:

objective-c
@interface Jukebox : NSObject
+@property (nonatomic, strong, nonnull) NSSet<NSString *> *library;
+@property (nonatomic, copy, nullable) NSString *nowPlaying;
+@property (nonatomic, readonly, getter=isCurrentlyPlaying) BOOL currentlyPlaying;
+@property (nonatomic, class, readonly, nonnull) NSArray<NSString *> * favoritesPlaylist;
+- (nonnull instancetype)initWithSongs:(NSArray<NSString *> * __nonnull)songs OBJC_DESIGNATED_INITIALIZER;
+- (BOOL)playSong:(NSString * __nonnull)name error:(NSError * __nullable * __null_unspecified)error;
+@end

注意
无法在 Objective-C 中继承一个 Swift 类。

配置 Swift 在 Objective-C 中的接口

在某些情况下,需要更精确地控制如何将 Swift API 暴露给 Objective-C。你可以使用@objc(name)特性来改变类、属性、方法、枚举类型以及枚举用例暴露给 Objective-C 代码的声明。

例如,如果 Swift 类的类名包含 Objective-C 中不支持的字符,就可以为其提供一个在 Objective-C 中的别名。如果要为 Swift 函数提供 Objective-C 别名,使用 Objective-C 选择器语法,并记得在选择器参数片段后添加冒号(:)。

swift
@objc(Color)
+enum Цвет: Int {
+
+    @objc(Red)
+    case Красный
+
+    @objc(Black)
+    case Черный
+}
+
+@objc(Squirrel)
+class Белка: NSObject {
+
+    @objc(color)
+    var цвет: Цвет = .Красный
+
+    @objc(initWithName:)
+    init (имя: String) {
+        // ...
+    }
+
+    @objc(hideNuts:inTree:)
+    func прячьОрехи(количество: Int, вДереве дерево: Дерево) {
+        // ...
+    }
+}

对 Swift 类使用@objc(name)特性时,该类将在 Objective-C 中可用并且没有任何命名空间。因此,这个特性在迁徙被归档的 Objecive-C 类到 Swift 时会非常有用。由于归档文件中存储了被归档对象的类名,因此应该使用@objc(name)特性来指定被归档的 Objective-C 对象的类名,这样归档文件才能通过新的 Swift 类解档。

注意
相反,Swift 还提供了@nonobjc特性,可以让一个 Swift 声明在 Objective-C 中不可用。可以利用它来解决桥接方法循环,以及重载由 Objective-C 中导入的类中的方法。另外,如果一个 Objective-C 方法在 Swift 中被重写后,无法再以 Objective-C 的语言特性呈现,例如将参数变为了 Swift 中的可变参数,那么这个方法必须标记为@nonobjc

需要动态分派

可在 Objective-C 中调用的 Swift API 必须通过动态分派提供。不过,在 Swift 中调用这些 API 时,动态分派的可用性并不妨碍 Swift 编译器选择更高效的分派方法。

你可以使用 @objc 特性和 dynamic 修饰符来要求通过 Objective-C 运行时动态分派对成员的访问操作。一般很少需要这种动态分派,但是,在使用类似键值监听(KVO)这类 API,以及使用 Objective-C 运行时库中的 method_exchangeImplementations 这类需要在运行时动态替换方法实现的函数时,则必须使用动态分派。

使用 dynamic 修饰符标记的声明还必须显式标记 @objc 特性,除非声明所在的上下文为其隐式添加了 @objc 特性。关于 @objc 特性何时会被隐式添加的相关信息,请参阅 The Swift Programming Language 中文版 中的声明特性部分。

选择器

Objective-C 选择器是一种用于引用 Objective-C 方法名的类型。在 Swift,Objective-C 选择器用Selector结构体表示。可以使用#selector表达式创建一个选择器,将方法名传入即可,例如#selector(MyViewController.tappedButton(sender:))。创建 Objective-C 存取方法的选择器时,为了区分,将属性名加上getter:setter:标签,例如#selector(getter: MyViewController.myButton)

swift
import UIKit
+class MyViewController: UIViewController {
+    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
+
+    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
+        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
+        let action = #selector(MyViewController.tappedButton)
+        myButton.addTarget(self, action: action, for: .touchUpInside)
+    }
+
+    func tappedButton(sender: UIButton?) {
+        print("tapped button")
+    }
+
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+    }
+}

注意
Objective-C 方法引用还可以加上圆括号,并使用as运算符来消除重载方法之间的歧义,例如#selector(((UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -> Void))

Objective-C 方法的不安全调用

可以使用perform(_:)方法以及它的变体在兼容 Objective-C 的对象上调用方法。使用选择器调用方法并非内在安全的,因为编译器无法保证结果,甚至无法保证对象能否响应选择器。因此,坚决不提倡使用这些 API,除非代码确实依赖于 Objective-C 运行时提供的动态方法决议。例如,实现一个类似NSResponder这种在接口中使用了目标-行为设计模式的类。绝大多数情况下,将对象转换为AnyObject类型,再使用可选链语法调用方法会更为安全和方便,请参阅 id 兼容性 小节获取更多信息。

swift
let string: NSString = "Hello, Cocoa!"
+let selector = #selector(NSString.lowercased(with:))
+let locale = Locale.current
+if let result = string.perform(selector, with: locale) {
+    print(result.takeUnretainedValue())
+}
+// 打印输出 "hello, cocoa!"

向一个对象发送无法识别的选择器将造成接收者调用doesNotRecognizeSelector(_:)方法,其默认实现是抛出NSInvalidArgumentException异常。

swift
let array: NSArray = ["delta", "alpha", "zulu"]
+// 下面这句代码不会导致编译错误,因为该选择器存在于 NSDictionary 中
+let selector = #selector(NSDictionary.allKeysForObject)
+// 下面这句代码将抛出异常,因为 NSArray 无法响应该选择器
+array.performSelector(selector)

键和键路径

在 Objective-C,键是一个表示某个对象特定属性的字符串。键路径是一个由多个键构成的字符串,键之间用点分隔,表示一条能访问到某个对象特定属性的路径。键和键路径经常用于键值编码(KVC),这是一种通过字符串来访问某个对象的属性的机制。键和键路径也常用于键值监听(KVO),这是一种能让某个对象在另一个对象的特定属性改变时获得通知的机制。

在 Swift,可以用 key-path 表达式创建键路径来访问属性。例如,可以用 \\Animal.name 这样的 key-path 表达式来访问 Animal 类中的 name 属性。键路径通过 key-path 表达式创建,其中包含了属性所在类型的类型信息。对一个实例使用键路径所得到的结果就如同直接访问该实例的对应属性一样。key-path 表达式接受属性引用以及链式属性引用,例如 \\Animal.name.count

swift
let llama = Animal(name: "Llama")
+let nameAccessor = \\Animal.name
+let nameCountAccessor = \\Animal.name.count
+
+llama[keyPath: nameAccessor]
+// "Llama"
+llama[keyPath: nameCountAccessor]
+// "5"

在 Swift,还可以用 #keyPath 字符串表达式生成可被编译器检查的键和键路径,并可将之用于 KVC 方法 value(forKey:) 和  value(forKeyPath:),以及 KVO 方法 addObserver(_:forKeyPath:options:context:)#keyPath 字符串表达式接受链式的方法或属性引用。它还支持可选值链式引用,例如 #keyPath(Person.bestFriend.name)。与使用 key-path 表达式这种创建方式不同的是,#keyPath 字符串表达式不会将属性或方法所属类型的类型信息传递给接受键路径的 API。

注意
#keyPath 表达式语法类似 #selector 表达式语法,请参阅 选择器

swift
class Person: NSObject {
+    @objc var name: String
+    @objc var friends: [Person] = []
+    @objc var bestFriend: Person? = nil
+
+    init(name: String) {
+        self.name = name
+    }
+}
+
+let gabrielle = Person(name: "Gabrielle")
+let jim = Person(name: "Jim")
+let yuanyuan = Person(name: "Yuanyuan")
+gabrielle.friends = [jim, yuanyuan]
+gabrielle.bestFriend = yuanyuan
+
+#keyPath(Person.name)
+// "name"
+gabrielle.value(forKey: #keyPath(Person.name))
+// "Gabrielle"
+#keyPath(Person.bestFriend.name)
+// "bestFriend.name"
+gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))
+// "Yuanyuan"
+#keyPath(Person.friends.name)
+// "friends.name"
+gabrielle.value(forKeyPath: #keyPath(Person.friends.name))
+// ["Yuanyuan", "Jim"]
`,198)]))}const c=i(h,[["render",l]]);export{g as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.lean.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.lean.js new file mode 100644 index 0000000..9fe57b8 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_01-Interacting with Objective-C APIs.md.CgyRJN7j.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"与 Objective-C API 交互","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md","filePath":"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md"}'),h={name:"frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md"};function l(e,s,k,p,d,E){return n(),a("div",null,s[0]||(s[0]=[t("",198)]))}const c=i(h,[["render",l]]);export{g as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.js new file mode 100644 index 0000000..f257642 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.js @@ -0,0 +1,49 @@ +import{_ as s,c as a,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const n="/assets/Attributes%20Inspector@2x.B2mpndFp.png",l="/assets/Identity%20Inspector@2x.CkbcHy2u.png",p="/assets/coredataeditor_2x.C-_TZgB_.png",h="/assets/coredatanamespace_2x.DT2Ua0ZZ.png",b=JSON.parse('{"title":"使用 Objective-C 特性编写 Swift 类和协议","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md","filePath":"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md"}'),r={name:"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md"};function k(o,i,d,c,g,E){return e(),a("div",null,i[0]||(i[0]=[t(`

使用 Objective-C 特性编写 Swift 类和协议

互用性让你在编写 Swift 代码时可以融合 Objective-C 语言特性。在编写 Swift 代码时,不仅可以继承 Objective-C 类,声明和采用 Objective-C 协议,还可以使用 Objective-C 的一些其它功能。这意味着不但可以基于 Objective-C 中耳熟能详的既有特性来编写 Swift 代码,还可以利用 Swift 更为强大的现代化语言特性来改善代码。

继承 Objective-C 类

在 Swift,可以定义一个继承自 Objective-C 类的 Swift 子类。在 Swift 的类名后面加上一个冒号(:),冒号后面跟上 Objective-C 类的类名即可。

swift
import UIKit
+class MySwiftViewController: UIViewController {
+    // 定义类
+}

Swift 子类可以从 Objective-C 父类中继承所有的功能。

如果要覆盖父类中的实现,可以使用 override 修饰符。编译器会根据 Swift 方法名来自动推断被重写的父类方法。也可以使用 @objc(name) 特性来明确指定相对应的 Objective-C 符号。

当 Swift 类引入了许多需要 Objective-C 运行时行为的新方法或属性时,请在该类的声明中使用 @objcMembers 特性。对类使用 @objcMembers 特性会隐式地将 @objc 特性添加到类中所有兼容 Objective-C 的成员。由于使用 @objc 特性会增加应用程序编译后的体积并对性能产生不利影响,因此只有在每个成员都需要使用 @objc 特性时才应在类声明中使用 @objcMembers 特性。

NSCoding 协议

NSCoding协议要求采用协议的类型实现其所要求的构造器init(coder:)以及其所要求的方法encode(with:)。直接采用NSCoding协议的类必须实现这个方法。对于采用NSCoding协议的类的子类,如果有一个或者多个自定义的构造器或者有不具有默认初始值的属性,那么也必须实现这个方法。Xcode 提供了下面这个fix-it来提供一个占位实现:

swift
required init(coder aDecoder: NSCoder) {
+    fatalError("init(coder:) has not been implemented")
+}

对于那些从 Storyboards 里加载的对象,或者用NSUserDefaultsNSKeyedArchiver归档到硬盘的对象,则必须提供该构造器的完整实现。当然,如果一个类型不会以此种方式实例化时,就不需要提供该构造器的完整实现。

采用协议

Objective-C 协议会被导入为 Swift 协议。所有协议都写在一个用逗号分隔的列表中,跟在父类类名后面(如果该类有父类的话)。

swift
class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
+    // 定义类
+}

声明符合单个协议的类型时,直接使用协议名作为其类型,类似于 Objective-C 中id<SomeProtocol>这种形式。声明符合多个协议的类型时,使用SomeProtocol & AnotherProtocol这种协议组合的形式,类似于 Objective-C 中id<SomeProtocol, AnotherProtocol>这种形式。

swift
var textFieldDelegate: UITextFieldDelegate
+var tableViewController: UITableViewDataSource & UITableViewDelegate

注意
在 Swift,类和协议的命名空间是统一的,因此 Objective-C 的NSObject协议会被重映射为 Swift 的NSObjectProtocol协议。

编写构造器和析构器

Swift 编译器能确保构造器不会遗留任何未初始化的属性,从而增加代码的安全性和可预测性。另外,与 Objective-C 不同,Swift 不提供单独的内存分配方法。你会始终使用原生的 Swift 构造器,即使是使用 Objective-C 类,Swift 会将 Objective-C 构造方法转换为 Swift 构造器。请参阅 The Swift Programming Language 中文版 中的 构造器 章节了解关于如何实现构造器的更多信息。

如果希望在对象释放前进行额外的清理工作,可以实现一个析构器来代替dealloc方法。在对象被释放前,Swift 会自动调用析构器。当 Swift 调用完子类的析构器后,会自动调用父类的析构器。使用 Objective-C 类或者继承自 Objective-C 类的 Swift 类时,Swift 也会自动调用该类父类中的dealloc方法。请参阅 The Swift Programming Language 中文版 中的 析构器 章节了解关于如何实现析构器的更多信息。

兼容使用 Swift 类名的 Objective-C API

Swift 类的命名空间基于其所在的模块,即使是使用来自 Objective-C 的代码。在 Objective-C 中所有的类都是全局命名空间的一部分,名字不能重复。而 Swift 类可以基于其所在模块来消除歧义。例如,MyFramework框架中的DataManager类在 Swift 中的全限定名是MyFramework.DataManager。一个 Swift 应用的target就是一个模块,因此,在一个叫MyGreatApp的应用里,一个叫做Observer的 Swift 类的全限定名是MyGreatApp.Observer

Swift 类在 Objective-C 代码中使用时,为了保持命名空间,Swift 类会将其全限定名暴露给 Objective-C 运行时。因此,使用那些用到 Swift 类名字符串的 API 时,必须使用类的全限定名。例如,你创建了一个基于文档的 Mac 应用,需要在应用的Info.plist里提供NSDocument子类的类名。在 Swift 中,必须使用NSDocument子类的全限定名,即应用名或者框架名加上子类名。

下面的例子中,NSClassFromString(_:)函数用于从一个字符串表示的类名获取该类的引用。为了获取 Swift 类,需要使用全限定名,也就是需要加上应用的名字。

swift
let myPersonClass: AnyClass= NSClassFromString("MyGreatApp.Person")

与 Interface Builder 结合

Swift 编译器包含一些特性,能让 Swift 类使用 Interface Builder 的一些特色功能。和 Objective-C 一样,在 Swift 也可使用 outlet,action 以及实时渲染。

使用 Outlet 和 Action

使用 Outlets 和 Actions 可以连接源代码和 Interface Builder 中的 UI 对象,只需在属性或方法声明前标记@IBOutlet@IBAction特性。声明一个 outlet 集合同样是用@IBOutlet特性,只不过会为该类型指定一个数组。

在 Swift 中声明一个 outlet 时,应该将类型声明为隐式解包可选类型。通过这种方式,Swift 编译器会自动为它分配空值nil,就不需要在构造器中为其分配初始值了。在运行时,构造过程完成后,Interface Builder 会连接各个 outlet。如果从故事版或者xib文件实例化对象,则可以假定这些 outlet 已经连接完毕。

例如,下面的 Swift 代码声明了一个拥有 outlet,outlet 集合和 action 的类:

swift
class MyViewController: UIViewController {
+    @IBOutlet weak var button: UIButton!
+    @IBOutlet var textFields: [UITextField]!
+    @IBAction func buttonTapped(sender: AnyObject) {
+        print("button tapped!")
+    }
+}

实时渲染

可以使用@IBDesignable@IBInspectable特性开启实时渲染,在 Interface Builder 中对自定义视图进行交互式设计。继承UIView或者NSView来自定义一个视图时,可以在类声明前标记@IBDesignable特性。在 Interface Builder 里添加自定义的视图后(在 Identity Inspector 面板的 Class 输入框中进行设置),Interface Builder 将在画布上实时渲染自定义视图。

还可以将@IBInspectable特性添加到类型兼容用户定义运行时属性(可以在 Identity Inspector 面板的 User Defined Runtime Attributes 中查看)的属性前。将自定义的视图添加到 Interface Builder 后,就可以在 Attributes Inspector 面板中编辑这些属性。

swift
@IBDesignable
+class MyCustomView: UIView {
+    @IBInspectable var textColor: UIColor
+    @IBInspectable var iconHeight: CGFloat
+    // ...
+}

指定属性特性

在 Objective-C,属性通常会有一系列用于指定该属性的一些附加信息的属性特性。在 Swift,将通过不同的方式指明这些属性特性。

强引用和弱引用

在 Swift,属性默认都是强引用,可以使用weak关键字指明某个属性持有其所指向对象的弱引用。该关键字仅能修饰可选的类类型。请参阅 The Swift Programming Language 中文版 中的 类和结构 章节了解更多信息。

读写和只读

在 Swift,没有readwritereadonly特性。声明一个存储型属性时,使用let使其只读;使用var使其可读写。声明一个计算型属性时,只为其提供一个读取方法使其只读;同时提供读取方法和写入方法使其可读写。请参阅 The Swift Programming Language 中文版 中的 属性 章节了解更多信息。

拷贝语义

在 Swift,Objective-C 的copy属性特性被转化为@NSCopying。这种类型的属性必须符合NSCopying协议。请参阅 The Swift Programming Language 中文版 中的 类和结构 章节了解更多信息。

实现 Core Data 的 NSManagedObject 子类

Core Data 提供了底层存储以及NSManagedObject子类的属性实现,还提供了在对多关系中添加和移除对象的实例方法实现。可以使用@NSManaged特性告知 Swift 编译器,一个声明的底层存储和实现部分将在运行时由 Core Data 提供。

NSManagedObject子类中,为每一个和 Core Data 实体模型文件中相对应的属性或者方法声明标记@NSManaged特性。例如,思考下面这个叫做Person的 Core Data 实体,它有个叫做nameString类型的属性,以及一个叫做friends的对多关系。

相对应的NSManagedObject子类Person中的代码如下:

swift
import CoreData
+class Person: NSManagedObject {
+    @NSManaged var name: String
+    @NSManaged var friends: NSSet
+        
+    @NSManaged func addFriendsObject(friend: Person)
+    @NSManaged func removeFriendsObject(friend: Person)
+    @NSManaged func addFriends(friends: NSSet)
+    @NSManaged func removeFriends(friends: NSSet)
+}

namefriends属性都标记了@NSManaged特性,以此表明 Core Data 会在运行时提供其实现和存储。由于friends是个对多关系,因此 Core Data 还提供了一些相关的存取方法。

为了在 Swift 中配置一个NSManagedObject的子类供 Core Data 模型实体使用,在 Xcode 中打开 Data Model Inspector,在 Class 输入框中输入类名,并在 Module 输入框的下拉列表中选择Current Product Module

声明协议

在 Swift 中可以定义能让 Objective-C 类采用的协议,在协议声明前添加@objc特性即可。

swift
import UIKit
+@objc protocol MyCustomProtocol {
+    var people: [Person] { get }
+
+    func tableView(_ tableView: UITableView, configure cell: UITableViewCell, forPerson person: Person)
+
+    @objc optional func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forPerson person: Person)
+}

为了符合协议,Objective-C 类必须实现协议中声明的所有构造器,属性,下标,以及方法。可选协议要求必须标记@objc特性以及optional修饰符。

Objective-C 类可以像采用 Objective-C 协议一样采用 Swift 协议,实现所有协议要求即可。

objective-c
@interface MyCustomController: UIViewController <MyCustomProtocol>
+@property (nonatomic, strong) NSArray<Person *> *people;
+@end
+
+@implementation MyCustomController
+@synthesize people;
+
+- (void)tableView:(UITableView *)tableView
+		 configure:(UITableViewCell *)cell
+		 forPerson:(Person *)person
+{
+    // ...
+}
+@end
`,77)]))}const f=s(r,[["render",k]]);export{b as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.lean.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.lean.js new file mode 100644 index 0000000..0aded05 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_02-Writing Swift Classes and Protocols with Objective-C Behavior.md.DiA-b_2v.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as e,ag as t}from"./chunks/framework.BHpayLOB.js";const n="/assets/Attributes%20Inspector@2x.B2mpndFp.png",l="/assets/Identity%20Inspector@2x.CkbcHy2u.png",p="/assets/coredataeditor_2x.C-_TZgB_.png",h="/assets/coredatanamespace_2x.DT2Ua0ZZ.png",b=JSON.parse('{"title":"使用 Objective-C 特性编写 Swift 类和协议","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md","filePath":"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md"}'),r={name:"frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md"};function k(o,i,d,c,g,E){return e(),a("div",null,i[0]||(i[0]=[t("",77)]))}const f=s(r,[["render",k]]);export{b as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.js new file mode 100644 index 0000000..a8549bf --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.js @@ -0,0 +1,43 @@ +import{_ as s,c as a,o as t,ag as e}from"./chunks/framework.BHpayLOB.js";const c=JSON.parse('{"title":"使用 Cocoa 框架","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md","filePath":"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md"}'),n={name:"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md"};function l(h,i,p,k,d,r){return t(),a("div",null,i[0]||(i[0]=[e(`

使用 Cocoa 框架

为了便于与 Objective-C 进行交互,Swift 提供了高效便捷的方式来使用 Cocoa 框架。

Swift 会自动将一些 Objective-C 类型转换为 Swift 类型,也会将一些 Swift 类型转换为 Objective-C 类型。可以在 Objective-C 和 Swift 间相互转换的数据类型被称为桥接类型。例如,在 Swift,可以将一个String类型的值传递给一个接收NSString对象的 Objective-C 方法。除此之外,很多 Cocoa 框架,包括 Foundation,AppKit,以及 UIKit,都改善了它们的 API,从而在 Swift 中使用起来更加自然。例如,NSCoder的方法decodeObjectOfClass(_:forKey:)使用 Swift 泛型来提供强类型的方法签名。

Foundation

Foundation 框架为应用和框架提供了基层功能,包括数据存储,文本处理,日期时间,排序过滤,持久化和网络等。

被桥接的类型

Swift 中的 Foundation 提供了如下桥接值类型用于替代如下 Objective-C 引用类型:

Objective-C 引用类型Swift 值类型
NSAffineTransformAffineTransform
NSArrayArray
NSCalendarCalendar
NSCharacterSetCharacterSet
NSDataData
NSDateComponentsDateComponents
NSDateIntervalDateInterval
NSDateDate
NSDecimalNumberDecimal
NSDictionaryDictionary
NSIndexPathIndexPath
NSIndexSetIndexSet
NSLocaleLocale
NSMeasurementMeasurement
NSNotificationNotification
NSNumberBool, Double, Float, Int, UInt
NSPersonNameComponentsPersonNameComponents
NSSetSet
NSStringString
NSTimeZoneTimeZone
NSURLComponentsURLComponents
NSURLQueryItemURLQueryItem
NSURLURL
NSURLComponentsURLComponents
NSURLQueryItemURLQueryItem
NSURLRequestURLRequest
NSUUIDUUID

这些值类型的功能与其对应的引用类型相同。包含不可变和可变子类的类簇被统一桥接为单个值类型。Swift 代码使用varlet来控制可变性,因此它们不再需要两个类了。原先的引用类型依然可以通过加上NS前缀来访问。

可以使用 Objective-C 桥接引用类型的地方就可以使用 Swift 桥接值类型,从而可以在 Swift 代码中以更加自然的方式使用这些原有的功能。基于这个原因,你应该尽量避免在 Swift 代码中使用 Objective-C 桥接引用类型。事实上,Swift 代码导入 Objective-C API 时,导入器会将引用类型替换为相对应的值类型。与之类似,Objective-C 代码导入 Swift API 时,导入器也会将值类型替换为相对应的引用类型。

如果你需要使用原本的 Foundation 对象,你可以使用as操作符在这些桥接类型间进行转换。

被重命名的类型

Swift 中的 Foundation 重名了一些类,协议,枚举以及常量。

在导入 Foundation 类时,Swift 丢弃了类名的NS前缀,但有如下例外情况:

  • Objective-C 和 Objective-C 运行时中的一些特定类,例如NSObjectNSAutoreleasePoolNSExceptionNSProxy
  • 平台特定类,例如NSBackgroundActivityNSUserNotificationNSXPCConnection
  • 拥有对应的桥接值类型的一些类,例如NSStringNSDictionaryNSURL
  • 目前尚无对应的桥接值类型,但是未来会有的一些类,例如NSAttributedStringNSRegularExpressionNSPredicate

Foundation 中的类经常会声明一些枚举和常量类型。导入这些类型时,Swift 会将它们移到相关类型的内部作为嵌套类型。例如,NSJSONReadingOptions的选项集会被导入为JSONSerialization.ReadingOptions

字符串

字符串可以在String类型和NSString类型之间桥接。你可以使用as运算符将String值转换为NSString对象。你也可以通过提供类型标注的方式利用字符串字面量创建NSString对象。

swift
import Foundation
+let string: String = "abc"
+let bridgedString: NSString = string as NSString
+
+let stringLiteral: NSString = "123"
+if let integerValue = Int(stringLiteral as String) {
+    print("\\(stringLiteral) is the integer \\(integerValue)")
+}
+// 打印 "123 is the integer 123"

注意
Swift 的String类型由独立编码的 Unicode 字符组成,并提供了在各种 Unicode 表现形式下访问这些字符的支持。NSString类以 UTF-16 码元序列的形式编码兼容 Unicode 的文本字符串。表示字符串长度,字符索引,区间的这些依据 16 位平台字节序值的NSString方法,均有相对应的 Swift 方法,这些方法使用String.IndexRange<String.Index>值而不是IntNSRange值。

数值

Swift 会在 NSNumber 类和 Swift 算术类型之间桥接,包括 IntDoubleBool

你可以使用 as 运算符转换 Swift 数值来创建 NSNumber 对象。由于 NSNumber 可以包含多种不同类型,将其转换为 Swift 数值时必须使用 as? 运算符。例如,将表示数字500的 NSNumber 值转换为 Swift 类型 Int8 将会失败并返回 nil,因为 Int8 值可表示的最大值是127。

你还可以通过显式提供类型标注,使用浮点数、整数或布尔字面量创建 NSNumber 对象。

swift
import Foundation
+let number = 42
+let bridgedNumber: NSNumber = number as NSNumber
+
+let integerLiteral: NSNumber = 5
+let floatLiteral: NSNumber = 3.14159
+let booleanLiteral: NSNumber = true

注意
Objective-C 中具有平台适应性的整数类型,例如 NSUIntegerNSInteger,会被桥接为 Int

数组

Swift 会在Array类型和NSArray类之间桥接。使用轻量泛型的NSArray对象被桥接时,其元素类型也会被桥接过去。如果NSArray对象没有使用轻量泛型,那么它会被桥接为[Any]类型的 Swift 数组。

例如,思考以下 Objective-C 声明:

objective-c
@property NSArray *objects;
+@property NSArray<NSDate *> *dates;
+- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
+- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;

Swift 以如下所示导入它们:

swift
var objects: [Any]
+var dates: [Date]
+func datesBeforeDate(date: Date) -> [Date]
+func addDatesParsedFromTimestamps(timestamps: [String])

还可以直接利用 Swift 数组字面量创建NSArray对象,这同样遵循上面提到的桥接规则。将常量或变量声明为NSArray类型并为其赋值数组字面量时,Swift 将会创建NSArray对象,而不是 Swift 数组。

swift
let schoolSupplies: NSArray = ["Pencil", "Eraser", "Notebkko"]
+// schoolSupplies 是一个包含三个元素的 NSArray 对象

集合

Swift 也会在Set类型和NSSet类之间桥接。使用轻量泛型的NSSet对象会被桥接为Set<ObjectType>类型的 Swift 集合。如果NSSet对象没有使用轻量泛型,那么它会被桥接为Set<AnyHashable>类型的 Swift 集合。

例如,思考以下 Objective-C 声明:

objective-c
@property NSSet *objects;
+@property NSSet<NSString *> *words;
+- (NSSet<NSString *> *)wordsMatchingPredicate:(NSPredicate *)predicate;
+- (void)removeWords:(NSSet<NSString *> *)words;

Swift 以如下所示导入它们:

swift
var objects: Set<AnyHashable>
+var words: Set<String>
+func wordsMatchingPredicate(predicate: NSPredicate) -> Set<String>
+func removeWords(words: Set<String>)

还可以直接利用 Swift 数组字面量创建NSSet对象,这同样遵循上面提到的桥接规则。将常量或者变量声明为NSSet类型,并为其赋值数组字面量时,Swift 将会创建NSSet对象,而不是 Swift 集合。

swift
let amenities: NSSet = ["Sauna", "Steam Room", "Jacuzzi"]
+// amenities 是一个包含三个元素的 NSSet 对象

字典

Swift 同样会在Dictionary类型和NSDictionary类之间桥接。使用轻量泛型的NSDictionary对象会被桥接为[Key: Value]类型的 Swift 字典。如果NSDictionary对象没有使用轻量泛型,那么它会被桥接为[AnyHashable: Any]类型的 Swift 字典。

例如,思考以下 Objective-C 声明:

objective-c
@property NSDictionary *keyedObjects;
+@property NSDictionary<NSURL *, NSData *> *cachedData;
+- (NSDictionary<NSURL *, NSNumber *> *)fileSizesForURLsWithSuffix:(NSString *)suffix;
+- (void)setCacheExpirations:(NSDictionary<NSURL *, NSDate *> *)expirations;

Swift 以如下所示导入它们:

swift
var keyedObjects: [AnyHashable: Any]
+var cachedData: [URL: Data]
+func fileSizesForURLsWithSuffix(suffix: String) -> [URL: NSNumber]
+func setCacheExpirations(expirations: [URL: NSDate])

还可以直接利用 Swift 字典字面量创建NSDictionary对象,这同样遵循上面提到的桥接规则。将常量或者变量声明为NSDictionary类型,并为其赋值字典字面量时,Swift 将会创建NSDictionary对象,而不是 Swift 字典。

swift
let medalRankings: NSDictionary = ["Gold": "1st Place", "Silver": "2nd Place", "Bronze": "3rd Place"]
+// medalRankings 是一个包含三个键值对的 NSDictionary 对象

Core Foundation

Core Foundation 类型会被导入为 Swift 类。无论是否提供了内存管理标注,Swift 都会自动管理 Core Foundation 对象的内存,包括你自己实例化的 Core Foundation 对象。在 Swift,可以将每一对可以桥接的 Fundation 和 Core Foundation 类型互换使用。如果先将 Core Foundation 类型桥接为 Foundation 类型,就可以进一步桥接为 Swift 标准库类型。

重映射类型

Swift 导入 Core Foundation 类型时,会将这些类型的名字重映射,从类型名字的末端移除 Ref,所有的 Swift 类都是引用类型,因此该后缀是多余的。

Core Foundation 的CFTypeRef类型会重映射为Anyobject类型。以前使用CFTypeRef的地方,现在该换成AnyObject了。

内存受管理的对象

对于从带内存管理标注的 API 返回的 Core Foundation 对象,Swift 会自动对其进行内存管理,你不需要再调用CFRetainCFRelease,或者CFAutorelease函数。

如果自定义的 C 函数或 Objective-C 方法返回 Core Foundation 对象,需要用CF_RETURNS_RETAINED或者CF_RETURNS_NOT_RETAINED宏标注这些函数或方法,从而帮助编译器自动插入内存管理函数调用。还可以使用CF_IMPLICIT_BRIDGING_ENABLEDCF_IMPLICIT_BRIDGING_DISABLED宏围住那些遵循 Core Foundation 内存管理命名规定的 C 函数声明,从而能够根据命名推导出内存管理策略。

如果只调用那些带有内存管理标注并且不会间接返回 Core Foundation 对象的 API,那么可以略过本节的剩余部分了。否则,需要进一步学习有关 Core Foundation 非托管对象的知识。

非托管对象

对于那些没有内存管理标注的 API,编译器无法自动对返回的 Core Foundation 对象进行内存管理。Swift 将这些返回的 Core Foundation 对象包装在一个Unmanaged<Instance>结构中。所有被间接返回的 Core Foundation 对象也都是非托管对象。例如,这有个不带内存管理标注的 C 函数:

objective-c
CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)

Swift 以如下所示导入它们:

swift
func StringByAddingTwoStrings(_: CFString!, _: CFString!) -> Unmanaged<CFString>! {
+    // ...
+}

从没有内存管理标注的 API 接收到非托管对象后,在使用它之前,必须将它转换为能够接受内存管理的对象。通过这种方式,Swift 就可以为你对其进行内存管理。Unmanaged<Instance>结构提供了两个方法,用于将一个非托管对象转换为一个可接受内存管理的对象,即takeUnretainedValue()方法和takeRetainedValue()方法。这两个方法均会返回解包后的原始对象,可以根据 API 返回的是非保留对象还是被保留对象来选择对应的方法。

例如,假设上面的 C 函数不会保留CFString对象。在使用这个对象前,应该使用takeUnretainedValue()函数。

swift
let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
+// memoryManagedResult 是一个接受内存管理的 CFString

当然,也可以对一个非托管对象使用retain()release()autorelease()方法,但是这种做法并不推荐。

想要了解更多信息,请参阅 Memory Management Programming Guide for Core Foundation 中的 Core Foundation Object Lifecycle Management 小节。

统一日志

统一日志系统提供了一个 API 来捕获系统各个层级传递的消息,它是 Foundation 框架中NSLog函数的替代者。统一日志只在 iOS 10.0macOS 10.12tvOS 10.0watchOS 3.0,以及更高的系统平台上可用。

在 Swift,你可以通过顶级函数os_log(_:dso:log:type:_:)来使用统一日志系统,该函数声明在os模块的子模块log中。

swift
import os.log
+
+os_log("This is a log message.")

你可以通过使用NSStringprintf格式化字符串连同单个或多个尾参数来格式化日志信息。

swift
let fileSize = 1234567890
+os_log("Finished downloading file. Size: %{iec-bytes}d", fileSize)

你还可以指定一个日志系统中定义的日志级别,例如InfoDebugError,从而根据日志事件的重要性来控制日志信息如何被处理。例如,某条信息可能很有帮助,但是该信息并不是排查错误所必需的,那么这条信息就应该记录在信息级别。

swift
os_log("This is additional info that may be helpful for troubleshooting.", type: .info)

为了将某条信息记录到指定子系统,你可以创建一个新的OSLog对象,指定子系统和类别,并将其作为参数传入os_log函数。

swift
et customLog = OSLog("com.your_company.your_subsystem_name.plist", "your_category_name")
+os_log("This is info that may be helpful during development or debugging.", log: customLog, type: .debug)

想要了解更多关于统一日志的信息,请参阅 Logging

Cocoa 结构体

在 Swift,Coach 和 Foundation 中的一些内建结构体可以和NSValue桥接:

  • CATransform3D
  • CLLocationCoordinate2D
  • CGAffineTransform
  • CGPoint
  • CGRect
  • CGSize
  • CGVector
  • CMTimeMapping
  • CMTimeRange
  • CMTime
  • MKCoordinateSpan
  • NSRange
  • SCNMatrix4
  • SCNVector3
  • SCNVector4
  • UIEdgeInsets
  • UIOffset
`,98)]))}const g=s(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.lean.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.lean.js new file mode 100644 index 0000000..cccf466 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_03-Working with Cocoa Frameworks.md.BVm4Kcn8.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as t,ag as e}from"./chunks/framework.BHpayLOB.js";const c=JSON.parse('{"title":"使用 Cocoa 框架","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md","filePath":"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md"}'),n={name:"frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md"};function l(h,i,p,k,d,r){return t(),a("div",null,i[0]||(i[0]=[e("",98)]))}const g=s(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.js new file mode 100644 index 0000000..3821d62 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.js @@ -0,0 +1,221 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const o=JSON.parse('{"title":"采用 Cocoa 设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md","filePath":"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md"}'),h={name:"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md"};function l(e,s,p,k,r,E){return n(),a("div",null,s[0]||(s[0]=[t(`

采用 Cocoa 设计模式

使用 Cocoa 既有的设计模式,能帮助开发者开发出设计巧妙、扩展性强的应用程序。这些模式很多都依赖于在 Objective-C 中定义的类。由于 Swift 与 Objective-C 的互用性,你依然可以在 Swift 中使用这些设计模式。在许多情况下,你甚至可以使用 Swift 的语言特性扩展或简化这些 Cocoa 设计模式,使这些设计模式更加强大易用。

代理

在 Swift 和 Objective-C,代理通常表现为一个定义交互方法的协议和符合协议的代理属性。就像在 Objective-C,在向代理发送可能无法响应的消息之前,应询问代理能否响应消息。在 Swift,可以使用可选链语法在一个可能为nil的对象上调用可选的代理方法,并使用if-let语法解包可能存在的返回值。下面的代码阐明了这个过程:

  1. 检查myDelegate不为nil
  2. 检查myDelegate是否实现了window:willUseFullScreenContentSize:方法。
  3. 如果步骤1和步骤2的检查顺利通过,那么调用该方法,将返回值赋值给名为fullScreenSize的常量。
  4. 在控制台打印方法的返回值。
swift
class MyDelegate: NSObject, NSWindowDelegate {
+    func window(_ window: NSWindow, willUseFullScreenContentSize proposedSize: NSSize) -> NSSize {
+        return proposedSize
+    }
+}
+myWindow.delegate = MyDelegate()
+if let fullScreenSize = myWindow.delegate?.window(myWindow, willUseFullScreenContentSize: mySize) {
+    print(NSStringFromSize(fullScreenSize))
+}

惰性初始化

惰性属性的值只会在被初次访问时才被初始化。如果属性的初始化过程十分复杂或者代价昂贵,或者属性的初始值无法在实例的构造过程完成前确定时,那么就可以使用惰性属性。

在 Objective-C,一个属性可能会覆写其自动合成的读取方法,只在实例变量为nil时才初始化实例变量:

objective-c
@property NSXMLDocument *XML;
+
+- (NSXMLDocument *)XML {
+    if (_XML == nil) {
+        _XML = [[NSXMLDocument alloc] initWithContentsOfURL:[[Bundle mainBundle] URLForResource:@"/path/to/resource" withExtension:@"xml"] options:0 error:nil];
+    }
+
+    return _XML;
+}

在 Swift,可以使用lazy修饰符声明一个存储属性,这将使计算初始值的表达式只在属性被初次访问时才进行求值:

swift
lazy var XML: XMLDocument = try! XMLDocument(contentsOf: Bundle.main.url(forResource: "document", withExtension: "xml")!, options: 0)

由于惰性属性只在被初次访问时才进行初始化,此时实例本身已被完全初始化,因此在初始化表达式中可以使用self

swift
var pattern: String
+lazy var regex: NSRegularExpression = try! NSRegularExpression(pattern: self.pattern, options: [])

如果还需在初始化的基础上进行额外的设置,可以通过返回属性初始值的自求值闭包给属性赋值:

swift
lazy var currencyFormatter: NumberFormatter = {
+    let formatter = NumberFormatter()
+    formatter.numberStyle = .currency
+    formatter.currencySymbol = "¤"
+    return formatter
+}()

注意
如果一个惰性属性还未被初始化就被多个线程同时访问,那么此时无法保证此惰性属性只被初始化一次。

请参阅 The Swift Programming Language 中文版 中的 延迟存储属性 小节。

错误处理

在 Cocoa 中,会产生错误的方法将 NSError 指针参数作为最后一个参数,当产生错误时,该参数会被 NSError 对象填充。Swift 会自动将 Objective-C 中会产生错误的方法转换为根据 Swift 原生错误处理机制抛出错误的方法。

注意
某些接受错误的方法,例如委托方法,或者接受一个带有 NSError 参数的块作为参数的方法,不会被 Swift 导入为抛出方法。

例如,请考虑如下来自于 NSFileManager 的 Objective-C 方法:

objective-c
- (BOOL)removeItemAtURL:(NSURL *)URL
+                  error:(NSError **)error;

在 Swift,它会被这样导入:

swift
func removeItem(at: URL) throws

注意 removeItem(at:) 方法被 Swift 导入时,返回值类型为 Void,没有 error 参数,并且还有一个 throws 声明。

如果 Objective-C 方法的最后一个非块类型的参数是 NSError ** 类型,Swift 会将之替换为 throws 关键字,以表明该方法可以抛出一个错误。如果 Objective-C 方法的错误参数也是它的第一个参数,Swift 会尝试删除选择器的第一部分中的 “WithError” 或 “AndReturnError” 后缀(如果存在)来进一步简化方法名。如果简化后的方法名会和其他方法名冲突,则不会对方法名进行简化。

如果产生错误的 Objective-C 方法返回一个用来表示方法调用成功或失败的 BOOL 值,Swift 会把返回值转换为 Void。同样,如果产生错误的 Objective-C 方法返回一个nil 值来表明方法调用失败,Swift 会把返回值转换为非可选类型。

否则,如果不能推断任何约定,则该方法保持不变。

注意
在一个产生错误的 Objective-C 方法声明上使用 NS_SWIFT_NOTHROW 宏可以防止该方法被 Swift 作为抛出方法导入。

捕获和处理错误

在 Objective-C,错误处理是可选的,这意味着除非提供了一个错误指针,否则方法产生的错误会被忽略。在 Swift,调用一个会抛出错误的方法时必须明确进行错误处理。

以下示例演示了在 Objective-C 中调用方法时如何处理错误:

objective-c
NSFileManager *fileManager = [NSFileManager defaultManager];
+NSURL *fromURL = [NSURL fileURLWithPath:@"/path/to/old"];
+NSURL *toURL = [NSURL fileURLWithPath:@"/path/to/new"];
+NSError *error = nil;
+BOOL success = [fileManager moveItemAtURL:fromURL toURL:toURL error:&error];
+if (!success) {
+    NSLog(@"Error: %@", error.domain);
+}

Swift 中等效的代码如下所示:

swift
let fileManager = FileManager.default
+let fromURL = URL(fileURLWithPath: "/path/to/old")
+let toURL = URL(fileURLWithPath: "/path/to/new")
+do {
+    try fileManager.moveItem(at: fromURL, to: toURL)
+} catch let error as NSError {
+    print("Error: \\(error.domain)")
+}

此外,你可以使用 catch 子句来匹配特定的错误代码以便区分可能的失败情况:

swift
do {
+    try fileManager.moveItem(at: fromURL, to: toURL)
+} catch CocoaError.fileNoSuchFile {
+    print("Error: no such file exists")
+} catch CocoaError.fileReadUnsupportedScheme {
+    print("Error: unsupported scheme (should be 'file://')")
+}

将错误转换为可选值

在 Objective-C 中,当你只关心是否有错误,而不是发生什么特定错误时,你可以传递 NULL 作为错误参数。在 Swift,你可以使用 try? 关键字将抛出表达式转换为返回可选值的表达式,然后检查返回值是否为 nil

例如,NSFileManager 的实例方法 URLForDirectory(_:inDomain:appropriateForURL:create:) 会返回指定搜索路径和域中的 URL,或者如果适当的 URL 不存在且不能创建,则会产生错误。在 Objective-C 中,此方法成功或是失败可以通过是否返回 URL 对象来判断。

objective-c
NSFileManager *fileManager = [NSFileManager defaultManager];
+     
+NSURL *tmpURL = [fileManager URLForDirectory:NSCachesDirectory 
+                                    inDomain:NSUserDomainMask 
+                           appropriateForURL:nil 
+                                      create:YES 
+                                       error:NULL];
+if (tmpURL != nil) {
+    // ...
+}

在 Swfit 中你可以像下面这样做:

swift
let fileManager = FileManager.default
+if let tmpURL = try? fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) {
+    // ...
+}

抛出错误

如果在一个 Objective-C 方法中发生错误,则使用错误对象来填充该方法的错误指针参数:

objective-c
// 发生一个错误
+if (errorPtr) {
+   *errorPtr = [NSError errorWithDomain:NSURLErrorDomain
+                                   code:NSURLErrorCannotOpenFile
+                               userInfo:nil];
+}

如果在一个 Swift 方法中发生错误,则错误会被抛出,并且自动传播给调用者:

swift
// 发生一个错误
+throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)

如果 Objective-C 代码调用会抛出错误的 Swift 方法,则该错误会自动填充到桥接的 Objective-C 方法的错误指针参数。

例如,考虑 NSDocument 中的 read(from:ofType:) 方法。在 Objective-C 中,此方法的最后一个参数是 NSError ** 类型。在 Swift 的 NSDocument 子类中重写此方法时,该方法会以抛出错误的方式替代错误指针参数。

swift
class SerializedDocument: NSDocument {
+    static let ErrorDomain = "com.example.error.serialized-document"
+
+    var representedObject: [String: Any] = [:]
+
+    override func read(from fileWrapper: FileWrapper, ofType typeName: String) throws {
+        guard let data = fileWrapper.regularFileContents else {
+            throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)
+        }
+
+        if case let JSON as [String: Any] = try JSONSerialization.jsonObject(with: data, options: []) {
+            self.representedObject = JSON
+        } else {
+            throw NSError(domain: SerializedDocument.ErrorDomain, code: -1, userInfo: nil)
+        }
+    }
+}

如果该方法无法使用文档的常规文件内容来创建对象,就会抛出一个 NSError 对象。如果该方法在 Swift 中调用,则错误会传播到它的调用域。如果该方法在 Objective-C 中调用,则错误会填充错误指针参数。

处理异常

在 Objective-C 中,异常与错误不同。Objective-C 异常处理使用 @try@catch@throw 语法来标明不可恢复的程序错误。这与司空见惯的 Cocoa 错误模式截然不同,后者使用一个尾随的 NSError 参数来标明你在开发过程中设计的可恢复错误。

在 Swift 中,你可以从使用 Cocoa 错误模式传递的错误中恢复,如前文错误处理中所述。然而,没有可靠的方法可以从 Swift 中的 Objective-C 异常中恢复。要处理 Objective-C 异常,则需编写 Objective-C 代码,以便在异常到达任何 Swift 代码之前捕获异常。

关于 Objective-C 异常的更多信息,请参阅 Exception Programming Topics

捕获和处理自定义错误

Objective-C 框架可以使用自定义错误域和枚举来组织相关的错误类别。

下面的例子展示了使用 Objective-C 中的 NS_ERROR_ENUM 宏定义的自定义错误类型:

objective-c
extern NSErrorDomain const MyErrorDomain;
+typedef NS_ERROR_ENUM(MyErrorDomain, MyError) {
+    specificError1 = 0,
+    specificError2 = 1
+};

如下示例展示了如何在 Swift 中使用该自定义错误类型生成错误:

swift
func customThrow() throws {
+    throw NSError(
+        domain: MyErrorDomain,
+        code: MyError.specificError2.rawValue,
+        userInfo: [
+            NSLocalizedDescriptionKey: "A customized error from MyErrorDomain."
+        ]
+    )
+}
+
+do {
+    try customThrow()
+} catch MyError.specificError1 {
+    print("Caught specific error #1")
+} catch let error as MyError where error.code == .specificError2 {
+    print("Caught specific error #2, ", error.localizedDescription)
+    // Prints "Caught specific error #2. A customized error from MyErrorDomain."
+} let error {
+    fatalError("Some other error: \\(error)")
+}

键值观察

键值观察是一种能让某个对象在其他对象指定属性变化时得到通知的机制。只要 Swift 类继承自 NSObject 类,就可以在 Swift 中通过如下两步实现键值观察。

  1. 为想要观察的属性添加 dynamic 修改符和 @objc 属性。关于 dynamic 修饰符的更多信息,请参阅强制动态派发小节。

    swift
    class MyObjectToObserve: NSObject {
    +    @objc dynamic var myDate = NSDate()
    +    func updateDate() {
    +        myDate = NSDate()
    +    }
    +}
  2. 为键路径创建一个对应的观察者并调用 observe(_:options:changeHandler) 方法。关于键路径的更多信息,请参阅键和键路径小节。

    swift
    class MyObjectToObserve: NSObject {
    +    @objc dynamic var myDate = NSDate()
    +    func updateDate() {
    +        myDate = NSDate()
    +    }
    +}
    +
    +class MyObserver: NSObject {
    +    @objc var objectToObserve: MyObjectToObserve
    +    var observation: NSKeyValueObservation?
    +
    +    init(object: MyObjectToObserve) {
    +        objectToObserve = object
    +        super.init()
    +
    +        observation = observe(\\.objectToObserve.myDate) { object, change in
    +            print("Observed a change to \\(object.objectToObserve).myDate, updated to: \\(object.objectToObserve.myDate)")
    +        }
    +    }
    +}
    +
    +let observed = MyObjectToObserve()
    +let observer = MyObserver(object: observed)
    +
    +observed.updateDate()

目标-动作

目标-动作是一种常见的 Cocoa 设计模式,可以在特定事件发生时,让某个对象向另一个对象发送消息。Swift 和 Objective-C 的目标-动作模式基本类似。在 Swift,可以使用Selector类型引用 Objective-C 的选择器。请参阅 选择器 小节查看在 Swift 中使用目标-动作模式的示例。

单例

单例模式提供了一个可全局访问的共享对象。可以自己创建在应用程序内共享的单例对象,从而提供一个统一的资源或服务的访问入口,比如一个播放音效的音频通道或发起 HTTP 请求的网络管理者。

在 Objective-C,可以用dispatch_once函数包裹初始化代码,从而保证在应用程序的生命周期内,块内的代码只会执行一次,这样就确保了只有唯一的实例会被创建:

objective-c
+ (instancetype)sharedInstance {
+    static id _sharedInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _sharedInstance = [[self alloc] init];
+    });
+    
+    return _sharedInstance;
+}

在 Swift,可以简单地使用静态类型属性来实现单例,它能保证延迟初始化只执行一次,即使在多个线程同时访问的情况下:

swift
class Singleton {
+    static let sharedInstance = Singleton()
+}

如果在初始化的基础上还需要进行额外的设置,那么可以通过调用闭包返回初始值的方式来初始化:

swift
class Singleton {
+    static let sharedInstance: Singleton = {
+        let instance = Singleton()
+        // 设置代码
+        return instance
+    }()
+}

请参阅 The Swift Programming Language 中文版 中的 类型属性 小节获取更多信息。

内省

在 Objective-C,使用isKindOfClass:方法检查某个对象是否是特定类型的实例,使用conformsToProtocol:方法检查某个对象是否符合特定协议。在 Swift,可以使用is运算符来检查类型,可以使用as?运算符向下转换到指定类型。

可以使用is运算符检查一个实例是否是指定类或其子类的实例。若是,那么is返回结果为true,反之为false

swift
if object is UIButton {
+    // object 是 UIButton 类型
+} else {
+    // object 不是 UIButton 类型
+}

也可以使用as?运算符尝试向下转换到子类型。as?运算符返回可选类型的值,可结合if-let语句使用。

swift
if let button = object as? UIButton {
+    // object 成功转换为 UIButton 并绑定到 button
+} else {
+    // object 无法转换为 UIButton
+}

请参阅 The Swift Programming Language 中文版 中的 类型转换 章节获取更多信息。

检查协议符合性以及转换到符合协议类型的语法和上述类型检查和转换的语法是完全一样的。如下是使用as?检查协议符合性的示例:

swift
if let dataSource = object as? UITableViewDataSource {
+    // object 符合 UITableViewDataSource 协议并绑定到 dataSource
+} else {
+    // object 不符合 UITableViewDataSource 协议
+}

注意,经过转换之后,dataSource常量的类型为UITableViewDataSource,所以只能访问和调用UITableViewDataSource协议定义的属性和方法。想进行其他操作时,必须将其转换为其他类型。

请参阅 The Swift Programming Language 中文版 中的 协议 章节获取更多信息。

序列化

通过序列化,可以在应用程序中编码和解码对象,将其转换为独立于体系结构的数据形式,例如 JSON 或属性列表,并能从这类数据形式转换回对象。这类数据形式可以写入文件,传给其他本地进程,以及通过网络进行传递。

在 Objective-C 中,可以使用 Foundation 框架的 NSJSONSerialiation 类或 NSPropertyListSerialization 类从 JSON 或者属性列表来实例化对象,通常这种对象会是 NSDictionary<NSString *, id> 类型。

在 Swift 中,标准库定义了一套标准化方法来编码和解码数据。若要使用这套方法,你可以让自定义类型遵守 Encodable 或 Decodable 协议,若要同时遵守这两种协议,更便捷的方式是直接遵守 Codable 协议。你可以通过 Foundation 库中的 JSONEncoderPropertyListEncoder 类将某个实例转化为 JSON 或属性列表数据。与此相似,你可以用 JSONDecoderPropertyListDecoder 类从 JSON 或属性列表数据解码并初始化实例。

例如,一个应用从 web 服务器接收到一些表示食品杂货店商品的 JSON 数据,如下所示:

swift
{
+    "name": "Banana",
+    "points": 200,
+    "description": "A banana grown in Ecuador.",
+    "varieties": [
+    	"yellow",
+    	"green",
+    	"brown"
+    ]
+}

如下代码演示了如何编写一个表示食品杂货店商品的 Swift 类型,该类型可以使用任何提供了编码器和解码器的序列化格式:

swift
struct GroceryProduct: Codable {
+    let name: String
+    let points: Int
+    let description: String
+    let varieties: [String]
+}

你可以从 JSON 数据形式创建 GroceryProduct 实例,只需创建一个 JSONDecoder 实例,然后传入 GroceryProduct.self 类型以及相应的 JSON 数据:

swift
let json = """
+    {
+         "name": "Banana",
+         "points": 200,
+         "description": "A banana grown in Ecuador.",
+         "varieties": [
+             "yellow",
+             "green",
+             "brown"
+          ]
+    }
+""".data(using: .utf8)!
+
+let decoder = JSONDecoder()
+let banana = try decoder.decode(GroceryProduct.self, from: json)
+
+print("\\(banana.name) (\\(banana.points) points): \\(banana.description)")
+// Prints "Banana (200 points): A banana grown in Ecuador."

关于如何编码和解码更复杂的自定义类型的相关信息,请参阅 Encoding and Decoding Custom Types。关于如何编码和解码 JSON 的更多信息,请参阅 Using JSON with Custom Types

本地化

在 Objective-C,通常用NSLocalizedString系列宏来本地化字符串。这套宏包括NSLocalizedStringNSLocalizedStringFromTableNSLocalizedStringFromTableInBundle,以及NSLocalizedStringWithDefaultValue。而在 Swift,NSLocalizedString(_:tableName:bundle:value:comment:)函数就可以实现NSLocalizedString系列宏的这些功能。

Swift 并没有为每个本地化宏单独定义函数,而是为NSLocalizedString(_:tableName:bundle:value:comment:)函数的tableNamebundlevalue参数提供了默认值,以便可以在需要时重写它们。

例如,本地化字符串最常见的形式可能仅仅需要一个本地化键和一句注释:

swift
let format = NSLocalizedString("Hello, %@!", comment: "Hello, {given name}!")
+let name = "Mei"
+let greeting = String(format: format, arguments: [name as CVarArg])
+print(greeting)
+// 打印 "Hello, Mei!"

或者,为了使用单独的包来提供本地化资源,应用可能需要使用更复杂的本地化形式:

swift
if let path = Bundle.main.path(forResource: "Localization", ofType: "strings", inDirectory: nil, forLocalization: "ja"),
+    let bundle = Bundle(path: path) {
+    let translation = NSLocalizedString("Hello", bundle: bundle, comment: "")
+    print(translation)
+}
+// 打印 "こんにちは"

更多信息请参阅 Internationalization and Localization Guide

自动释放池

自动释放池块可以让对象放弃所有权而又不会被立即释放。通常,你不需要创建自己的自动释放池块,但是有的情况下则必须创建,例如生成次级线程时,还有一些时候则最好创建,例如通过循环创建大量临时的自动释放对象时。

在 Objective-C,自动释放池块使用@autoreleasepool标记。在 Swift,你可以使用autoreleasepool(_:)函数在自动释放池块中执行一个闭包。

swift
import Foundation
+
+autoreleasepool {
+    // 创建自动释放对象的相关代码
+}

更多信息请参阅 Advanced Memory Management Programming Guide.

API 可用性

一些 API 并非在所有平台的所有版本中都可用。为了确保应用程序能够适应任何功能上的差异,就需要检查这些 API 的可用性。

在 Objective-C,使用respondsToSelector:instancesRespondToSelector:方法检查一个类或者实例的方法是否可用。否则,调用方法可能会抛出NSInvalidArgumentException类型的unrecognized selector sent to instance异常。例如,CLLocationManager实例的requestWhenInUseAuthorization方法从iOS 8.0macOS10.10开始才可用:

objective-c
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {
+    // 方法可用
+} else {
+    // 方法不可用
+}

在 Swift,试图调用项目所支持的最低平台版本不支持的方法将会引发编译时错误。

如上例子在 Swift 中如下所示:

swift
let locationManager = CLLocationManager()
+locationManager.requestWhenInUseAuthorization()
+// error: only available on iOS 8.0 or newer

如果应用程序在版本低于iOS 8.0或者macOS 10.10的平台上运行,那么requestWhenInUseAuthorization()方法将不可用,因此编译器会报告错误。

Swift 代码可以使用 API 可用性在运行时作为判断条件。可用性检查可以作为控制流语句的一个条件,例如ifguardwhile语句。

针对之前的例子,可以在if语句中检查可用性,当requestWhenInUseAuthorization()方法在运行时可用时才去调用:

swift
let locationManager = CLLocationManager()
+if #available(iOS 8.0, macOS 10.10, *) {
+    locationManager.requestWhenInUseAuthorization()
+}

或者,可以在guard语句中检查可用性,除非当前的平台版本符合指定要求,否则将退出作用域。这种方式简化了处理不同平台功能时的逻辑。

swift
let locationManager = CLLocationManager()
+guard #available(iOS 8.0, macOS 10.10, *) else { return }
+locationManager.requestWhenInUseAuthorization()

每个平台参数由下面列出的平台名称组成,后面跟着相应的版本号。最后一个参数是一个星号(*),用来处理未来可能的平台。

平台名称:

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension

所有的 Cocoa API 都提供了可用性信息,因此能确信代码可以在应用所支持的任何平台上如期工作。

可以用@available特性标注自己的 API 声明来指明其可用性。@available特性的语法和#available一样,以逗号分隔的参数提供平台版本要求。

例如:

swift
@available(iOS 8.0, macOS 10.10, *)
+func useShinyNewFeature() {
+    // ...
+}

注意
使用@available特性标记的方法可以安全地使用满足指定平台要求的 API 而不用再进行可用性检查。

处理命令行参数

macOS,通常通过点击 Dock 或者 Launchpad 上的应用程序图标启动应用程序,也可以双击 Finder 中的应用程序图标。然而,也可以使用终端通过编程的方式打开应用程序,并可以为其传递一些命令行参数。

可以访问类型属性CommandLine.arguments获取应用程序启动时指定的一系列命令行参数。

$ /path/to/app --argumentName value
swift
for argument in CommandLine.arguments {
+    print(argument)
+}
+// 打印 /path/to/app
+// 打印 --argumentName
+// 打印 value

CommandLine.arguments的第一个元素总是可执行文件的路径。从Process.arguments[1]开始才是启动时指定的命令行参数。

注意
这等同于访问ProcessInfo.processInfoarguments属性。

`,158)]))}const g=i(h,[["render",l]]);export{o as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.lean.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.lean.js new file mode 100644 index 0000000..12bae41 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_04-Adopting Cocoa Design Patterns.md.B1zZGYT6.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const o=JSON.parse('{"title":"采用 Cocoa 设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md","filePath":"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md"}'),h={name:"frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md"};function l(e,s,p,k,r,E){return n(),a("div",null,s[0]||(s[0]=[t("",158)]))}const g=i(h,[["render",l]]);export{o as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.js new file mode 100644 index 0000000..df923bc --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.js @@ -0,0 +1,207 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"与 C 语言 API 交互","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/05-Interacting with C APIs.md","filePath":"frontend/swift/02-Interoperability/05-Interacting with C APIs.md"}'),h={name:"frontend/swift/02-Interoperability/05-Interacting with C APIs.md"};function l(k,s,p,e,d,E){return n(),a("div",null,s[0]||(s[0]=[t(`

与 C 语言 API 交互

为了更好地支持与 Objective-C 语言的互用性,Swift 对一些 C 语言的类型和特性保持了兼容性,提供了一些方式来使用常见的 C 语言设计和模式。

基本类型

Swift 提供了一些与 C 语言基本数值类型(例如charintfloatdouble)对应的类型。然而,这些类型和 Swift 基本数值类型(例如Int)之间不能进行隐式转换。因此,只应在必要时才使用这些类型,尽可能地使用Int这种原生 Swift 类型。

C 类型Swift 类型
boolCBool
char, signed charCChar
unsigned charCUnsignedChar
shortCShort
unsigned shortCUnsignedShort
intCInt
unsigned intCUnsignedInt
longCLong
unsigned longCUnsignedLong
long longCLongLong
unsigned long longCUnsignedLongLong
wchar_tCWideChar
char16_tCChar16
char32_tCChar32
floatCFloat
doubleCDouble

全局常量

C 和 Objective-C 的源文件中定义的全局常量会自动被 Swift 编译器导入为 Swift 全局常量。

导入的常量枚举和结构体

在 Objective-C,常量通常用来为属性或者方法参数提供一系列合适的值。你可以用 NS_TYPED_ENUMNS_TYPED_EXTENSIBLE_ENUM 宏标注 Objective-C typedef 声明,这样 Swift 就会将该类型导入为枚举或结构体,而该类型的各种常量会变成相应的类型成员。使用 NS_TYPED_ENUM 宏标注一套不会再扩充新值的常量声明。使用 NS_TYPED_EXTENSIBLE_ENUM 宏标注一套可以通过 Swift 扩展来扩充新值的常量声明。

表示一组固定值的常量声明在标注 NS_TYPED_ENUM 宏之后会以结构体形式导入到 Swift。例如,请考虑如下整形常量类型 TrafficLightColor 的 Objective-C 声明:

objective-c
typedef long TrafficLightColor NS_TYPED_ENUM;
+
+TrafficLightColor const TrafficLightColorRed;
+TrafficLightColor const TrafficLightColorYellow;
+TrafficLightColor const TrafficLightColorGreen;

Swift 会以如下形式导入它们:

swift
struct TrafficLightColor: RawRepresentable, Equatable, Hashable {
+    typealias RawValue = Int
+
+    init(rawValue: RawValue)
+    var rawValue: RawValue { get }
+
+    static var red: TrafficLightColor { get }
+    static var yellow: TrafficLightColor { get }
+    static var green: TrafficLightColor { get }
+}

表示一套可扩充新值的常量的声明在标注 NS_TYPED_EXTENSIBLE_ENUM 宏之后也会作为结构体导入到 Swift。例如,考虑以下 Objective-C 声明,它们表示交通信号灯的颜色组合:

objective-c
typedef TrafficLightColor TrafficLightCombo [3] NS_TYPED_EXTENSIBLE_ENUM;
+
+TrafficLightCombo const TrafficLightComboJustRed;
+TrafficLightCombo const TrafficLightComboJustYellow;
+TrafficLightCombo const TrafficLightComboJustGreen;
+
+TrafficLightCombo const TrafficLightComboRedYellow;

Swift 会以如下形式导入它们:

swift
struct TrafficLightCombo: RawRepresentable, Equatable, Hashable {
+    typealias RawValue = (TrafficLightColor, TrafficLightColor, TrafficLightColor)
+
+    init(_ rawValue: RawValue)
+    init(rawValue: RawValue)
+    var rawValue: RawValue { get }
+
+    static var justRed: TrafficLightCombo { get }
+    static var justYellow: TrafficLightCombo { get }
+    static var justGreen: TrafficLightCombo { get }
+    static var redYellow: TrafficLightCombo { get }
+}

可以看到,使用可扩充形式的常量声明在导入后会额外获得一个构造器,这使得调用者可以在扩充新值时省略参数标签。

标注 NS_TYPED_EXTENSIBLE_ENUM 宏的常量声明可在 Swift 代码中进行扩充以添加新值:

swift
extension TrafficLightCombo {
+    static var all: TrafficLightCombo {
+        return TrafficLightCombo((.red, .yellow, .green))
+    }
+}

注意
你可能会遇到使用 NS_STRING_ENUMNS_EXTENSIBLE_STRING_ENUM 旧版宏的 Objective-C 代码,这些宏用于组织字符串常量。组织任意类型的相关常量(包括字符串常量)时,请使用 NS_TYPED_ENUMNS_TYPED_EXTENSIBLE_ENUM

函数

Swift 将 C 头文件中的所有函数声明导入为 Swift 全局函数。例如,思考如下 Objective-C 函数声明:

objective-c
int product(int multiplier, int multiplicand);
+int quotient(int dividend, int devisor, int *remainder);
+
+struct Point2D createPoint2D(float x, float y);
+float distance(struct Point2D from, struct Point2D to);

Swift 会以如下形式导入它们:

swift
func product(_ multiplier: Int32, _ multiplicand: Int32) -> Int32
+func quotient(_ dividend: Int32, _ devisor: Int32, _ remainder: UnsafeMutablePointer<Int32>) -> Int32
+
+func createPoint2D(_ x: Float, _ y: Float) -> Point2D
+func distance(_ from: Point2D, _ to: Point2D) -> Float

变参函数

在 Swift,可以调用 C 中的可变参数函数,例如vasprintf函数,调用这种函数需使用 getVaList(_:)withVaList(_:_:) 函数。getVaList(_:)函数接受一个CVarArgType类型的数组,返回一个CVaListPointer类型的值。withVaList(_:_:)函数则会在闭包体中通过闭包参数来提供该值,而不是直接返回它。最终,CVaListPointer类型的值会传递给接受可变参数的 C 函数的va_list参数。

例如,如下示例代码演示了如何在 Swift 中调用vasprintf函数:

swift
func swiftprintf(format: String, arguments: CVarArg...) -> String? {
+    return withVaList(arguments) { va_list in
+        var buffer: UnsafeMutablePointer<Int8>? = nil
+        return format.withCString { CString in
+            guard vasprintf(&buffer, CString, va_list) != 0 else {
+                return nil
+            }
+
+            return String(validatingUTF8: buffer!)
+        }
+    }
+}
+print(swiftprintf(format: "√2 ≅ %g", arguments: sqrt(2.0))!)
+// 打印 "√2 ≅ 1.41421"

注意
可选指针不能传递给withVaList(_:invoke:)函数。相反,使用Int.init(bitPattern:)构造器将可选指针转化为Int值,在所有支持的平台上,Int类型的 C 可变函数调用约定和指针类型一样。

结构体

Swift 将 C 头文件中的所有结构体声明导入为 Swift 结构体。导入后的结构体会用存储属性表示结构体中的字段,并且有一个参数对应各个存储属性的构造器。如果所有被导入的结构体成员都有默认值,Swift 还会提供一个无参数的默认构造器。例如,思考如下 C 结构体声明:

objective-c
struct Color {
+    float r, g, b;
+};
+typedef struct Color Color;

相对应的 Swift 结构体如下所示:

swift
public struct Color {
+    var r: Float
+    var g: Float
+    var b: Float
+
+    init()
+    init(r: Float, g: Float, b: Float)
+}

导入函数作为类型成员

C API,例如 Core Foundation 框架,通常会提供一些函数用于创建、访问、修改结构体。你可以在自己的代码中使用CF_SWIFT_NAME宏来让 Swift 将这些 C 函数导入为相应结构体的成员函数。例如,对于如下 C 函数声明:

objective-c
Color ColorCreateWithCMYK(float c, float m, float y, float k) CF_SWIFT_NAME(Color.init(c:m:y:k:));
+
+float ColorGetHue(Color color) CF_SWIFT_NAME(getter:Color.hue(self:));
+void ColorSetHue(Color color, float hue) CF_SWIFT_NAME(setter:Color.hue(self:newValue:));
+
+Color ColorDarkenColor(Color color, float amount) CF_SWIFT_NAME(Color.darken(self:amount:));
+
+extern const Color ColorBondiBlue CF_SWIFT_NAME(Color.bondiBlue);
+
+Color ColorGetCalibrationColor(void) CF_SWIFT_NAME(getter:Color.calibration());
+Color ColorSetCalibrationColor(Color color) CF_SWIFT_NAME(setter:Color.calibration(newValue:));

Swift 会将其导入为结构体的成员函数:

swift
extension Color {
+    init(c: Float, m: Float, y: Float, k: Float)
+
+    var hue: Float { get set }
+
+    func darken(amount: Float) -> Color
+
+    static var bondiBlue: Color
+
+    static var calibration: Color
+}

传入CF_SWIFT_NAME宏的参数使用和#selector表达式相同的语法。实例方法对应的CF_SWIFT_NAME宏中的参数self引用着方法的调用者。

注意
你无法使用CF_SWIFT_NAME宏改变方法的参数顺序或参数数量,要实现该需求,只能提供一个新的 Swift 函数,并在函数实现中调用相关函数。

枚举

Swift 会将用NS_ENUM宏标注的 C 语言枚举导入为原始值类型为Int的 Swift 枚举。无论是系统框架还是自己代码中的枚举,导入到 Swift 后,它们的前缀名均会被移除。

例如,一个 Objective-C 枚举的声明如下:

objective-c
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
+	UITableViewCellStyleDefault,
+    UITableViewCellStyleValue1,
+    UITableViewCellStyleValue2,
+    UITableViewCellStyleSubtitle
+};

在 Swift,它被导入为如下形式:

swift
enum UITableViewCellStyle: Int {
+    case \`default\`
+    case value1
+    case value2
+    case subtitle
+}

需要使用一个枚举值时,使用以点(.)开头的枚举变量名:

swift
let cellStyle: UITableViewCellStyle = .default

注意
对于导入到 Swift 的 C 枚举,使用原始值进行初始化时,即使原始值不匹配任何枚举值,初始化也不会失败。这是为了兼容 C 枚举的特性,即枚举可以存储任何值,包括一些只在内部使用而没有在头文件中暴露出来的值。

Swift 会将未使用NS_ENUMNS_OPTIONS宏标注的 C 语言枚举导入为结构体。每个枚举成员会被导入为属性类型是该结构体类型的全局只读计算型属性,而不是作为结构体本身的属性。

例如,下面是个未使用NS_ENUM宏声明的 C 语言枚举:

objective-c
typedef enum {
+    MessageDispositionUnread = 0,
+    MessageDispositionRead = 1,
+    MessageDispositionDeleted = -1,
+} MessageDisposition;

在 Swift,它被导入为如下形式:

swift
struct MessageDisposition: RawRepresentable, Equatable {}
+
+var MessageDispositionUnread: MessageDisposition { get }
+var MessageDispositionRead: MessageDisposition { get }
+var MessageDispositionDeleted: MessageDisposition { get }

被导入到 Swift 的 C 语言枚举会自动遵守Equatable协议。

选项集

Swfit 会将使用NS_OPTIONS宏标注的 C 语言枚举导入为 Swfit 选项集。选项集会像枚举一样把前缀移除,只剩下选项值名称。

例如,一个 Objective-C 选项集的声明如下:

objective-c
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
+    UIViewAutoresizingNone                 = 0,
+    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
+    UIViewAutoresizingFlexibleWidth        = 1 << 1,
+    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
+    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
+    UIViewAutoresizingFlexibleHeight       = 1 << 4,
+    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
+};

在 Swift,它被导入为如下形式:

swift
public struct UIViewAutoresizing : OptionSet {
+    public init(rawValue: UInt)
+
+    public static var flexibleLeftMargin: UIViewAutoresizing { get }
+    public static var flexibleWidth: UIViewAutoresizing { get }
+    public static var flexibleRightMargin: UIViewAutoresizing { get }
+    public static var flexibleTopMargin: UIViewAutoresizing { get }
+    public static var flexibleHeight: UIViewAutoresizing { get }
+    public static var flexibleBottomMargin: UIViewAutoresizing { get }
+}

在 Objective-C,一个选项集是一些整数值的位掩码。可以使用按位或操作符(|)组合选项值,使用按位与操作符(&)检查选项值。可以使用常量值或者表达式创建一个选项集。一个空的选项集使用常数0表示。

在 Swift,选项集用一个遵守OptionSet协议的结构体表示,每个选项值都是结构体的一个静态变量。可以使用一个数组字面量创建一个选项集,访问选项值像枚举一样也用点(.)开头。创建空选项集时,可以使用一个空数组字面量,也可以调用默认构造器。

注意
在导入标注NS_OPTIONS宏的 C 枚举时,Swift 会忽略值为0的枚举成员,因为 Swift 会使用空选项集表示这种选项。

选项集类似于 Swift 的集合类型Set,可以用insert(_:)或者formUnion(_:)方法添加选项值,用remove(_:)或者subtract(_:)方法移除选项值,用contains(_:)方法检查选项值。

swift
let options: Data.Base64EncodingOptions = [
+    .lineLength64Characters,
+    .endLineWithLineFeed
+]
+let string = data.base64EncodedString(options: options)

联合体

Swift 将 C 联合体导入为 Swift 结构体。尽管 Swift 不支持联合体,但 C 联合体导入为 Swift 结构体后仍将保持类似 C 联合体的行为。例如,思考如下名为SchroedingersCat的 C 联合体,它拥有isAliveisDead两个字段:

swift
union SchroedingersCat {
+    bool isAlive;
+    bool isDead;
+};
+
+它被导入到 Swift 后如下所示:
+
+struct SchroedingersCat {
+    var isAlive: Bool { get set }
+    var isDead: Bool { get set }
+
+    init(isAlive: Bool)
+    init(isDead: Bool)
+
+    init()
+}

由于 C 联合体所有字段共享同一块内存,因此联合体作为结构体导入到 Swift 后,所有计算属性也会共享同一块内存。这将导致修改任意计算属性的值都会改变其他计算属性的值。

在上述例子中,修改结构体SchroedingersCat的计算属性isAlive的值也会改变计算属性isDead的值:

swift
var mittens = SchroedingersCat(isAlive: false)
+
+print(mittens.isAlive, mittens.isDead)
+// 打印 "false false"
+
+mittens.isAlive = true
+print(mittens.isDead)
+// 打印 "true"

位字段

Swift 会将结构体中的位字段导入为结构体的计算型属性,例如 Foundation 中的NSDecimal类型。使用位字段相对应的计算属性时,Swift 会处理好这些值和其兼容的 Swift 类型之间的转换工作。

匿名结构体和联合体字段

C structunion类型既可以定义匿名字段,也可以定义具有匿名类型的字段。匿名字段由内部所嵌套的拥有命名字段的structunion类型构成。

例如,在如下这个 C 结构体Cake中,layersheight两个字段嵌套在匿名union类型中,toppings字段则是一个匿名struct类型:

objective-c
struct Cake {
+    union {
+        int layers;
+        double height;
+    };
+
+    struct {
+        bool icing;
+        bool sprinkles;
+    } toppings;
+};

导入到 Swift 后,可以像如下这样创建和使用它:

swift
var simpleCake = Cake()
+simpleCake.layers = 5
+print(simpleCake.toppings.icing)

Cake结构体被导入后会拥有一个逐一成员构造器,可以通过该构造器将结构体的字段初始化为自定义的值,就像下面这样:

swift
let cake = Cake(
+    .init(layers: 2),
+    toppings: .init(icing: true, sprinkles: false)
+)
+
+print("The cake has \\(cake.layers) layers.")
+// 打印 "The cake has 2 layers."
+print("Does it have sprinkles?", cake.toppings.sprinkles ? "Yes." : "No.")
+// 打印 "Does it have sprinkles? No."

因为Cake结构体第一个字段是匿名的,因此构造器的第一个参数没有标签。由于Cake结构体的字段是匿名类型,因此使用.init构造器,这将借助类型推断来为结构体的每个匿名字段设置初始值。

指针

Swift 尽可能地避免直接使用指针。不过,Swift 也提供了多种指针类型以供直接操作内存。如下表格使用Type作为类型名称的占位符来表示相应的映射语法。

对于返回类型,变量和参数,遵循如下映射:

C 语法Swift 语法
const Type *UnsafePointer<Type>
Type *UnsafeMutablePointer<Type>

对于类类型,遵循如下映射:

C 语法Swift 语法
Type * const *UnsafePointer<Type>
Type * __strong *UnsafeMutablePointer<Type>
Type **AutoreleasingUnsafeMutablePointer<Type>

对于指向原始内存的无类型指针,遵循如下映射:

C 语法Swift 语法
const void *UnsafeRawPointer
void *UnsafeMutableRawPointer

如果指针的类型在 Swift 中无法表示,例如某个不完备的结构体类型,Swift 会将之导入为OpaquePointer

常量指针

如果函数接受UnsafePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • UnsafePointer<Type>UnsafeMutablePointer<Type>AutoreleasingUnsafeMutablePointer<Type>类型的值,后两种类型会转换成UnsafePointer<Type>
  • 一个String类型的值,如果TypeInt8或者UInt8String类型的值会被自动转换为 UTF8 形式到一个缓冲区内,该缓冲区的指针会被传递给函数。
  • 一个左操作数为Type类型的inout表达式,左操作数的内存地址作为函数参数传入。
  • 一个[Type]类型的值,将作为该数组的起始指针传递给函数。

传递给函数的指针仅保证在函数调用期间内有效,不要试图保留指针并在函数返回之后继续使用。

如果定义了一个类似下面这样的函数:

swift
func takesAPointer(_ p: UnsafePointer<Float>) {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0
+takesAPointer(&x)
+takesAPointer([1.0, 2.0, 3.0])

如果函数接受UnsafeRawPointer参数,那么该函数参数可以是任意类型的UnsafePointer<Type>

如果定义了一个类似下面这样的函数:

swift
func takesAVoidPointer(_ p: UnsafeRawPointer?)  {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0, y: Int = 0
+takesAVoidPointer(&x)
+takesAVoidPointer(&y)
+takesAVoidPointer([1.0, 2.0, 3.0] as [Float])
+let intArray = [1, 2, 3]
+takesAVoidPointer(intArray)

可变指针

如果函数接受UnsafeMutablePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • 一个UnsafeMutablePointer<Type>类型的值。
  • 一个左操作数为Type类型的inout表达式,左操作数的内存地址作为函数参数传入。
  • 一个inout [Type]类型的值,将作为该数组的起始指针传入,其生命周期会延续到本次调用结束。

如果定义了一个类似下面这样的函数:

swift
func takesAMutablePointer(_ p: UnsafeMutablePointer<Float>) {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0
+var a: [Float] = [1.0, 2.0, 3.0]
+takesAMutablePointer(&x)
+takesAMutablePointer(&a)

如果函数接受UnsafeMutableRawPointer参数,那么该函数参数可以是任意类型的UnsafeMutablePointer<Type>

如果定义了一个类似下面这样的函数:

swift
func takesAMutableVoidPointer(_ p: UnsafeMutableRawPointer?)  {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0, y: Int = 0
+var a: [Float] = [1.0, 2.0, 3.0], b: [Int] = [1, 2, 3]
+takesAMutableVoidPointer(&x)
+takesAMutableVoidPointer(&y)
+takesAMutableVoidPointer(&a)
+takesAMutableVoidPointer(&b)

自动释放指针

如果函数接受AutoreleasingUnsafeMutablePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • 一个AutoreleasingUnsafeMutablePointer<Type>类型的值。
  • 一个inout表达式,其操作数首先被拷贝到一个无主临时缓冲区,缓冲区的地址会作为函数参数传入。函数调用结束时,读取并保留缓冲区中的值,然后重新赋值给操作数。

注意,上述列表中没有包含数组。

如果定义了一个类似下面这样的函数:

swift
func takesAnAutoreleasingPointer(_ p: AutoreleasingUnsafeMutablePointer<NSDate?>) {
+    // ...
+}

那么可以通过以下方式来调用该函数:

swift
var x: NSDate? = nil
+takesAnAutoreleasingPointer(&x)

指针指向的类型不会被桥接。例如,NSString **转换到 Swift 后,会是AutoreleasingUnsafeMutablePointer<NSString?>,而不是AutoreleasingUnsafeMutablePointer<String?>

函数指针

Swift 将 C 函数指针导入为沿用其调用约定的闭包,使用@convention(c)特性来表示。例如,一个类型为int (*)(void)的 C 函数指针,会以@convention(c) () -> Int32的形式导入到 Swift。

调用一个以函数指针为参数的函数时,可以传递一个顶级的 Swift 函数作为其参数,也可以传递闭包字面量,或者nil。也可以传递一个泛型类型的闭包属性或者泛型方法,只要闭包的参数列表或闭包体内没有引用泛型类型的参数。例如,Core Foundation 的CFArrayCreateMutable(_:_:_:)函数接受一个CFArrayCallBacks结构体作为参数,这个CFArrayCallBacks结构体使用一些函数指针进行初始化:

swift
func customCopyDescription(_ p: UnsafeRawPointer?) -> Unmanaged<CFString>? {
+    // 返回一个 Unmanaged<CFString>? 值
+}
+
+var callbacks = CFArrayCallBacks(
+    version: 0,
+    retain: nil,
+    release: nil,
+    copyDescription: customCopyDescription,
+    equal: { (p1, p2) -> DarwinBoolean in
+        // 返回布尔值
+    }
+)
+
+var mutableArray = CFArrayCreateMutable(nil, 0, &callbacks)

上面的例子中,结构体CFArrayCallBacks的构造器使用nil作为参数retainrelease的值,使用函数customCopyDescription作为参数copyDescription的值,最后使用一个闭包字面量作为参数equal的值。

注意
只有使用 C 函数指针调用约定的 Swift 函数才可以作为函数指针参数。如同 C 函数指针,使用@convention(c)特性的 Swift 函数同样不具有捕获周围作用域上下文的能力。

更多信息请参阅 The Swift Programming Language 中文版类型特性小节。

`,154)]))}const o=i(h,[["render",l]]);export{g as __pageData,o as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.lean.js b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.lean.js new file mode 100644 index 0000000..ed359c5 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_02-Interoperability_05-Interacting with C APIs.md.B7qyAuun.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const g=JSON.parse('{"title":"与 C 语言 API 交互","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/02-Interoperability/05-Interacting with C APIs.md","filePath":"frontend/swift/02-Interoperability/05-Interacting with C APIs.md"}'),h={name:"frontend/swift/02-Interoperability/05-Interacting with C APIs.md"};function l(k,s,p,e,d,E){return n(),a("div",null,s[0]||(s[0]=[t("",154)]))}const o=i(h,[["render",l]]);export{g as __pageData,o as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.js b/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.js new file mode 100644 index 0000000..6ccbded --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.js @@ -0,0 +1,79 @@ +import{_ as s,c as a,o as t,ag as e}from"./chunks/framework.BHpayLOB.js";const n="/assets/DAG_2x.NtzGJ5bn.png",l="/assets/bridgingheader_2x.CFOipoi_.png",E=JSON.parse('{"title":"在项目中同时使用 Swift 和 Objective-C","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md","filePath":"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md"}'),h={name:"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md"};function p(k,i,c,r,d,o){return t(),a("div",null,i[0]||(i[0]=[e('

在项目中同时使用 Swift 和 Objective-C

由于 Swift 与 Objective-C 的兼容性,你可以在项目中同时使用两种语言,开发基于混合语言的应用程序。利用这种特性,你可以用 Swift 的最新语言特性实现应用程序的部分功能,并无缝并入现有的 Objective-C 代码中。

混搭概述

Objective-C 和 Swift 文件可以在项目中并存,无论这个项目原本是基于 Objective-C 还是 Swift。还可以直接往现有项目中添加另一种语言的源文件。这种自然的工作流程使得创建基于混合语言的应用程序或框架变得和单独使用一种语言一样简单。

基于混合语言编写应用程序或框架的过程还是有些区别的。下图展示了同时使用两种语言时,在同一 target 中导入代码的基本原理,后续小节会介绍更多细节。

在应用程序 target 中导入代码

在编写基于混合语言的应用程序时,可能需要在 Swift 代码中使用 Objective-C 代码,或者反过来。下面描述的流程适用于非框架类型的 target 。

将 Objective-C 代码导入到 Swift

在应用程序 target 中导入一系列 Objective-C 文件供 Swift 代码使用时,需要依靠 Objective-C 桥接头文件将这些文件暴露给 Swift。添加 Swift 文件到现有的 Objective-C 项目时(或者反过来),Xcode 会自动创建 Objective-C 桥接头文件。

如果选择创建,Xcode 会随着源文件的创建生成 Objective-C 桥接头文件,并用产品模块名拼接上"-Bridging-Header.h"作为 Objective-C 桥接头文件的文件名。关于产品模块名的具体介绍,请参阅为产品模块命名小节。

或者,可以选择File > New > File > (iOS,watchOS,tvOS,macOS) > Source > Header File来手动创建 Objective-C 桥接头文件。

你可以编辑这个 Objective-C 桥接头文件将 Objective-C API 暴露给 Swift。

在 target 中将 Objective-C 代码导入到 Swift
  1. 在 Objective-C 桥接头文件中,导入希望暴露给 Swift 的 Objective-C 头文件。例如:

    objective-c
    #import "XYZCustomCell.h"
    +#import "XYZCustomView.h"
    +#import "XYZCustomViewController.h"
  2. 确保在Build Settings > Swfit Compiler - Code Generation > Objective-C Bridging Header中设置了 Objective-C 桥接头文件的路径。该路径相对于项目,类似Info.plistBuild Settings中指定的路径。Xcode 自动生成 Objective-C 桥接头文件时会自动设置该路径,因此大多数情况下你不需要专门去设置它。

在 Objective-C 桥接头文件中导入的所有 Objective-C 头文件都会暴露给 Swift。target 中所有 Swift 文件都可以使用这些 Objective-C 头文件中的内容,不需要任何导入语句。不但如此,你还能用 Swift 语法使用这些自定义的 Objective-C 代码,就像使用系统的 Swift 类一样。

swift
let myCell = XYZCustomCell()
+myCell.subtitle = "A custom cell"

将 Swift 代码导入到 Objective-C

将 Swift 代码导入到 Objective-C 时,需要依靠 Xcode 自动生成的头文件将这些 Swift 文件暴露给 Objective-C(此头文件不是上小节描述的 Objective-C 桥接头文件,该头文件在项目目录下不可见,但是可以跳转进去查看)。这个自动生成的头文件是一个 Objective-C 头文件,声明了 target 中的一些 Swift 接口。可以将这个 Objective-C 头文件看作 Swift 代码的保护伞头文件。该头文件以产品模块名拼接上"-Swift.h"来命名。关于产品模块名的具体介绍,请参阅为产品模块命名小节。

默认情况下,这个头文件包含所有标记publicopen修饰符的 Swift 声明。如果 target 中有 Objective-C 桥接头文件的话,它还会包含标记internal修饰符的 Swift 声明。标记privatefileprivate修饰符的 Swift 声明不会出现在这个头文件中。私有声明不会暴露给 Objective-C,除非它们被标记@IBAction@IBOutlet@objc。如果应用程序的 target 启用了单元测试,在单元测试的 target 中导入应用程序的 target 时,在import语句前加上@testable特性,就可以在单元测试的 target 中访问应用程序的 target 中任何标记internal修饰符的声明,犹如它们标记了public修饰符一般。

关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

这个头文件会由 Xcode 自动生成,可直接导入到 Objective-C 代码中使用。注意,如果这个头文件中的 Swift 接口使用了自定义的 Objective-C 类型,在导入这个自动生成的头文件前,必须先将相关的自定义 Objective-C 类型对应的 Objective-C 头文件导入。

在 target 中将 Swift 代码导入到 Objective-C
  • 在 target 中的 Objective-C .m文件中,用如下语法导入 Swift 代码:
objective-c
#import "ProductModuleName-Swift.h" // 将 ProductModuleName 替换为产品模块名

target 中的一些 Swift 声明会暴露给包含这个导入语句的 Objective-C .m文件。关于如何在 Objective-C 中使用 Swift,请参阅在 Objective-C 中使用 Swift小节。

导入到 Swift导入到 Objective-C
Swift 代码不需要导入语句#import "ProductModuleName-Swift.h"
Objective-C 代码不需要导入语句;需要 Objective-C 桥接头文件#import "Header.h"

在框架 target 中导入代码

在编写基于混合语言的框架时,往往需要在 Swift 代码中访问 Objective-C 代码,或者反过来。

将 Objective-C 代码导入到 Swift

若要将 Objective-C 文件导入到 target 中的 Swift 代码中,需要将这些 Objective-C 文件导入到 Objective-C 的保护伞头文件中。

译者注
此处的“保护伞头文件”指的是带有框架版本号和版本字符串声明的那个头文件。

在 target 中将 Objective-C 代码导入到 Swift
  1. 确保将 target 的Build Settings > Packaging > Defines Module设置为Yes

  2. 在保护伞头文件中导入希望暴露给 Swift 的 Objective-C 头文件。例如:

objective-c
#import <XYZ/XYZCustomCell.h>
+#import <XYZ/XYZCustomView.h>
+#import <XYZ/XYZCustomViewController.h>

保护伞头文件中导入的 Objective-C 头文件都会暴露给 Swift。target 中所有 Swift 文件都可以使用这些 Objective-C 头文件中的内容,不需要任何导入语句。不但如此,你还能用 Swift 语法使用这些自定义的 Objective-C 代码,就像使用系统的 Swift 类一样。

swift
let myOtherCell = XYZCustomCell()
+myOtherCell.subtitle = "Another custom cell"

将 Swift 代码导入到 Objective-C

若要将 Swift 文件导入到 target 中的 Objective-C 代码中,不需要导入任何东西到保护伞头文件,只需将 Xcode 为 Swift 代码自动生成的头文件导入到要使用 Swift 代码的 Objective-C .m文件。

由于这个自动生成的头文件是框架公共接口的一部分,因此只有标记publicopen修饰符的 Swift 声明才会出现在这个自动生成的头文件中。

对于继承自 Objective-C 类的 Swift 子类中标记internal修饰符的方法和属性,它们只会暴露给 Objective-C 运行时系统,这意味着它们不会出现在 Swift 代码的头文件中,也无法在编译期访问它们。

译者注
使用这些标记internal的 Swift 声明时,编译器会报错提示符号未定义,研究了一下发现可以采取如下方式解决:

swift
// Swift 代码部分
+@objc(Foo) 
+class Foo: NSObject {
+    func hello() { print("Hello!") }
+}
objective-c
// Objective-C 代码部分
+// 为了解决符号未定义的错误,手动写个接口声明,注意 Swift 代码中的 @objc(Foo),否则会导致类名不匹配
+@interface Foo : NSObject
+- (void)hello;
+@end

关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

在 target 中将 Swift 代码导入到 Objective-C
  1. 确保将 target 的Build Settings > Packaging > Defines Module设置为Yes

  2. 使用如下语法将 Swift 代码导入到 target 中的 Objective-C .m文件:

objective-c
// 分别用产品名和产品模块名替换 ProductName 和 ProductModuleName
+#import <ProductName/ProductModuleName-Swift.h>

target 中的一些 Swift 声明会暴露给包含这个导入语句的 Objective-C .m文件。关于如何在 Objective-C 中使用 Swift,请参阅在 Objective-C 中使用 Swift小节。

导入到 Swift导入到 Objective-C
Swift 代码不需要导入语句#import <ProductName/ProductModuleName-Swift.h>
Objective-C 代码不需要导入语句;需要 Objective-C 保护伞头文件#import "Header.h"

导入外部框架

你可以导入位于其他 target 中的外部框架,无论它是基于 Objective-C,Swift,还是基于混合语言的。导入流程都是一样的,只需确保被导入框架的Build Setting > Pakaging > Defines Module设置为Yes

使用如下语法将外部框架导入到 Swift 文件:

swift
import FrameworkName

使用如下语法将外部框架导入到 Objective-C .m文件:

objective-c
@import FrameworkName;
导入到 Swift导入到 Objective-C
任意语言框架import FrameworkName@import FrameworkName;

在 Objective-C 中使用 Swift

将 Swift 代码导入到 Objective-C 后,就可用标准 Objective-C 语法使用 Swift 类。

objective-c
MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
+[swiftObject swiftMethod];

只有继承自 Objective-C 类的 Swift 类才能在 Objective-C 中使用。想要了解 Swift 如何将接口导入到 Objective-C 以及在 Objective-C 中能使用哪些 Swift 特性,请参阅Swift 类型兼容性小节。

在 Objective-C 头文件中引用 Swift 类或协议

为避免循环引用,不要将 Swift 代码导入到 Objective-C 头文件(.h文件),而应该使用前向声明来引用一个 Swift 类或者协议。

objective-c
// MyObjcClass.h
+@class MySwiftClass;
+@protocol MySwiftProtocol;
+
+@interface MyObjcClass : NSObject
+- (MySwiftClass *)returnSwiftClassInstance;
+- (id <MySwiftProtocol>)returnInstanceAdoptingSwiftProtocol;
+// ...
+@end

Swift 类和协议的前向声明只能用于声明方法和属性。

声明可被 Objective-C 类遵守的 Swift 协议

将 Swift 协议标记@objc特性,从而让 Objective-C 类可以遵守该协议。

swift
@objc public protocol MySwiftProtocol {
+    func requiredMethod()
+
+    @objc optional func optionalMethod()
+}

为了遵守协议,Objective-C 类必须实现协议中声明的所有构造器,属性,下标,方法。可选的协议要求必须标记@objc特性和optional修饰符。

在 Objective-C 的实现文件中采用 Swift 协议

Objective-C 类可以在实现文件(.m文件)中导入 Xcode 自动生成的 Swift 头文件,然后使用类扩展来采用 Swift 协议。

objective-c
// MyObjcClass.m
+#import "ProductModuleName-Swift.h"
+     
+@interface MyObjcClass () <MySwiftProtocol>
+// ...
+@end
+     
+@implementation MyObjcClass
+// ...
+@end

声明可在 Objective-C 中使用的 Swift 错误类型

遵守Error协议并标记@objc特性的 Swift 枚举会在 Swift 头文件中生成一个NS_ENUM枚举声明,并会为错误域生成相应的NSString字符串常量。例如,有如下 Swift 枚举声明:

swift
@objc public enum CustomError: Int, Error {
+    case a, b, c
+}

Swift 头文件中相应的 Objective-C 声明如下所示:

objective-c
// Project-Swift.h
+typedef SWIFT_ENUM(NSInteger, CustomError) {
+    CustomErrorA = 0,
+    CustomErrorB = 1,
+    CustomErrorC = 2,
+};
+static NSString * const CustomErrorDomain = @"Project.CustomError";

为 Objective-C 接口提供 Swift 命名

Swift 编译器自动将 Objective-C 代码作为常规 Swift 代码导入,它将 Objective-C 类工厂方法导入为 Swift 构造器,还会缩短 Objective-C 枚举值的命名。

代码中也许会存在无法自动处理的特殊情况。对于 Objective-C 方法,枚举值,或者选项集的值,可以使用NS_SWIFT_NAME宏来自定义它们导入到 Swift 后的命名。

类工厂方法

如果 Swift 编译器无法识别类工厂方法,可以使用NS_SWIFT_NAME宏来指定类工厂方法导入为 Swift 构造器后的方法名,从而能够将其正确导入。例如:

objective-c
+ (instancetype)recordWithRPM:(NSUInteger)RPM NS_SWIFT_NAME(init(RPM:));

如果 Swift 编译器错误地将一个普通的类方法识别为类工厂方法,可以使用NS_SWIFT_NAME宏来指定类方法导入为 Swift 类方法后的方法名,从而能够将其正确导入。例如:

objective-c
+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));

枚举

默认情况下,Swift 导入枚举时,会将枚举值的名称前缀截断。如果需要自定义枚举值的名称,可以使用NS_SWIFT_NAME宏来指定枚举值导入到 Swift 后的命名。例如:

objective-c
typedef NS_ENUM(NSInteger, ABCRecordSide) {
+    ABCRecordSideA,
+    ABCRecordSideB NS_SWIFT_NAME(FlipSide),
+};

让 Objective-C 接口在 Swift 中不可用

一些 Objective-C 接口可能不适合或者没必要暴露给 Swift,为了防止 Objective-C 接口导入到 Swift,可以使用NS_SWIFT_UNAVAILABLE宏来传达一个提示信息,从而指引 API 使用者使用其他替代方式。

例如,一个 Objective-C 类提供了一个接收一些键值对作为可变参数的便利构造器,可以建议 Swift 用户使用字典字面量作为替代:

objective-c
+ (instancetype)collectionWithValues:(NSArray *)values 
+                             forKeys:(NSArray<NSCopying> *)keys NS_SWIFT_UNAVAILABLE("使用字典字面量替代");

试图在 Swift 中调用+collectionWithValues:forKeys:方法将导致编译错误。

优化 Objective-C 声明

可以使用NS_REFINED_FOR_SWIFT宏标记 Objective-C 方法的声明,然后在 Swift 中通过扩展提供一个优雅的 Swift 接口,通过该接口去调用方法的原始实现。例如,接收一个或者多个指针参数的 Objective-C 方法可以优化为一个返回元组值的 Swift 方法。使用该宏标记的方法导入到 Swift 后会做如下处理:

  • 对于初始化方法,在第一个外部参数名前加双下划线(__)。
  • 对于对象下标方法,只要设值或取值方法被标记NS_REFINED_FOR_SWIFT宏,这对下标方法就会变为 Swift 中的普通方法。被标记宏的下标方法会在方法名前加双下划线(__)。
  • 对于其他方法,在方法名前加双下划线(__)。

思考如下 Objective-C 声明:

objective-c
@interface Color : NSObject
+
+- (void)getRed:(nullable CGFloat *)red
+         green:(nullable CGFloat *)green
+          blue:(nullable CGFloat *)blue
+         alpha:(nullable CGFloat *)alpha NS_REFINED_FOR_SWIFT;
+         
+@end

可以通过 Swift 扩展来提供一个优化后的接口:

swift
extension Color {
+    var RGBA: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
+        var r: CGFloat = 0.0
+        var g: CGFloat = 0.0
+        var b: CGFloat = 0.0
+        var a: CGFloat = 0.0
+        __getRed(&r, green: &g, blue: &b, alpha: &a)
+        return (red: r, green: g, blue: b, alpha: a)
+    }
+}

将可用性信息添加到 Objective-C API

在 Swift 中为特定平台编译应用时,你可以使用 @available 特性来控制一个声明是否可用。同样,你可以使用可用性条件 #available 根据所需平台和版本有条件地执行代码。

两种可用性说明符在 Objective-C 中都有提供,使用以下示例中展示的相应语法即可。

如下示例展示了如何为 Swift 声明添加可用性信息:

swift
@available(iOS 11, macOS 10.13, *)
+func newMethod() {
+    // 使用 iOS 11 API
+}

如下示例展示了如何在 Objective-C 中添加相同的可用性信息:

objective-c
@interface MyViewController : UIViewController
+- (void) newMethod API_AVAILABLE(ios(11), macosx(10.13));
+@end

如下示例展示了如何在 Swift 条件语句中使用可用性信息:

swift
if #available(iOS 11, *) {
+    // 使用 iOS 11 API
+} else {
+    // 早期版本的 iOS 的替代代码
+}

如下示例展示了如何在 Objective-C 中使用相同的可用性信息:

objective-c
if (@available(iOS 11, *)) {
+    // 使用 iOS 11 API
+} else {
+    // 早期版本的 iOS 的替代代码
+}

关于指定平台可用性的更多信息,请参阅 The Swift Programming Language 中文版 中的声明特性部分。

为产品模块命名

无论是 Xcode 为 Swift 代码自动生成的头文件,还是 Objective-C 桥接头文件,都会根据产品模块名来命名。默认情况下,产品模块名和产品名一样。然而,如果产品名包含特殊字符(只能是字母、数字、下划线),例如点号(.),作为产品模块名时,这些特殊字符会被下划线(_)替换。如果产品名以数字开头,作为产品模块名时,第一个数字也会被下划线替换。

也可以为产品模块名提供一个自定义的名称,Xcode 会根据这个名称来命名桥接头文件和自动生成的头文件,只需修改Build setting > Packaging > Product Module Name中的名称即可。

注意
无法改变框架的产品模块名。

故障排除贴士

  • 将 Swift 和 Objective-C 文件看作同一代码集,注意命名冲突。

  • 如果使用框架,确保框架的Build setting > Packaging > Defines ModuleDEFINES_MODULE)设置为Yes

  • 如果使用 Objective-C 桥接头文件,确保Build setting > Swift Compiler > Code GenerationSWIFT_OBJC_BRIDGING_HEADER)中的头文件路径是头文件自身相对于项目的路径,例如MyApp/MyApp-Bridging-Header.h

  • Xcode 会根据产品模块名(PRODUCT_MODULE_NAME),而不是 target 的名称(TARGET_NAME)来命名 Objective-C 桥接头文件以及为 Swift 代码自动生成的头文件。详情请参阅为产品模块命名小节。

  • 只有继承自 Objective-C 类的 Swift 类,以及标记了@objc(包括各种被隐式标记的情况)的 Swift 声明,才能在 Objective-C 中使用。

  • 将 Swift 代码导入到 Objective-C 时,注意 Objective-C 无法转化 Swift 的独有特性。详情请参阅在 Objective-C 中使用 Swift小节。

  • 如果在 Swift 代码中使用了自定义的 Objective-C 类型,在 Objective-C 中使用这部分 Swift 代码时,确保先导入相关的 Objective-C 类型的头文件,然后再将 Xcode 为 Swift 代码自动生成的头文件导入。

  • 标记privatefileprivate修饰符的 Swift 声明不会出现在自动生成的头文件中,因为私有声明不会暴露给 Objective-C,除非它们被标记@IBAction@IBOutlet或者@objc

  • 对于应用程序的 target,当存在 Objective-C 桥接头文件时,标记internal修饰符的 Swift 声明也会出现在自动生成的头文件中。

  • 对于框架的 target,只有标记publicopen修饰符的声明才会出现在自动生成的头文件中,不过依然可以在框架内部的 Objective-C 代码中使用标记internal修饰符的 Swift API,只要它们所属的类继承自 Objective-C 类。关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

`,142)]))}const b=s(h,[["render",p]]);export{E as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.lean.js b/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.lean.js new file mode 100644 index 0000000..d1cf008 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_03-Mix and Match_Swift and Objective-C in the Same Project.md.B8DxxDli.lean.js @@ -0,0 +1 @@ +import{_ as s,c as a,o as t,ag as e}from"./chunks/framework.BHpayLOB.js";const n="/assets/DAG_2x.NtzGJ5bn.png",l="/assets/bridgingheader_2x.CFOipoi_.png",E=JSON.parse('{"title":"在项目中同时使用 Swift 和 Objective-C","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md","filePath":"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md"}'),h={name:"frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md"};function p(k,i,c,r,d,o){return t(),a("div",null,i[0]||(i[0]=[e("",142)]))}const b=s(h,[["render",p]]);export{E as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.js b/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.js new file mode 100644 index 0000000..3130bda --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.js @@ -0,0 +1,5 @@ +import{_ as i,c as t,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"迁移 Objective-C 代码到 Swift","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md","filePath":"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md"}'),r={name:"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md"};function c(l,e,n,s,p,d){return a(),t("div",null,e[0]||(e[0]=[o(`

迁移 Objective-C 代码到 Swift

迁移工作提供了一个重新审视现有的 Objective-C 应用程序的机会,通过用 Swift 代码替换 Objective-C 代码来改善程序的架构,逻辑以及性能。简而言之,通过之前学习的工具,即混搭和互用来对应用程序进行增量迁移。在决定哪些特性和功能用 Swift 实现,哪些依然用 Objective-C 实现时,混搭和互用会让这一切变得简单可行。通过这些工具,可以一步步探索 Swift 广泛的功能并整合到现有的 Objective-C 应用程序中,而不必立刻使用 Swift 重写整个应用程序。

为 Objective-C 代码做好迁移准备

在开始迁移代码之前,请确保 Objective-C 和 Swift 代码间有着最佳兼容性。这意味着你可能需要整理现有项目,并将 Objective-C 现代化特性应用其中。为了更好地与 Swift 无缝交互,现有的 Objective-C 代码需要遵循现代编码实践。在开始前,这有个简短的实践列表,请参阅 Adopting Mordern Objective-C

迁移过程

迁移代码到 Swift 的最有效的方式是逐个文件迁移,即一次迁移一个类。由于无法在 Objective-C 中继承 Swift 类,因此最好选择一个没有子类的类开始。使用单个.swift文件替换对应的.m.h文件,实现和接口将直接放进这个 Swift 文件。你也不用创建头文件,Xcode 会在你需要引用头文件的时候自动生成头文件。

准备迁移

  • 在 Xcode 中,选择File > New > File > (iOS,watchOS,tvOS,macOS) > Source > Swift File为对应的 Objective-C .m.h文件创建一个 Swift 类。可以使用相同或者不同的类名。类前缀在 Swift 中不是必须的。

  • 导入相关的系统框架。

  • 如果需要在 Swift 文件中使用同一 target 中的 Objective-C 代码,可以填写一个 Objective-C 桥接头文件。具体的操作步骤,请参阅在应用程序的 target 中导入代码小节。

  • 为了让 Swift 类能在 Objective-C 中使用,Swift 类必须继承自 Objective-C 类。如果想为 Swift 类指定在 Objective-C 中的类名,可以使用@objc(name)特性,name就是 Swift 类在 Objective-C 中的类名。关于@objc的更多信息,请参阅Swift 类型兼容性小节。

开始迁移

  • 使用 Cocoa 设计模式的时候,请参阅采用 Cocoa 设计模式章节。

  • 对于如何将属性从 Objective-C 转换到 Swift,请参阅 The Swift Programming Language 中文版 中的属性章节。

  • 在需要的时候,使用@objc(name)特性为 Swift 中的属性或方法提供 Objective-C 命名。例如,可以像下面这样将enabled属性的取值方法在 Objective-C 中的命名更改为isEnabled

    swift
    var enabled: Bool {
    +	@objc(isEnabled) get {
    +		// ...
    +	}
    +}
  • 分别用funcclass func来声明实例方法(-)和类方法(+)。

  • 将简单宏声明为全局常量,将复杂宏声明为函数。

完成迁移

  • 将 Objective-C 代码中对应的导入语句更改为#import "ProductModuleName-Swift.h",更多信息请参阅在应用程序的 target 中导入代码小节。

  • 将原始的 Objective-C .m文件在Target Membership选择框中的勾选取消,从而将其从 target 中移除。不要立刻删除.m.h文件,以备解决问题时使用。

  • 如果为 Swift 类起了一个新的类名,在相关代码中请使用新的 Swift 类名代替原来的 Objective-C 类名。

故障排除贴士

尽管对于不同的项目,迁移过程是不尽相同的,但仍有一些通用的办法能解决代码迁移时遇到的问题:

  • 无法在 Objective-C 中继承 Swift 类。因此,被迁移的类不能有任何 Objective-C 子类。

  • 迁移一个类到 Swift 时,必须从 target 中移除相关的.m文件,避免编译时出现符号重复的错误。

  • 为了能在 Objective-C 中使用,Swift 类必须是一个 Objective-C 类的子类。

  • 在将 Swift 代码导入 Objective-C 代码时,切记 Objective-C 不能转化某些 Swift 的独有特性。详细列表请参阅在 Objective-C 中使用 Swift小节。

  • 可以在 Objective-C 代码中通过Commond + 单击一个 Swift 类名的方式来查看 Xcode 为它自动生成的头文件。

  • 可以Option + 单击一个符号来查看它的详细信息,比如它的类型,特性以及文档注释等。

`,23)]))}const b=i(r,[["render",c]]);export{f as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.lean.js b/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.lean.js new file mode 100644 index 0000000..bee7105 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_04-Migration_Migrating Your Objective-C Code to Swift.md.3nq7zSnw.lean.js @@ -0,0 +1 @@ +import{_ as i,c as t,o as a,ag as o}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"迁移 Objective-C 代码到 Swift","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md","filePath":"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md"}'),r={name:"frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md"};function c(l,e,n,s,p,d){return a(),t("div",null,e[0]||(e[0]=[o("",23)]))}const b=i(r,[["render",c]]);export{f as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.js b/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.js new file mode 100644 index 0000000..29c4c6d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.js @@ -0,0 +1 @@ +import{_ as a,c as t,o as i,ag as r}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"目录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/index.md","filePath":"frontend/swift/index.md"}'),l={name:"frontend/swift/index.md"};function n(o,e,h,c,d,s){return i(),t("div",null,e[0]||(e[0]=[r('

目录

开始

交互

混搭

迁移

',10)]))}const b=a(l,[["render",n]]);export{u as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.lean.js b/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.lean.js new file mode 100644 index 0000000..2ead48d --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_swift_index.md.DLsK_7-d.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,o as i,ag as r}from"./chunks/framework.BHpayLOB.js";const u=JSON.parse('{"title":"目录","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/swift/index.md","filePath":"frontend/swift/index.md"}'),l={name:"frontend/swift/index.md"};function n(o,e,h,c,d,s){return i(),t("div",null,e[0]||(e[0]=[r("",10)]))}const b=a(l,[["render",n]]);export{u as __pageData,b as default}; diff --git a/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.js b/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.js new file mode 100644 index 0000000..ad88596 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.js @@ -0,0 +1 @@ +import{_ as t,c as n,o as r,j as e,a as o}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"vue 前端","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/vue/index.md","filePath":"frontend/vue/index.md"}'),d={name:"frontend/vue/index.md"};function s(i,a,c,l,u,f){return r(),n("div",null,a[0]||(a[0]=[e("h1",{id:"vue-前端",tabindex:"-1"},[o("vue 前端 "),e("a",{class:"header-anchor",href:"#vue-前端","aria-label":'Permalink to "vue 前端"'},"​")],-1),e("p",null,"待更新",-1)]))}const v=t(d,[["render",s]]);export{m as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.lean.js b/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.lean.js new file mode 100644 index 0000000..ad88596 --- /dev/null +++ b/docs/.vitepress/dist/assets/frontend_vue_index.md.CSegZYxX.lean.js @@ -0,0 +1 @@ +import{_ as t,c as n,o as r,j as e,a as o}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"vue 前端","description":"","frontmatter":{},"headers":[],"relativePath":"frontend/vue/index.md","filePath":"frontend/vue/index.md"}'),d={name:"frontend/vue/index.md"};function s(i,a,c,l,u,f){return r(),n("div",null,a[0]||(a[0]=[e("h1",{id:"vue-前端",tabindex:"-1"},[o("vue 前端 "),e("a",{class:"header-anchor",href:"#vue-前端","aria-label":'Permalink to "vue 前端"'},"​")],-1),e("p",null,"待更新",-1)]))}const v=t(d,[["render",s]]);export{m as __pageData,v as default}; diff --git a/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.js b/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.js new file mode 100644 index 0000000..7419226 --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.js @@ -0,0 +1 @@ +import{_ as t,c as o,o as r,j as a,a as s}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"关于本知识库","description":"","frontmatter":{},"headers":[],"relativePath":"guide/about.md","filePath":"guide/about.md"}'),n={name:"guide/about.md"};function d(i,e,c,l,u,p){return r(),o("div",null,e[0]||(e[0]=[a("h1",{id:"关于本知识库",tabindex:"-1"},[s("关于本知识库 "),a("a",{class:"header-anchor",href:"#关于本知识库","aria-label":'Permalink to "关于本知识库"'},"​")],-1)]))}const _=t(n,[["render",d]]);export{f as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.lean.js b/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.lean.js new file mode 100644 index 0000000..7419226 --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_about.md.C8JydTFK.lean.js @@ -0,0 +1 @@ +import{_ as t,c as o,o as r,j as a,a as s}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"关于本知识库","description":"","frontmatter":{},"headers":[],"relativePath":"guide/about.md","filePath":"guide/about.md"}'),n={name:"guide/about.md"};function d(i,e,c,l,u,p){return r(),o("div",null,e[0]||(e[0]=[a("h1",{id:"关于本知识库",tabindex:"-1"},[s("关于本知识库 "),a("a",{class:"header-anchor",href:"#关于本知识库","aria-label":'Permalink to "关于本知识库"'},"​")],-1)]))}const _=t(n,[["render",d]]);export{f as __pageData,_ as default}; diff --git a/docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.js b/docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.js similarity index 70% rename from docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.js rename to docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.js index 22d931f..730e543 100644 --- a/docs/.vitepress/dist/assets/api-examples.md.B__5zNjv.js +++ b/docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.js @@ -1,4 +1,4 @@ -import{u as p,c as h,o,ae as d,j as a,t,k as i,a as s}from"./chunks/framework.B8KKhRA6.js";const f=JSON.parse('{"title":"Runtime API Examples","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"api-examples.md","filePath":"api-examples.md"}'),m={name:"api-examples.md"},E=Object.assign(m,{setup(k){const{site:g,theme:n,page:l,frontmatter:r}=p();return(c,e)=>(o(),h("div",null,[e[0]||(e[0]=d(`

Runtime API Examples

This page demonstrates usage of some of the runtime APIs provided by VitePress.

The main useData() API can be used to access site, theme, and page data for the current page. It works in both .md and .vue files:

md
<script setup>
+import{u as p,c as h,o,ag as d,j as a,t,k as i,a as s}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"Runtime API Examples","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/api-examples.md","filePath":"guide/api-examples.md"}'),g={name:"guide/api-examples.md"},E=Object.assign(g,{setup(m){const{site:k,theme:n,page:l,frontmatter:r}=p();return(u,e)=>(o(),h("div",null,[e[0]||(e[0]=d(`

Runtime API Examples

This page demonstrates usage of some of the runtime APIs provided by VitePress.

The main useData() API can be used to access site, theme, and page data for the current page. It works in both .md and .vue files:

md
<script setup>
 import { useData } from 'vitepress'
 
 const { theme, page, frontmatter } = useData()
diff --git a/docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.lean.js b/docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.lean.js
new file mode 100644
index 0000000..8840845
--- /dev/null
+++ b/docs/.vitepress/dist/assets/guide_api-examples.md.DrTxPAI1.lean.js
@@ -0,0 +1 @@
+import{u as p,c as h,o,ag as d,j as a,t,k as i,a as s}from"./chunks/framework.BHpayLOB.js";const f=JSON.parse('{"title":"Runtime API Examples","description":"","frontmatter":{"outline":"deep"},"headers":[],"relativePath":"guide/api-examples.md","filePath":"guide/api-examples.md"}'),g={name:"guide/api-examples.md"},E=Object.assign(g,{setup(m){const{site:k,theme:n,page:l,frontmatter:r}=p();return(u,e)=>(o(),h("div",null,[e[0]||(e[0]=d("",6)),a("pre",null,t(i(n)),1),e[1]||(e[1]=a("h3",{id:"page-data",tabindex:"-1"},[s("Page Data "),a("a",{class:"header-anchor",href:"#page-data","aria-label":'Permalink to "Page Data"'},"​")],-1)),a("pre",null,t(i(l)),1),e[2]||(e[2]=a("h3",{id:"page-frontmatter",tabindex:"-1"},[s("Page Frontmatter "),a("a",{class:"header-anchor",href:"#page-frontmatter","aria-label":'Permalink to "Page Frontmatter"'},"​")],-1)),a("pre",null,t(i(r)),1),e[3]||(e[3]=a("h2",{id:"more",tabindex:"-1"},[s("More "),a("a",{class:"header-anchor",href:"#more","aria-label":'Permalink to "More"'},"​")],-1)),e[4]||(e[4]=a("p",null,[s("Check out the documentation for the "),a("a",{href:"https://vitepress.dev/reference/runtime-api#usedata",target:"_blank",rel:"noreferrer"},"full list of runtime APIs"),s(".")],-1))]))}});export{f as __pageData,E as default};
diff --git a/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.js b/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.js
new file mode 100644
index 0000000..7206ad2
--- /dev/null
+++ b/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.js
@@ -0,0 +1 @@
+import{_ as r,c as t,o as n,j as a,a as d}from"./chunks/framework.BHpayLOB.js";const x=JSON.parse('{"title":"markdown 语法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),o={name:"guide/index.md"};function i(s,e,c,m,l,p){return n(),t("div",null,e[0]||(e[0]=[a("h1",{id:"markdown-语法",tabindex:"-1"},[d("markdown 语法 "),a("a",{class:"header-anchor",href:"#markdown-语法","aria-label":'Permalink to "markdown 语法"'},"​")],-1)]))}const _=r(o,[["render",i]]);export{x as __pageData,_ as default};
diff --git a/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.lean.js b/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.lean.js
new file mode 100644
index 0000000..7206ad2
--- /dev/null
+++ b/docs/.vitepress/dist/assets/guide_index.md.jxbnF1tf.lean.js
@@ -0,0 +1 @@
+import{_ as r,c as t,o as n,j as a,a as d}from"./chunks/framework.BHpayLOB.js";const x=JSON.parse('{"title":"markdown 语法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),o={name:"guide/index.md"};function i(s,e,c,m,l,p){return n(),t("div",null,e[0]||(e[0]=[a("h1",{id:"markdown-语法",tabindex:"-1"},[d("markdown 语法 "),a("a",{class:"header-anchor",href:"#markdown-语法","aria-label":'Permalink to "markdown 语法"'},"​")],-1)]))}const _=r(o,[["render",i]]);export{x as __pageData,_ as default};
diff --git a/docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.js b/docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.js
similarity index 69%
rename from docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.js
rename to docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.js
index 7c62374..6af2d07 100644
--- a/docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.js
+++ b/docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.js
@@ -1,8 +1,8 @@
-import{_ as a,c as i,o as n,ae as e}from"./chunks/framework.B8KKhRA6.js";const E=JSON.parse('{"title":"Markdown Extension Examples","description":"","frontmatter":{},"headers":[],"relativePath":"markdown-examples.md","filePath":"markdown-examples.md"}'),t={name:"markdown-examples.md"};function l(p,s,h,k,r,o){return n(),i("div",null,s[0]||(s[0]=[e(`

Markdown Extension Examples

This page demonstrates some of the built-in markdown extensions provided by VitePress.

Syntax Highlighting

VitePress provides Syntax Highlighting powered by Shiki, with additional features like line-highlighting:

Input

md
\`\`\`js{4}
-export default {
-  data () {
-    return {
-      msg: 'Highlighted!'
+import{_ as a,c as i,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const E=JSON.parse('{"title":"Markdown Extension Examples","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown-examples.md","filePath":"guide/markdown-examples.md"}'),e={name:"guide/markdown-examples.md"};function l(p,s,h,k,r,d){return n(),i("div",null,s[0]||(s[0]=[t(`

Markdown Extension Examples

This page demonstrates some of the built-in markdown extensions provided by VitePress.

Syntax Highlighting

VitePress provides Syntax Highlighting powered by Shiki, with additional features like line-highlighting:

Input

md
\`\`\`js{4}
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
     }
   }
 }
@@ -30,4 +30,4 @@ import{_ as a,c as i,o as n,ae as e}from"./chunks/framework.B8KKhRA6.js";const E
 
 ::: details
 This is a details block.
-:::

Output

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

More

Check out the documentation for the full list of markdown extensions.

`,19)]))}const c=a(t,[["render",l]]);export{E as __pageData,c as default}; +:::

Output

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

More

Check out the documentation for the full list of markdown extensions.

`,19)]))}const c=a(e,[["render",l]]);export{E as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.lean.js b/docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.lean.js new file mode 100644 index 0000000..55ef15f --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_markdown-examples.md.DaMNxmUN.lean.js @@ -0,0 +1 @@ +import{_ as a,c as i,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const E=JSON.parse('{"title":"Markdown Extension Examples","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown-examples.md","filePath":"guide/markdown-examples.md"}'),e={name:"guide/markdown-examples.md"};function l(p,s,h,k,r,d){return n(),i("div",null,s[0]||(s[0]=[t("",19)]))}const c=a(e,[["render",l]]);export{E as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.js b/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.js new file mode 100644 index 0000000..dab5dea --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.js @@ -0,0 +1,361 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const c=JSON.parse('{"title":"Markdown 扩展","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown-extension.md","filePath":"guide/markdown-extension.md"}'),l={name:"guide/markdown-extension.md"};function e(p,s,h,k,d,r){return n(),a("div",null,s[0]||(s[0]=[t(`

Markdown 扩展

VitePress 带有内置的 Markdown 扩展。

标题锚点

标题会自动应用锚点。可以使用 markdown.anchor 选项配置锚点的渲染。

自定义锚点

要为标题指定自定义锚点而不是使用自动生成的锚点,请向标题添加后缀:

# 使用自定义锚点 {#my-anchor}

这允许将标题链接为 #my-anchor,而不是默认的 #使用自定义锚点

内部和外部链接都会被特殊处理。

内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 index.md 都会自动转换为 index.html,并带有相应的 URL /

例如,给定以下目录结构:

.
+├─ index.md
+├─ foo
+│  ├─ index.md
+│  ├─ one.md
+│  └─ two.md
+└─ bar
+   ├─ index.md
+   ├─ three.md
+   └─ four.md

假设现在处于 foo/one.md 文件中:

md
[Home](/) <!-- 将用户导航至根目录下的 index.html -->
+[foo](/foo/) <!-- 将用户导航至目录 foo 下的 index.html -->
+[foo heading](./#heading) <!-- 将用户锚定到目录 foo 下的index文件中的一个标题上 -->
+[bar - three](../bar/three) <!-- 可以省略扩展名 -->
+[bar - three](../bar/three.md) <!-- 可以添加 .md -->
+[bar - four](../bar/four.html) <!-- 或者可以添加 .html -->

页面后缀

默认情况下,生成的页面和内部链接带有 .html 后缀。

外部链接带有 target="_blank" rel="noreferrer"

frontmatter

YAML 格式的 frontmatter 开箱即用:

yaml
---
+title: Blogging Like a Hacker
+lang: en-US
+---

此数据将可用于页面的其余部分,以及所有自定义和主题组件。

GitHub 风格的表格

输入

| Tables        |      Are      |  Cool |
+| ------------- | :-----------: | ----: |
+| col 3 is      | right-aligned | $1600 |
+| col 2 is      |   centered    |   $12 |
+| zebra stripes |   are neat    |    $1 |

输出

TablesAreCool
col 3 isright-aligned$1600
col 2 iscentered$12
zebra stripesare neat$1

Emoji 🎉

输入

:tada: :100:

输出

🎉 💯

这里可以找到所有支持的 emoji 列表

目录表 (TOC)

输入

[[toc]]

输出

可以使用 markdown.toc 选项配置 TOC 的呈现效果。

自定义容器

自定义容器可以通过它们的类型、标题和内容来定义。

默认标题

输入

md
::: info
+This is an info box.
+:::
+
+::: tip
+This is a tip.
+:::
+
+::: warning
+This is a warning.
+:::
+
+::: danger
+This is a dangerous warning.
+:::
+
+::: details
+This is a details block.
+:::

输出

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

自定义标题

可以通过在容器的 "type" 之后附加文本来设置自定义标题。

输入

md
::: danger STOP
+危险区域,请勿继续
+:::
+
+::: details 点我查看代码
+\`\`\`js
+console.log('Hello, VitePress!')
+\`\`\`
+:::

输出

STOP

危险区域,请勿继续

点我查看代码
js
console.log('Hello, VitePress!')

此外,可以通过在站点配置中添加以下内容来全局设置自定义标题,如果不是用英语书写,这会很有帮助:

ts
// config.ts
+export default defineConfig({
+  // ...
+  markdown: {
+    container: {
+      tipLabel: '提示',
+      warningLabel: '警告',
+      dangerLabel: '危险',
+      infoLabel: '信息',
+      detailsLabel: '详细信息'
+    }
+  }
+  // ...
+})

raw

这是一个特殊的容器,可以用来防止与 VitePress 的样式和路由冲突。这在记录组件库时特别有用。可能还想查看 whyframe 以获得更好的隔离。

语法

md
::: raw
+Wraps in a \`<div class="vp-raw">\`
+:::

vp-raw class 也可以直接用于元素。样式隔离目前是可选的:

  • 使用喜欢的包管理器来安装需要的依赖项:

    sh
    $ npm add -D postcss
  • 创建 docs/postcss.config.mjs 文件并将以下内容添加到其中:

    js
    import { postcssIsolateStyles } from 'vitepress'
    +
    +export default {
    +  plugins: [postcssIsolateStyles()]
    +}

    它在底层使用 postcss-prefix-selector。你可以像这样传递它的选项:

    js
    postcssIsolateStyles({
    +  includeFiles: [/vp-doc\\.css/] // 默认为 /base\\.css/
    +})

GitHub 风格的警报

VitePress 同样支持以标注的方式渲染 GitHub 风格的警报。它们和自定义容器的渲染方式相同。

md
> [!NOTE]
+> 强调用户在快速浏览文档时也不应忽略的重要信息。
+
+> [!TIP]
+> 有助于用户更顺利达成目标的建议性信息。
+
+> [!IMPORTANT]
+> 对用户达成目标至关重要的信息。
+
+> [!WARNING]
+> 因为可能存在风险,所以需要用户立即关注的关键内容。
+
+> [!CAUTION]
+> 行为可能带来的负面影响。

NOTE

强调用户在快速浏览文档时也不应忽略的重要信息。

TIP

有助于用户更顺利达成目标的建议性信息。

IMPORTANT

对用户达成目标至关重要的信息。

WARNING

因为可能存在风险,所以需要用户立即关注的关键内容。

CAUTION

行为可能带来的负面影响。

代码块中的语法高亮

VitePress 使用 Shiki 在 Markdown 代码块中使用彩色文本实现语法高亮。Shiki 支持多种编程语言。需要做的就是将有效的语言别名附加到代码块的开头:

输入

\`\`\`js
+export default {
+  name: 'MyComponent',
+  // ...
+}
+\`\`\`
\`\`\`html
+<ul>
+  <li v-for="todo in todos" :key="todo.id">
+    {{ todo.text }}
+  </li>
+</ul>
+\`\`\`

输出

js
export default {
+  name: 'MyComponent'
+  // ...
+}
html
<ul>
+  <li v-for="todo in todos" :key="todo.id">
+    {{ todo.text }}
+  </li>
+</ul>

在 Shiki 的代码仓库中,可以找到合法的编程语言列表

在代码块中实现行高亮

输入

\`\`\`js{4}
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}
+\`\`\`

输出

js
export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}

除了单行之外,还可以指定多个单行、多行,或两者均指定:

  • 多行:例如 {5-8}{3-10}{10-17}
  • 多个单行:例如 {4,7,9}
  • 多行与单行:例如 {4,7-13,16,23-27,40}

输入

\`\`\`js{1,4,6-8}
+export default { // Highlighted
+  data () {
+    return {
+      msg: \`Highlighted!
+      This line isn't highlighted,
+      but this and the next 2 are.\`,
+      motd: 'VitePress is awesome',
+      lorem: 'ipsum'
+    }
+  }
+}
+\`\`\`

输出

js
export default { // Highlighted
+  data () {
+    return {
+      msg: \`Highlighted!
+      This line isn't highlighted,
+      but this and the next 2 are.\`,
+      motd: 'VitePress is awesome',
+      lorem: 'ipsum',
+    }
+  }
+}

也可以使用 // [!code highlight] 注释实现行高亮。

输入

\`\`\`js
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!' // [!!code highlight]
+    }
+  }
+}
+\`\`\`

输出

js
export default {
+  data() {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}

代码块中聚焦

在某一行上添加 // [!code focus] 注释将聚焦它并模糊代码的其他部分。

此外,可以使用 // [!code focus:<lines>] 定义要聚焦的行数。

输入

\`\`\`js
+export default {
+  data () {
+    return {
+      msg: 'Focused!' // [!!code focus]
+    }
+  }
+}
+\`\`\`

输出

js
export default {
+  data() {
+    return {
+      msg: 'Focused!'
+    }
+  }
+}

代码块中的颜色差异

在某一行添加 // [!code --]// [!code ++] 注释将会为该行创建 diff,同时保留代码块的颜色。

输入

\`\`\`js
+export default {
+  data () {
+    return {
+      msg: 'Removed' // [!!code --]
+      msg: 'Added' // [!!code ++]
+    }
+  }
+}
+\`\`\`

输出

js
export default {
+  data () {
+    return {
+      msg: 'Removed'
+      msg: 'Added'
+    }
+  }
+}

高亮“错误”和“警告”

在某一行添加 // [!code warning]// [!code error] 注释将会为该行相应的着色。

输入

\`\`\`js
+export default {
+  data () {
+    return {
+      msg: 'Error', // [!!code error]
+      msg: 'Warning' // [!!code warning]
+    }
+  }
+}
+\`\`\`

输出

js
export default {
+  data() {
+    return {
+      msg: 'Error', 
+      msg: 'Warning'
+    }
+  }
+}

行号

可以通过以下配置为每个代码块启用行号:

js
export default {
+  markdown: {
+    lineNumbers: true
+  }
+}

可以在代码块中添加 :line-numbers / :no-line-numbers 标记来覆盖在配置中的设置。

还可以通过在 :line-numbers 之后添加 = 来自定义起始行号,例如 :line-numbers=2 表示代码块中的行号从 2 开始。

输入

md
\`\`\`ts {1}
+// 默认禁用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
+\`\`\`
+
+\`\`\`ts:line-numbers {1}
+// 启用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
+\`\`\`
+
+\`\`\`ts:line-numbers=2 {1}
+// 行号已启用,并从 2 开始
+const line3 = 'This is line 3'
+const line4 = 'This is line 4'
+\`\`\`

输出

ts
// 默认禁用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
ts
// 启用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
ts
// 行号已启用,并从 2 开始
+const line3 = 'This is line 3'
+const line4 = 'This is line 4'

导入代码片段

可以通过下面的语法来从现有文件中导入代码片段:

md
<<< @/filepath

此语法同时支持行高亮

md
<<< @/filepath{highlightLines}

输入

md
<<< @/snippets/snippet.js{2}

Code file

js
export default function () {
+  // ..
+}

输出

js
export default function () {
+  // ..
+}

TIP

@ 的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 srcDir。或者也可以从相对路径导入:

md
<<< ../snippets/snippet.js

也可以使用 VS Code region 来只包含代码文件的相应部分。可以在文件目录后面的 # 符号后提供一个自定义的区域名:

输入

md
<<< @/snippets/snippet-with-region.js#snippet{1}

Code file

js
// #region snippet
+function foo() {
+  // ..
+}
+// #endregion snippet
+
+export default foo

输出

js
function foo() {
+  // ..
+}

也可以像这样在大括号内({})指定语言:

md
<<< @/snippets/snippet.cs{c#}
+
+<!-- 带行高亮: -->
+
+<<< @/snippets/snippet.cs{1,2,4-6 c#}
+
+<!-- 带行号: -->
+
+<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers}

如果无法从文件扩展名推测出源语言,这将会很有帮助

代码组

可以像这样对多个代码块进行分组:

输入

md
::: code-group
+
+\`\`\`js [config.js]
+/**
+ * @type {import('vitepress').UserConfig}
+ */
+const config = {
+  // ...
+}
+
+export default config
+\`\`\`
+
+\`\`\`ts [config.ts]
+import type { UserConfig } from 'vitepress'
+
+const config: UserConfig = {
+  // ...
+}
+
+export default config
+\`\`\`
+
+:::

输出

js
/**
+ * @type {import('vitepress').UserConfig}
+ */
+const config = {
+  // ...
+}
+
+export default config
ts
import type { UserConfig } from 'vitepress'
+
+const config: UserConfig = {
+  // ...
+}
+
+export default config

也可以在代码组中导入代码片段

输入

md
::: code-group
+
+<!-- 文件名默认用作标题 -->
+
+<<< @/snippets/snippet.js
+
+<!-- 也可以提供定制的代码组 -->
+
+<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
+
+:::

输出

js
export default function () {
+  // ..
+}
ts
function foo() {
+  // ..
+}

包含 markdown 文件

可以像这样在一个 markdown 文件中包含另一个 markdown 文件,甚至是内嵌的。

TIP

也可以使用 @,它的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 srcDir

例如,可以这样用相对路径包含 Markdown 文件:

输入

md
# Docs
+
+## Basics
+
+<!--@include: ./parts/basics.md-->

Part file (parts/basics.md)

md
Some getting started stuff.
+
+### Configuration
+
+Can be created using \`.foorc.json\`.

等价代码

md
# Docs
+
+## Basics
+
+Some getting started stuff.
+
+### Configuration
+
+Can be created using \`.foorc.json\`.

它还支持选择行范围:

输入

md
# Docs
+
+## Basics
+
+<!--@include: ./parts/basics.md{3,}-->

Part file (parts/basics.md)

md
Some getting started stuff.
+
+### Configuration
+
+Can be created using \`.foorc.json\`.

等价代码

md
# Docs
+
+## Basics
+
+### Configuration
+
+Can be created using \`.foorc.json\`.

所选行范围的格式可以是: {3,}{,10}{1,10}

WARNING

如果指定的文件不存在,这将不会产生错误。因此,在使用这个功能的时候请保证内容按预期呈现。

数学方程

现在这是可选的。要启用它,需要安装 markdown-it-mathjax3,在配置文件中设置markdown.mathtrue

sh
npm add -D markdown-it-mathjax3
ts
export default {
+  markdown: {
+    math: true
+  }
+}

输入

md
When $a \\ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
+$$ x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a} $$
+
+**Maxwell's equations:**
+
+| equation                                                                                                                                                                  | description                                                                            |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
+| $\\nabla \\cdot \\vec{\\mathbf{B}}  = 0$                                                                                                                                      | divergence of $\\vec{\\mathbf{B}}$ is zero                                               |
+| $\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t}  = \\vec{\\mathbf{0}}$                                                          | curl of $\\vec{\\mathbf{E}}$ is proportional to the rate of change of $\\vec{\\mathbf{B}}$ |
+| $\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} = \\frac{4\\pi}{c}\\vec{\\mathbf{j}}    \\nabla \\cdot \\vec{\\mathbf{E}} = 4 \\pi \\rho$ | _wha?_                                                                                 |

输出

When $a \\ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are $$ x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a} $$

Maxwell's equations:

equationdescription
$\\nabla \\cdot \\vec{\\mathbf{B}} = 0$divergence of $\\vec{\\mathbf{B}}$ is zero
$\\nabla \\times \\vec{\\mathbf{E}}, +, \\frac1c, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} = \\vec{\\mathbf{0}}$curl of $\\vec{\\mathbf{E}}$ is proportional to the rate of change of $\\vec{\\mathbf{B}}$
$\\nabla \\times \\vec{\\mathbf{B}} -, \\frac1c, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\nabla \\cdot \\vec{\\mathbf{E}} = 4 \\pi \\rho$wha?

图片懒加载

通过在配置文件中将 lazyLoading 设置为 true,可以为通过 markdown 添加的每张图片启用懒加载。

js
export default {
+  markdown: {
+    image: {
+      // 默认禁用;设置为 true 可为所有图片启用懒加载。
+      lazyLoading: true
+    }
+  }
+}

高级配置

VitePress 使用 markdown-it 作为 Markdown 渲染器。上面提到的很多扩展功能都是通过自定义插件实现的。可以使用 .vitepress/config.js 中的 markdown 选项来进一步自定义 markdown-it 实例。

js
import { defineConfig } from 'vitepress'
+import markdownItAnchor from 'markdown-it-anchor'
+import markdownItFoo from 'markdown-it-foo'
+
+export default defineConfig({
+  markdown: {
+    // markdown-it-anchor 的选项
+    // https://github.com/valeriangalliat/markdown-it-anchor#usage
+    anchor: {
+      permalink: markdownItAnchor.permalink.headerLink()
+    },
+    // @mdit-vue/plugin-toc 的选项
+    // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
+    toc: { level: [1, 2] },
+    config: (md) => {
+      // 使用更多的 Markdown-it 插件!
+      md.use(markdownItFoo)
+    }
+  }
+})
`,199)]))}const g=i(l,[["render",e]]);export{c as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.lean.js b/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.lean.js new file mode 100644 index 0000000..d695f39 --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_markdown-extension.md.CbXUJjX7.lean.js @@ -0,0 +1 @@ +import{_ as i,c as a,o as n,ag as t}from"./chunks/framework.BHpayLOB.js";const c=JSON.parse('{"title":"Markdown 扩展","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown-extension.md","filePath":"guide/markdown-extension.md"}'),l={name:"guide/markdown-extension.md"};function e(p,s,h,k,d,r){return n(),a("div",null,s[0]||(s[0]=[t("",199)]))}const g=i(l,[["render",e]]);export{c as __pageData,g as default}; diff --git a/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.js b/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.js new file mode 100644 index 0000000..91846a0 --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.js @@ -0,0 +1,60 @@ +import{_ as t,c as s,o as e,ag as i}from"./chunks/framework.BHpayLOB.js";const n="/img/zhihu.png",b=JSON.parse('{"title":"Markdown基础语法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown.md","filePath":"guide/markdown.md"}'),l={name:"guide/markdown.md"};function h(p,a,d,o,r,c){return e(),s("div",null,a[0]||(a[0]=[i(`

Markdown基础语法

本文介绍markdown语法。部分语法为非标准语法,为GitHub对markdown的扩充语法,称之为GitHub Flavored Markdown。简称GFM,大家在使用过程中注意验证。

目录

横线


***、---、___可以显示横线效果




标题

# 一级标题
+## 二级标题
+### 三级标题
+#### 四级标题
+##### 五级标题
+###### 六级标题

效果如下:

一级标题

二级标题

三级标题

四级标题

五级标题
六级标题

文本

普通文本

这是一段普通的文本

单行文本

Hello,大家好,我是果冻虾仁。
+

在一行开头加入1个Tab或者4个空格。

文本块

语法1

在连续几行的文本开头加入1个Tab或者4个空格。

欢迎到访
+很高兴见到您
+祝您,早上好,中午好,下午好,晚安
+

语法2

使用一对各三个的反引号:

欢迎到访
+我是前端码农
+你可以在github上搜索【feipages】找到我

该语法也可以实现代码高亮,见代码高亮

文字高亮

文字高亮功能能使行内部分文字高亮,使用一对反引号。 语法:

\`linux\` \`网络编程\` \`socket\` \`epoll\`

效果:linux 网络编程 socket epoll

也适合做一篇文章的tag

换行

直接回车不能换行, 可以在上一行文本后面补两个空格, 这样下一行的文本就换行了。

或者就是在两行文本直接加一个空行。

也能实现换行效果,不过这个行间距有点大。

斜体、粗体、删除线

语法效果
*斜体1*斜体1
_斜体2_斜体2
**粗体1**粗体1
__粗体2__粗体2
这是一个 ~~删除线~~这是一个 删除线
***斜粗体1***斜粗体1
___斜粗体2___斜粗体2
***~~斜粗体删除线1~~***斜粗体删除线1
~~***斜粗体删除线2***~~斜粗体删除线2
斜体、粗体、删除线可混合使用
+

图片

基本格式:

![alt](URL title)

alt和title即对应HTML中的alt和title属性(都可省略):

  • alt表示图片显示失败时的替换文本
  • title表示鼠标悬停在图片时的显示文本(注意这里要加引号)

URL即图片的url地址,如果引用本仓库中的图片,直接使用相对路径就可了,如果引用其他github仓库中的图片要注意格式,即:仓库地址/raw/分支名/图片路径,如:

https://github.com/guodongxiaren/ImageCache/raw/master/Logo/foryou.gif
#语法效果
1![baidu](http://www.baidu.com/img/bdlogo.gif "百度logo")baidu

注意例2的写法使用了URL标识符的形式,在链接一节有介绍。

在文末有code-past的定义:

[code-past]:/img/favicon.ico "收藏"

链接

链接外部URL

#语法效果
1[必应](https://www.bing.com "悬停显示")必应

语法2由两部分组成:

  • 第一部分使用两个中括号,[ ]里的标识符(本例中zhihu),可以是数字,字母等的组合,标识符上下对应就行了(姑且称之为URL标识符
  • 第二部分标记实际URL。

使用URL标识符能达到复用的目的,一般把全文所有的URL标识符统一放在文章末尾,这样看起来比较干净。除了干净之外,它还能达到复用的目的,比如你在多个地方想使用同一个链接,那么文内使用标识符,只在最底部给标识符定义出实际的URL链接即可,类似编程语言中的变量。

URL标识符是我起的名字,不知道是否准确。囧。。

链接本仓库里的URL

语法效果
[我的简介](/example/profile.md)我的简介

图片链接

给图片加链接的本质是混合图片显示语法和普通的链接语法。普通的链接中[ ]内部是链接要显示的文本,而图片链接[ ]里面则是要显示的图片。 直接混合两种语法当然可以,但是十分啰嗦,为此我们可以使用URL标识符的形式。

#语法效果
1[![](/img/zhihu.png "我的知乎,欢迎关注")][zhihu][][zhihu]

因为图片本身和链接本身都支持URL标识符的形式,所以图片链接也可以很简洁(见例3)。 注意,此时鼠标悬停时显示的文字是图片的title,而非链接本身的title了。

本文URL标识符都放置于文末

锚点

其实呢,每一个标题都是一个锚点,和HTML的锚点(#)类似,比如我们

语法效果
[回到顶部](#readme)回到顶部

不过要注意,标题中的英文字母都被转化为小写字母了。

以前GitHub对中文支持的不好,所以中文标题不能正确识别为锚点,但是现在已经没问题啦!

列表

无序列表

语法

* 昵称:果冻虾仁
+- 别名:隔壁老王
+* 英文名:Jelly

效果

  • 昵称:果冻虾仁
  • 别名:隔壁老王
  • 英文名:Jelly

多级无序列表

语法

* 编程语言
+    * 脚本语言
+        * Python

效果

  • 编程语言
    • 脚本语言
      • Python

一级有序列表

语法

就是在数字后面加一个点,再加一个空格。不过看起来起来可能不够明显。

面向对象的三个基本特征:
+
+1. 封装
+2. 继承
+3. 多态

效果

面向对象的三个基本特征:

  1. 封装
  2. 继承
  3. 多态

多级有序列表

和无序列表一样,有序列表也有多级结构。

语法

1. 这是一级的有序列表,数字1还是1
+   1. 这是二级的有序列表,阿拉伯数字在显示的时候变成了罗马数字
+      1. 这是三级的有序列表,数字在显示的时候变成了英文字母

效果

  1. 这是一级的有序列表,数字1还是1
    1. 这是二级的有序列表,阿拉伯数字在显示的时候变成了罗马数字
      1. 这是三级的有序列表,数字在显示的时候变成了英文字母

复选框列表

语法

- [x] 需求分析
+- [x] 系统设计
+- [x] 详细设计
+- [ ] 编码
+- [ ] 测试
+- [ ] 交付

效果

  • [x] 需求分析
  • [x] 系统设计
  • [x] 详细设计
  • [ ] 编码
  • [ ] 测试
  • [ ] 交付

您可以使用这个功能来标注某个项目各项任务的完成情况。

Tip:

在GitHub的issue中使用该语法是可以实时点击复选框来勾选或解除勾选的,而无需修改issue原文。

块引用

常用于引用文本

文本摘自《深入理解计算机系统》P27

令人吃惊的是,在哪种字节顺序是合适的这个问题上,人们表现得非常情绪化。实际上术语“little endian”(小端)和“big endian”(大端)出自Jonathan Swift的《格利佛游记》一书,其中交战的两个派别无法就应该从哪一端打开一个半熟的鸡蛋达成一致。因此,争论沦为关于社会政治的争论。只要选择了一种规则并且始终如一的坚持,其实对于哪种字节排序的选择都是任意的。

“端”(endian)的起源 以下是Jonathan Swift在1726年关于大小端之争历史的描述: “……下面我要告诉你的是,Lilliput和Blefuscu这两大强国在过去36个月里一直在苦战。战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今的皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了,因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破较小的一端,违令者重罚。”

块引用有多级结构

语法

> 数据结构
+>> 树
+>>> 二叉树
+>>>> 平衡二叉树
+>>>>> 满二叉树

效果

数据结构

二叉树

平衡二叉树

满二叉树

代码高亮

语法

在三个反引号\`\`\`后面加上编程语言的名字(比如javascipt),另起一行开始写代码,最后一行再加上三个反引号\`\`\`。

效果

Java
public static void main(String[]args){} //Java
c
int main(int argc, char *argv[]) //C
Bash
echo "hello GitHub" #Bash
javascript
document.getElementById("myH1").innerHTML="Welcome to my Homepage"; //javascipt
cpp
string &operator+(const string& A,const string& B) //cpp

表格

基本语法:

| 表头1  | 表头2|
+| ---------- | -----------|
+| 表格单元   | 表格单元   |
+| 表格单元   | 表格单元   |
表头1表头2
表格单元表格单元
表格单元表格单元

简洁语法:

表头1  | 表头2|
+--------- | --------|
+表格单元  | 表格单元 |
+表格单元  | 表格单元 |
表头1表头2
表格单元表格单元
表格单元表格单元

对齐

表格可以指定对齐方式

| 左对齐 | 居中  | 右对齐 |
+| :------------ |:---------------:| -----:|
+| col 3 is      | some wordy text | $1600 |
+| col 2 is      | centered        |   $12 |
+| zebra stripes | are neat        |    $1 |
左对齐居中右对齐
col 3 issome wordy text$1600
col 2 iscentered$12
zebra stripesare neat$1

混合其他语法

表格单元中的内容可以和其他大多数GFM语法配合使用,如:

使用普通文本的删除线,斜体等效果

名字描述
HelpDisplay the help window.
CloseCloses a window

表格中嵌入图片(链接)

其实前面介绍图片显示、图片链接的时候为了清晰就是放在在表格中显示的。

图片描述
![baidu][baidu-logo]百度

diff语法

版本控制的系统中都少不了diff的功能,即展示一个文件内容的增加与删除。 GFM中可以显示的展示diff效果。使用绿色表示新增,红色表示删除。

语法

其语法与代码高亮类似,只是在三个反引号后面写diff, 并且其内容中,可以用 + 开头表示新增,- 开头表示删除。 另外还有有 !#的语法。

效果

diff
+ 人闲桂花落,
+- 夜静春山空。
+! 月出惊山鸟,
+# 时鸣春涧中。

常用HTML语法

markdown是支持HTML语法的,虽然不鼓励大量使用HTML语法,毕竟那样就丧失了markdown的意义,但是有一些HTML语法在写README的时候是很少的补充。

折叠

<details>
+<summary>Linux环境</summary>
+
+##### 编译
+xxxx
+
+##### 安装
+xxxx
+</details>
Linux环境
编译

xxxx

安装

xxxx

居中

很多地方都会用到居中的效果,比如如下内容将会把一个表格在页面中居中展示:

<div align="center">
+
+| 表头1  | 表头2|
+| ---------- | -----------|
+| 表格单元   | 表格单元   |
+| 表格单元   | 表格单元   |
+
+</div>
表头1表头2
表格单元表格单元
表格单元表格单元

其他任意需要居中展示的语法,都可以放在其中。

`,160)]))}const k=t(l,[["render",h]]);export{b as __pageData,k as default}; diff --git a/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.lean.js b/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.lean.js new file mode 100644 index 0000000..c56f097 --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_markdown.md.B6cbd7BH.lean.js @@ -0,0 +1 @@ +import{_ as t,c as s,o as e,ag as i}from"./chunks/framework.BHpayLOB.js";const n="/img/zhihu.png",b=JSON.parse('{"title":"Markdown基础语法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/markdown.md","filePath":"guide/markdown.md"}'),l={name:"guide/markdown.md"};function h(p,a,d,o,r,c){return e(),s("div",null,a[0]||(a[0]=[i("",160)]))}const k=t(l,[["render",h]]);export{b as __pageData,k as default}; diff --git a/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.js b/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.js new file mode 100644 index 0000000..07e2dbd --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.js @@ -0,0 +1 @@ +import{_ as t,c as r,o,j as a,a as i}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"guide/profile.md","filePath":"guide/profile.md"}'),s={name:"guide/profile.md"};function n(d,e,l,c,p,f){return o(),r("div",null,e[0]||(e[0]=[a("h1",{id:"简介",tabindex:"-1"},[i("简介 "),a("a",{class:"header-anchor",href:"#简介","aria-label":'Permalink to "简介"'},"​")],-1)]))}const u=t(s,[["render",n]]);export{_ as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.lean.js b/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.lean.js new file mode 100644 index 0000000..07e2dbd --- /dev/null +++ b/docs/.vitepress/dist/assets/guide_profile.md.D2-043_-.lean.js @@ -0,0 +1 @@ +import{_ as t,c as r,o,j as a,a as i}from"./chunks/framework.BHpayLOB.js";const _=JSON.parse('{"title":"简介","description":"","frontmatter":{},"headers":[],"relativePath":"guide/profile.md","filePath":"guide/profile.md"}'),s={name:"guide/profile.md"};function n(d,e,l,c,p,f){return o(),r("div",null,e[0]||(e[0]=[a("h1",{id:"简介",tabindex:"-1"},[i("简介 "),a("a",{class:"header-anchor",href:"#简介","aria-label":'Permalink to "简介"'},"​")],-1)]))}const u=t(s,[["render",n]]);export{_ as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/index.md.6FSCG9lU.js b/docs/.vitepress/dist/assets/index.md.6FSCG9lU.js deleted file mode 100644 index 2102db5..0000000 --- a/docs/.vitepress/dist/assets/index.md.6FSCG9lU.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as t,o as a}from"./chunks/framework.B8KKhRA6.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"my blog project","text":"a blog site","tagline":"My great project tagline","actions":[{"theme":"brand","text":"Markdown Examples","link":"/markdown-examples"},{"theme":"alt","text":"API Examples","link":"/api-examples"}]},"features":[{"title":"Feature A","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"},{"title":"Feature B","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"},{"title":"Feature C","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function o(r,s,n,l,m,c){return a(),t("div")}const u=e(i,[["render",o]]);export{p as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/index.md.6FSCG9lU.lean.js b/docs/.vitepress/dist/assets/index.md.6FSCG9lU.lean.js deleted file mode 100644 index 2102db5..0000000 --- a/docs/.vitepress/dist/assets/index.md.6FSCG9lU.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,c as t,o as a}from"./chunks/framework.B8KKhRA6.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"my blog project","text":"a blog site","tagline":"My great project tagline","actions":[{"theme":"brand","text":"Markdown Examples","link":"/markdown-examples"},{"theme":"alt","text":"API Examples","link":"/api-examples"}]},"features":[{"title":"Feature A","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"},{"title":"Feature B","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"},{"title":"Feature C","details":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function o(r,s,n,l,m,c){return a(),t("div")}const u=e(i,[["render",o]]);export{p as __pageData,u as default}; diff --git a/docs/.vitepress/dist/assets/index.md.bEuRoy2r.js b/docs/.vitepress/dist/assets/index.md.bEuRoy2r.js new file mode 100644 index 0000000..eca43bd --- /dev/null +++ b/docs/.vitepress/dist/assets/index.md.bEuRoy2r.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.BHpayLOB.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"让技术赋能业务开发","text":"高效稳定赋能业务运行","tagline":"Keep Reading, Keep Thinking, Keep Doing","image":{"src":"/background.svg","alt":"背景图"},"actions":[{"theme":"brand","text":"关于","link":"/guide/about.md"},{"theme":"alt","text":"iOS","link":"/frontend/ios"},{"theme":"alt","text":"Markdown","link":"/guide/markdown"}]},"features":[{"title":"前端开发","details":"前端的前景在哪儿"},{"title":"ci/cd","details":"打包发版都是怎么进行的"},{"title":"项目开发那些事儿","details":"聊聊项目开发测试过程中的那些事儿"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function n(o,d,r,s,l,c){return a(),t("div")}const x=e(i,[["render",n]]);export{p as __pageData,x as default}; diff --git a/docs/.vitepress/dist/assets/index.md.bEuRoy2r.lean.js b/docs/.vitepress/dist/assets/index.md.bEuRoy2r.lean.js new file mode 100644 index 0000000..eca43bd --- /dev/null +++ b/docs/.vitepress/dist/assets/index.md.bEuRoy2r.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.BHpayLOB.js";const p=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"让技术赋能业务开发","text":"高效稳定赋能业务运行","tagline":"Keep Reading, Keep Thinking, Keep Doing","image":{"src":"/background.svg","alt":"背景图"},"actions":[{"theme":"brand","text":"关于","link":"/guide/about.md"},{"theme":"alt","text":"iOS","link":"/frontend/ios"},{"theme":"alt","text":"Markdown","link":"/guide/markdown"}]},"features":[{"title":"前端开发","details":"前端的前景在哪儿"},{"title":"ci/cd","details":"打包发版都是怎么进行的"},{"title":"项目开发那些事儿","details":"聊聊项目开发测试过程中的那些事儿"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function n(o,d,r,s,l,c){return a(),t("div")}const x=e(i,[["render",n]]);export{p as __pageData,x as default}; diff --git a/docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.lean.js b/docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.lean.js deleted file mode 100644 index ab75666..0000000 --- a/docs/.vitepress/dist/assets/markdown-examples.md.DX_lK_aG.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as a,c as i,o as n,ae as e}from"./chunks/framework.B8KKhRA6.js";const E=JSON.parse('{"title":"Markdown Extension Examples","description":"","frontmatter":{},"headers":[],"relativePath":"markdown-examples.md","filePath":"markdown-examples.md"}'),t={name:"markdown-examples.md"};function l(p,s,h,k,r,o){return n(),i("div",null,s[0]||(s[0]=[e("",19)]))}const c=a(t,[["render",l]]);export{E as __pageData,c as default}; diff --git a/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.js b/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.js new file mode 100644 index 0000000..ba15b70 --- /dev/null +++ b/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.js @@ -0,0 +1,10 @@ +import{_ as s,c as t,o as a,ag as n}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"HTTPS网站访问过程","description":"","frontmatter":{},"headers":[],"relativePath":"network/https-tips.md","filePath":"network/https-tips.md"}'),i={name:"network/https-tips.md"};function p(l,e,o,c,r,h){return a(),t("div",null,e[0]||(e[0]=[n(`

HTTPS网站访问过程

相对于普通HTTP网络请求,访问HTTPS时,浏览器会帮我们做很多影藏的工作。

  1. 发起请求 首先当输入完https网址 点击enter之后,浏览器首先向服务器发送一个访问的请求,这个请求中包含浏览器SSL协议的版本号,加密算法的种类,产生的随机数,以及其他 服务器与客户端之间通讯所需要的各种信息;
  2. 服务器端返回证书 服务器向客户端传送SSL协议的版本号,加密算法的种类,随机数以及其他信息,同时服务器还将向客服端传送自己的证书,这些信息被保存在客户端称作‘保护空间’的地方,这里最关键的就是证书信息;
  3. 浏览器验证证书信息 浏览器利用服务器传递过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器的证书的CA是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。 如果合法验证没有通过,通讯将断开,如果合法验证通过,将继续进行第四步。
  4. 客服端向服务器发送“预主密码” 浏览器随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤2中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器; 4.1 如果服务器要求客户的身份认证(在握手过程中可选),用户不光要给服务器“预主密码”,还需要建立一个随机数然后对其进行数据签名,将设个含有签名的随机数和客户自己的证书也传给服务器。 4.2 如果不需要,则只将“预主密码”传递给服务器,直接进行第6步。
  5. 服务器身份验证(需要才进行);
  6. 浏览器、服务器各自生成通话密码 服务器将自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主通讯密码(客服端也将通过同样的方法产生相同的主通讯密码);
  7. 约定通话密码 服务器和客服端用相同的主通讯密码即“通话密码”,一个对称密钥用于SSL协议的安全数据通讯的加解密通讯,同时在SSL通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。
  8. 浏览器通知服务器已经准备就绪
  9. 服务器通知浏览器已经准备就绪
  10. 开始数据通信 SSL的握手部分结束,SSL安全通道建立,开始进行数据通讯

NSURLSession 模拟HTTPS证书认证

当我们进行访问一个HTTPS网站时,当走到步骤2时(服务器返回证书时),需要我们在本地完成证书信任的过程,如果使用session创建的task进行网络访问,会进入到代理方法- URLSession:didReceiveChallenge:completionHandler:完成步骤3。 其中 challenge 是一个包含授权请求的对象(NSURLAuthenticationChalleng),代表进行HTTPS请求时,服务器发过来的质询,当收到质询之后就要开始进行客服端验证了, challenge 有几个重要的属性: protectionSpace它代表着对需要验证的受保护空间的验证,是一个NSURLProtectionSpace类型的对象,NSURLProtectionSpace对象包含请求的主机host、端口号port、代理类型proxyType、使用的协议protocol、服务端要求客户端对其验证的方法authenticationMethod等重要的信息,还有代表着服务器SSL传输状态的SecTrustRef类型的属性serverTrust,不过当且仅当authenticationMethod为NSURLAuthenticationMethodServerTrust这个属性值才不为Nil.

常见服务端指定的验证方法的类型

NSURLAuthenticationMethodHTTPBasic 
+NSURLAuthenticationMethodHTTPDigest
+NSURLAuthenticationMethodNTLM
+NSURLAuthenticationMethodClientCertificate
+NSURLAuthenticationMethodServerTrust

其中HTTP Basic、HTTP Digest与NTLM认证都是基于用户名/密码的认证,ClientCertificate(客户端证书)认证要求从客户端上传证书。客户端需要按照服务端指定的认证方法进行认证,否则可能会按照错误处理。例如使用HTTP Basic方式,客户端需要将用户名和密码信息放到凭据中,然后传递给服务端;如果使用的是ServerTrust方式,那么客户端就要将信任的凭据发给服务端。 一般在HTTPS访问的第3步过程中,服务端要求的认证方法几乎总是ServerTrust方式。有遇到过一些网络代理工具使用HTTP Digest的验证方式,在浏览器端进行访问的时候就弹出一个要求输入账号和密码的弹窗.

对于completionHandler参数是一个最终处理凭据的回调,要求在创建好包含验证信息的凭据之后必须调用,这样才会将验证的信息发送给服务端,也就意味着第3步的完成,开始进行第4步

typedef NS_ENUM(NSInteger, NSURLSessionAuthChallengeDisposition) {
+    NSURLSessionAuthChallengeUseCredential = 0,   // 使用服务器发回的凭据,不过可能为空     
+    NSURLSessionAuthChallengePerformDefaultHandling = 1,  // 默认的处理方法,凭据参数会被忽略
+    NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,  //取消整个请求,忽略凭据参数 
+    NSURLSessionAuthChallengeRejectProtectionSpace = 3, // 这次质询被拒绝,下次再试 ,凭据参数被忽略
+} NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);

参考:HTTPS访问控制

date: 2017-04-22 16:00:00 author: "Gao Fei"

`,12)]))}const T=s(i,[["render",p]]);export{d as __pageData,T as default}; diff --git a/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.lean.js b/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.lean.js new file mode 100644 index 0000000..b91e9c1 --- /dev/null +++ b/docs/.vitepress/dist/assets/network_https-tips.md.DbPLWUZ9.lean.js @@ -0,0 +1 @@ +import{_ as s,c as t,o as a,ag as n}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"HTTPS网站访问过程","description":"","frontmatter":{},"headers":[],"relativePath":"network/https-tips.md","filePath":"network/https-tips.md"}'),i={name:"network/https-tips.md"};function p(l,e,o,c,r,h){return a(),t("div",null,e[0]||(e[0]=[n("",12)]))}const T=s(i,[["render",p]]);export{d as __pageData,T as default}; diff --git a/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.js b/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.js new file mode 100644 index 0000000..0db6161 --- /dev/null +++ b/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"网络","description":"","frontmatter":{},"headers":[],"relativePath":"network/index.md","filePath":"network/index.md"}'),n={name:"network/index.md"};function i(d,a,s,l,_,c){return r(),t("div",null,a[0]||(a[0]=[o('

网络

网络协议

应用

',3)]))}const f=e(n,[["render",i]]);export{m as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.lean.js b/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.lean.js new file mode 100644 index 0000000..b8e6235 --- /dev/null +++ b/docs/.vitepress/dist/assets/network_index.md.yKg90t4v.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,ag as o}from"./chunks/framework.BHpayLOB.js";const m=JSON.parse('{"title":"网络","description":"","frontmatter":{},"headers":[],"relativePath":"network/index.md","filePath":"network/index.md"}'),n={name:"network/index.md"};function i(d,a,s,l,_,c){return r(),t("div",null,a[0]||(a[0]=[o("",3)]))}const f=e(n,[["render",i]]);export{m as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/newproject_2x.E4tz2V26.png b/docs/.vitepress/dist/assets/newproject_2x.E4tz2V26.png new file mode 100644 index 0000000..2a22b52 Binary files /dev/null and b/docs/.vitepress/dist/assets/newproject_2x.E4tz2V26.png differ diff --git a/docs/.vitepress/dist/assets/style.BOSx6zLo.css b/docs/.vitepress/dist/assets/style.CjMY2hXd.css similarity index 95% rename from docs/.vitepress/dist/assets/style.BOSx6zLo.css rename to docs/.vitepress/dist/assets/style.CjMY2hXd.css index d73d034..dfe5daa 100644 --- a/docs/.vitepress/dist/assets/style.BOSx6zLo.css +++ b/docs/.vitepress/dist/assets/style.CjMY2hXd.css @@ -1 +1 @@ -@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: #3c3c43;--vp-c-text-2: #67676c;--vp-c-text-3: #929295}.dark{--vp-c-text-1: #dfdfd6;--vp-c-text-2: #98989f;--vp-c-text-3: #6a6a71}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:lang(es),:lang(pt){--vp-code-copy-copied-text-content: "Copiado"}:lang(fa){--vp-code-copy-copied-text-content: "کپی شد"}:lang(ko){--vp-code-copy-copied-text-content: "복사됨"}:lang(ru){--vp-code-copy-copied-text-content: "Скопировано"}:lang(zh){--vp-code-copy-copied-text-content: "已复制"}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{overflow-x:auto}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc h4{margin:24px 0 0;letter-spacing:-.01em;line-height:24px;font-size:18px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s;color:var(--vp-c-text-2)}.vp-doc blockquote>p{margin:0;font-size:16px;transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code,.vp-doc h4>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;-webkit-user-select:none;user-select:none;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(:is(.no-icon,svg a,:has(img,svg))):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(:is(.no-icon,svg a,:has(img,svg))):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}.NotFound[data-v-d6be1790]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-d6be1790]{padding:96px 32px 168px}}.code[data-v-d6be1790]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-d6be1790]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-d6be1790]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-d6be1790]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-d6be1790]{padding-top:20px}.link[data-v-d6be1790]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-d6be1790]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-b933a997]{position:relative;z-index:1}.nested[data-v-b933a997]{padding-right:16px;padding-left:16px}.outline-link[data-v-b933a997]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-b933a997]:hover,.outline-link.active[data-v-b933a997]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-b933a997]{padding-left:13px}.VPDocAsideOutline[data-v-a5bbad30]{display:none}.VPDocAsideOutline.has-outline[data-v-a5bbad30]{display:block}.content[data-v-a5bbad30]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-a5bbad30]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-a5bbad30]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-e98dd255]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-e98dd255]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-e257564d]{margin-top:64px}.edit-info[data-v-e257564d]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-e257564d]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-e257564d]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-e257564d]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-e257564d]{margin-right:8px}.prev-next[data-v-e257564d]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-e257564d]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-e257564d]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-e257564d]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-e257564d]{margin-left:auto;text-align:right}.desc[data-v-e257564d]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-e257564d]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-39a288b8]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-39a288b8]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-39a288b8]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-39a288b8]{display:flex;justify-content:center}.VPDoc .aside[data-v-39a288b8]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{max-width:1104px}}.container[data-v-39a288b8]{margin:0 auto;width:100%}.aside[data-v-39a288b8]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-39a288b8]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-39a288b8]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-39a288b8]::-webkit-scrollbar{display:none}.aside-curtain[data-v-39a288b8]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-39a288b8]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-39a288b8]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-39a288b8]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-39a288b8]{order:1;margin:0;min-width:640px}}.content-container[data-v-39a288b8]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-39a288b8]{max-width:688px}.VPButton[data-v-fa7799d5]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-fa7799d5]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-fa7799d5]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-fa7799d5]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-fa7799d5]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-fa7799d5]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-fa7799d5]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-fa7799d5]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-fa7799d5]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-fa7799d5]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-fa7799d5]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-fa7799d5]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-fa7799d5]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-8426fc1a]{display:none}.dark .VPImage.light[data-v-8426fc1a]{display:none}.VPHero[data-v-4f9c455b]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-4f9c455b]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-4f9c455b]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-4f9c455b]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-4f9c455b]{flex-direction:row}}.main[data-v-4f9c455b]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-4f9c455b]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-4f9c455b]{text-align:left}}@media (min-width: 960px){.main[data-v-4f9c455b]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-4f9c455b]{max-width:592px}}.heading[data-v-4f9c455b]{display:flex;flex-direction:column}.name[data-v-4f9c455b],.text[data-v-4f9c455b]{width:fit-content;max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-4f9c455b],.VPHero.has-image .text[data-v-4f9c455b]{margin:0 auto}.name[data-v-4f9c455b]{color:var(--vp-home-hero-name-color)}.clip[data-v-4f9c455b]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-4f9c455b],.text[data-v-4f9c455b]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-4f9c455b],.text[data-v-4f9c455b]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-4f9c455b],.VPHero.has-image .text[data-v-4f9c455b]{margin:0}}.tagline[data-v-4f9c455b]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-4f9c455b]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-4f9c455b]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-4f9c455b]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-4f9c455b]{margin:0}}.actions[data-v-4f9c455b]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-4f9c455b]{justify-content:center}@media (min-width: 640px){.actions[data-v-4f9c455b]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-4f9c455b]{justify-content:flex-start}}.action[data-v-4f9c455b]{flex-shrink:0;padding:6px}.image[data-v-4f9c455b]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-4f9c455b]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-4f9c455b]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-4f9c455b]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-4f9c455b]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-4f9c455b]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-4f9c455b]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-4f9c455b]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-4f9c455b]{width:320px;height:320px}}[data-v-4f9c455b] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-4f9c455b] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-4f9c455b] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-a3976bdc]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-a3976bdc]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-a3976bdc]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-a3976bdc]>.VPImage{margin-bottom:20px}.icon[data-v-a3976bdc]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-a3976bdc]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-a3976bdc]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-a3976bdc]{padding-top:8px}.link-text-value[data-v-a3976bdc]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-a3976bdc]{margin-left:6px}.VPFeatures[data-v-a6181336]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-a6181336]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-a6181336]{padding:0 64px}}.container[data-v-a6181336]{margin:0 auto;max-width:1152px}.items[data-v-a6181336]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-a6181336]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336]{width:50%}.item.grid-3[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-a6181336]{width:25%}}.container[data-v-8e2d4988]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-8e2d4988]{padding:0 48px}}@media (min-width: 960px){.container[data-v-8e2d4988]{width:100%;padding:0 64px}}.vp-doc[data-v-8e2d4988] .VPHomeSponsors,.vp-doc[data-v-8e2d4988] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,.vp-doc[data-v-8e2d4988] .VPTeamPage a{text-decoration:none}.VPHome[data-v-8b561e3d]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-8b561e3d]{margin-bottom:128px}}.VPContent[data-v-1428d186]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-1428d186]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-1428d186]{margin:0}@media (min-width: 960px){.VPContent[data-v-1428d186]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-1428d186]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-1428d186]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-e315a0ad]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-e315a0ad]{display:none}.VPFooter[data-v-e315a0ad] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-e315a0ad] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-e315a0ad]{padding:32px}}.container[data-v-e315a0ad]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-e315a0ad],.copyright[data-v-e315a0ad]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-8a42e2b4]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-8a42e2b4]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-8a42e2b4]{color:var(--vp-c-text-1)}.icon[data-v-8a42e2b4]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]{font-size:14px}.icon[data-v-8a42e2b4]{font-size:16px}}.open>.icon[data-v-8a42e2b4]{transform:rotate(90deg)}.items[data-v-8a42e2b4]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-8a42e2b4]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-8a42e2b4]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-8a42e2b4]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-8a42e2b4]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-8a42e2b4]{transition:all .2s ease-out}.flyout-leave-active[data-v-8a42e2b4]{transition:all .15s ease-in}.flyout-enter-from[data-v-8a42e2b4],.flyout-leave-to[data-v-8a42e2b4]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-a6f0e41e]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-a6f0e41e]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-a6f0e41e]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-a6f0e41e]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-a6f0e41e]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-a6f0e41e]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-a6f0e41e]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-a6f0e41e]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-a6f0e41e]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-a6f0e41e]{display:none}}.menu-icon[data-v-a6f0e41e]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 32px 11px}}.VPSwitch[data-v-1d5665e3]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-1d5665e3]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-1d5665e3]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-1d5665e3]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-1d5665e3] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-1d5665e3] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-5337faa4]{opacity:1}.moon[data-v-5337faa4],.dark .sun[data-v-5337faa4]{opacity:0}.dark .moon[data-v-5337faa4]{opacity:1}.dark .VPSwitchAppearance[data-v-5337faa4] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-6c893767]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-6c893767]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-35975db6]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-35975db6]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-35975db6]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-35975db6]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-b98bc113]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-b98bc113] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-b98bc113] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-b98bc113] .group:last-child{padding-bottom:0}.VPMenu[data-v-b98bc113] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-b98bc113] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-b98bc113] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-b98bc113] .action{padding-left:24px}.VPFlyout[data-v-cf11d7a2]{position:relative}.VPFlyout[data-v-cf11d7a2]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-cf11d7a2]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-cf11d7a2]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-cf11d7a2]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-cf11d7a2]{color:var(--vp-c-brand-2)}.button[aria-expanded=false]+.menu[data-v-cf11d7a2]{opacity:0;visibility:hidden;transform:translateY(0)}.VPFlyout:hover .menu[data-v-cf11d7a2],.button[aria-expanded=true]+.menu[data-v-cf11d7a2]{opacity:1;visibility:visible;transform:translateY(0)}.button[data-v-cf11d7a2]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-cf11d7a2]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-cf11d7a2]{margin-right:0;font-size:16px}.text-icon[data-v-cf11d7a2]{margin-left:4px;font-size:14px}.icon[data-v-cf11d7a2]{font-size:20px;transition:fill .25s}.menu[data-v-cf11d7a2]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-bd121fe5]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-bd121fe5]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-bd121fe5]>svg,.VPSocialLink[data-v-bd121fe5]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarExtra[data-v-bb2aa2f0]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-bb2aa2f0]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-bb2aa2f0]{display:none}}.trans-title[data-v-bb2aa2f0]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-bb2aa2f0],.item.social-links[data-v-bb2aa2f0]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-bb2aa2f0]{min-width:176px}.appearance-action[data-v-bb2aa2f0]{margin-right:-2px}.social-links-list[data-v-bb2aa2f0]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-e56f3d57]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-e56f3d57],.VPNavBarMenuLink[data-v-e56f3d57]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-dc692963]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-dc692963]{display:flex}}/*! @docsearch/css 3.8.2 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch-Button-Key--pressed{box-shadow:var(--docsearch-key-pressed-shadow);transform:translate3d(0,1px,0)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.title[data-v-1168a8e4]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-1168a8e4]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-1168a8e4]{border-bottom-color:var(--vp-c-divider)}}[data-v-1168a8e4] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-88af2de4]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-88af2de4]{display:flex;align-items:center}}.title[data-v-88af2de4]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-6aa21345]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .25s}.VPNavBar.screen-open[data-v-6aa21345]{transition:none;background-color:var(--vp-nav-bg-color);border-bottom:1px solid var(--vp-c-divider)}.VPNavBar[data-v-6aa21345]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-6aa21345]:not(.home){background-color:transparent}.VPNavBar[data-v-6aa21345]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-6aa21345]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-6aa21345]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-6aa21345]{padding:0}}.container[data-v-6aa21345]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-6aa21345],.container>.content[data-v-6aa21345]{pointer-events:none}.container[data-v-6aa21345] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-6aa21345]{max-width:100%}}.title[data-v-6aa21345]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-6aa21345]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-6aa21345]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-6aa21345]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-6aa21345]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-6aa21345]{column-gap:.5rem}}.menu+.translations[data-v-6aa21345]:before,.menu+.appearance[data-v-6aa21345]:before,.menu+.social-links[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before,.appearance+.social-links[data-v-6aa21345]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before{margin-right:16px}.appearance+.social-links[data-v-6aa21345]:before{margin-left:16px}.social-links[data-v-6aa21345]{margin-right:-8px}.divider[data-v-6aa21345]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-6aa21345]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-6aa21345]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-b44890b2]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-b44890b2]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-df37e6dd]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-df37e6dd]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-3e9c20e4]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-3e9c20e4]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-b9ab8c58]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-b9ab8c58]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-b9ab8c58]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-b9ab8c58]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-b9ab8c58]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-b9ab8c58]{transform:rotate(45deg)}.button[data-v-b9ab8c58]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-b9ab8c58]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-b9ab8c58]{transition:transform .25s}.group[data-v-b9ab8c58]:first-child{padding-top:0}.group+.group[data-v-b9ab8c58],.group+.item[data-v-b9ab8c58]{padding-top:4px}.VPNavScreenTranslations[data-v-858fe1a4]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-858fe1a4]{height:auto}.title[data-v-858fe1a4]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-858fe1a4]{font-size:16px}.icon.lang[data-v-858fe1a4]{margin-right:8px}.icon.chevron[data-v-858fe1a4]{margin-left:4px}.list[data-v-858fe1a4]{padding:4px 0 0 24px}.link[data-v-858fe1a4]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-f2779853]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .25s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-f2779853],.VPNavScreen.fade-leave-active[data-v-f2779853]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-f2779853],.VPNavScreen.fade-leave-active .container[data-v-f2779853]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-f2779853],.VPNavScreen.fade-leave-to[data-v-f2779853]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-f2779853],.VPNavScreen.fade-leave-to .container[data-v-f2779853]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-f2779853]{display:none}}.container[data-v-f2779853]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-f2779853],.menu+.appearance[data-v-f2779853],.translations+.appearance[data-v-f2779853]{margin-top:24px}.menu+.social-links[data-v-f2779853]{margin-top:16px}.appearance+.social-links[data-v-f2779853]{margin-top:16px}.VPNav[data-v-ae24b3ad]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-ae24b3ad]{position:fixed}}.VPSidebarItem.level-0[data-v-b3fd67f8]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-b3fd67f8]{padding-bottom:10px}.item[data-v-b3fd67f8]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-b3fd67f8]{cursor:pointer}.indicator[data-v-b3fd67f8]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-b3fd67f8]{background-color:var(--vp-c-brand-1)}.link[data-v-b3fd67f8]{display:flex;align-items:center;flex-grow:1}.text[data-v-b3fd67f8]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-b3fd67f8]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-b3fd67f8],.VPSidebarItem.level-2 .text[data-v-b3fd67f8],.VPSidebarItem.level-3 .text[data-v-b3fd67f8],.VPSidebarItem.level-4 .text[data-v-b3fd67f8],.VPSidebarItem.level-5 .text[data-v-b3fd67f8]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-b3fd67f8]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-b3fd67f8]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-b3fd67f8]{color:var(--vp-c-brand-1)}.caret[data-v-b3fd67f8]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-b3fd67f8]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-b3fd67f8]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-b3fd67f8]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-b3fd67f8]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-b3fd67f8],.VPSidebarItem.level-2 .items[data-v-b3fd67f8],.VPSidebarItem.level-3 .items[data-v-b3fd67f8],.VPSidebarItem.level-4 .items[data-v-b3fd67f8],.VPSidebarItem.level-5 .items[data-v-b3fd67f8]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-b3fd67f8]{display:none}.no-transition[data-v-c40bc020] .caret-icon{transition:none}.group+.group[data-v-c40bc020]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-c40bc020]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSidebar[data-v-319d5ca6]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-319d5ca6]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-319d5ca6]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-319d5ca6]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-319d5ca6]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-319d5ca6]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-319d5ca6]{outline:0}.VPSkipLink[data-v-0b0ada53]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-0b0ada53]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-0b0ada53]{top:14px;left:16px}}.Layout[data-v-5d98c3a5]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3d121b4a]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-3d121b4a]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{margin:128px 0}}.VPHomeSponsors[data-v-3d121b4a]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 64px}}.container[data-v-3d121b4a]{margin:0 auto;max-width:1152px}.love[data-v-3d121b4a]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-3d121b4a]{display:inline-block}.message[data-v-3d121b4a]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3d121b4a]{padding-top:32px}.action[data-v-3d121b4a]{padding-top:40px;text-align:center}.VPTeamMembersItem[data-v-f3fa364a]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f3fa364a]{padding:32px}.VPTeamMembersItem.small .data[data-v-f3fa364a]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f3fa364a]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f3fa364a]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f3fa364a]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f3fa364a]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f3fa364a]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f3fa364a]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f3fa364a]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f3fa364a]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f3fa364a]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f3fa364a]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f3fa364a]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f3fa364a]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f3fa364a]{text-align:center}.avatar[data-v-f3fa364a]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f3fa364a]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f3fa364a]{margin:0;font-weight:600}.affiliation[data-v-f3fa364a]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f3fa364a]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f3fa364a]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f3fa364a]{margin:0 auto}.desc[data-v-f3fa364a] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f3fa364a]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f3fa364a]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f3fa364a]:hover,.sp .sp-link.link[data-v-f3fa364a]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f3fa364a]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4]{max-width:876px}.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4]{max-width:760px}.container[data-v-6cb0dbc4]{display:grid;gap:24px;margin:0 auto;max-width:1152px}.VPTeamPage[data-v-7c57f839]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-7c57f839]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-7c57f839-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-7c57f839-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:96px}}.VPTeamMembers[data-v-7c57f839-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 64px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );--vp-home-hero-image-background-image: linear-gradient( -45deg, #bd34fe 50%, #47caff 50% );--vp-home-hero-image-filter: blur(44px)}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(68px)}}:root{--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-brand-soft);--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft)}.DocSearch{--docsearch-primary-color: var(--vp-c-brand-1) !important} +@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: #3c3c43;--vp-c-text-2: #67676c;--vp-c-text-3: #929295}.dark{--vp-c-text-1: #dfdfd6;--vp-c-text-2: #98989f;--vp-c-text-3: #6a6a71}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:lang(es),:lang(pt){--vp-code-copy-copied-text-content: "Copiado"}:lang(fa){--vp-code-copy-copied-text-content: "کپی شد"}:lang(ko){--vp-code-copy-copied-text-content: "복사됨"}:lang(ru){--vp-code-copy-copied-text-content: "Скопировано"}:lang(zh){--vp-code-copy-copied-text-content: "已复制"}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{overflow-x:auto}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc h4{margin:24px 0 0;letter-spacing:-.01em;line-height:24px;font-size:18px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s;color:var(--vp-c-text-2)}.vp-doc blockquote>p{margin:0;font-size:16px;transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code,.vp-doc h4>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;-webkit-user-select:none;user-select:none;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(:is(.no-icon,svg a,:has(img,svg))):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(:is(.no-icon,svg a,:has(img,svg))):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}.NotFound[data-v-d6be1790]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-d6be1790]{padding:96px 32px 168px}}.code[data-v-d6be1790]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-d6be1790]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-d6be1790]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-d6be1790]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-d6be1790]{padding-top:20px}.link[data-v-d6be1790]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-d6be1790]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-b933a997]{position:relative;z-index:1}.nested[data-v-b933a997]{padding-right:16px;padding-left:16px}.outline-link[data-v-b933a997]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-b933a997]:hover,.outline-link.active[data-v-b933a997]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-b933a997]{padding-left:13px}.VPDocAsideOutline[data-v-a5bbad30]{display:none}.VPDocAsideOutline.has-outline[data-v-a5bbad30]{display:block}.content[data-v-a5bbad30]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-a5bbad30]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-a5bbad30]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-e98dd255]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-e98dd255]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-e257564d]{margin-top:64px}.edit-info[data-v-e257564d]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-e257564d]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-e257564d]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-e257564d]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-e257564d]{margin-right:8px}.prev-next[data-v-e257564d]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-e257564d]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-e257564d]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-e257564d]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-e257564d]{margin-left:auto;text-align:right}.desc[data-v-e257564d]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-e257564d]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-39a288b8]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-39a288b8]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-39a288b8]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-39a288b8]{display:flex;justify-content:center}.VPDoc .aside[data-v-39a288b8]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{max-width:1104px}}.container[data-v-39a288b8]{margin:0 auto;width:100%}.aside[data-v-39a288b8]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-39a288b8]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-39a288b8]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-39a288b8]::-webkit-scrollbar{display:none}.aside-curtain[data-v-39a288b8]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-39a288b8]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-39a288b8]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-39a288b8]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-39a288b8]{order:1;margin:0;min-width:640px}}.content-container[data-v-39a288b8]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-39a288b8]{max-width:688px}.VPButton[data-v-fa7799d5]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-fa7799d5]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-fa7799d5]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-fa7799d5]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-fa7799d5]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-fa7799d5]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-fa7799d5]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-fa7799d5]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-fa7799d5]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-fa7799d5]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-fa7799d5]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-fa7799d5]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-fa7799d5]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-8426fc1a]{display:none}.dark .VPImage.light[data-v-8426fc1a]{display:none}.VPHero[data-v-4f9c455b]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-4f9c455b]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-4f9c455b]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-4f9c455b]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-4f9c455b]{flex-direction:row}}.main[data-v-4f9c455b]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-4f9c455b]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-4f9c455b]{text-align:left}}@media (min-width: 960px){.main[data-v-4f9c455b]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-4f9c455b]{max-width:592px}}.heading[data-v-4f9c455b]{display:flex;flex-direction:column}.name[data-v-4f9c455b],.text[data-v-4f9c455b]{width:fit-content;max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-4f9c455b],.VPHero.has-image .text[data-v-4f9c455b]{margin:0 auto}.name[data-v-4f9c455b]{color:var(--vp-home-hero-name-color)}.clip[data-v-4f9c455b]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-4f9c455b],.text[data-v-4f9c455b]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-4f9c455b],.text[data-v-4f9c455b]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-4f9c455b],.VPHero.has-image .text[data-v-4f9c455b]{margin:0}}.tagline[data-v-4f9c455b]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-4f9c455b]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-4f9c455b]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-4f9c455b]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-4f9c455b]{margin:0}}.actions[data-v-4f9c455b]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-4f9c455b]{justify-content:center}@media (min-width: 640px){.actions[data-v-4f9c455b]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-4f9c455b]{justify-content:flex-start}}.action[data-v-4f9c455b]{flex-shrink:0;padding:6px}.image[data-v-4f9c455b]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-4f9c455b]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-4f9c455b]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-4f9c455b]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-4f9c455b]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-4f9c455b]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-4f9c455b]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-4f9c455b]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-4f9c455b]{width:320px;height:320px}}[data-v-4f9c455b] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-4f9c455b] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-4f9c455b] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-a3976bdc]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-a3976bdc]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-a3976bdc]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-a3976bdc]>.VPImage{margin-bottom:20px}.icon[data-v-a3976bdc]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-a3976bdc]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-a3976bdc]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-a3976bdc]{padding-top:8px}.link-text-value[data-v-a3976bdc]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-a3976bdc]{margin-left:6px}.VPFeatures[data-v-a6181336]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-a6181336]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-a6181336]{padding:0 64px}}.container[data-v-a6181336]{margin:0 auto;max-width:1152px}.items[data-v-a6181336]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-a6181336]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336]{width:50%}.item.grid-3[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-a6181336]{width:25%}}.container[data-v-8e2d4988]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-8e2d4988]{padding:0 48px}}@media (min-width: 960px){.container[data-v-8e2d4988]{width:100%;padding:0 64px}}.vp-doc[data-v-8e2d4988] .VPHomeSponsors,.vp-doc[data-v-8e2d4988] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,.vp-doc[data-v-8e2d4988] .VPTeamPage a{text-decoration:none}.VPHome[data-v-8b561e3d]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-8b561e3d]{margin-bottom:128px}}.VPContent[data-v-1428d186]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-1428d186]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-1428d186]{margin:0}@media (min-width: 960px){.VPContent[data-v-1428d186]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-1428d186]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-1428d186]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-e315a0ad]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-e315a0ad]{display:none}.VPFooter[data-v-e315a0ad] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-e315a0ad] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-e315a0ad]{padding:32px}}.container[data-v-e315a0ad]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-e315a0ad],.copyright[data-v-e315a0ad]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-8a42e2b4]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-8a42e2b4]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-8a42e2b4]{color:var(--vp-c-text-1)}.icon[data-v-8a42e2b4]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-8a42e2b4]{font-size:14px}.icon[data-v-8a42e2b4]{font-size:16px}}.open>.icon[data-v-8a42e2b4]{transform:rotate(90deg)}.items[data-v-8a42e2b4]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-8a42e2b4]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-8a42e2b4]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-8a42e2b4]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-8a42e2b4]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-8a42e2b4]{transition:all .2s ease-out}.flyout-leave-active[data-v-8a42e2b4]{transition:all .15s ease-in}.flyout-enter-from[data-v-8a42e2b4],.flyout-leave-to[data-v-8a42e2b4]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-a6f0e41e]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-a6f0e41e]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-a6f0e41e]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-a6f0e41e]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-a6f0e41e]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-a6f0e41e]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-a6f0e41e]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-a6f0e41e]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-a6f0e41e]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-a6f0e41e]{display:none}}.menu-icon[data-v-a6f0e41e]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 32px 11px}}.VPSwitch[data-v-1d5665e3]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-1d5665e3]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-1d5665e3]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-1d5665e3]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-1d5665e3] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-1d5665e3] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-5337faa4]{opacity:1}.moon[data-v-5337faa4],.dark .sun[data-v-5337faa4]{opacity:0}.dark .moon[data-v-5337faa4]{opacity:1}.dark .VPSwitchAppearance[data-v-5337faa4] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-6c893767]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-6c893767]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-35975db6]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-35975db6]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-35975db6]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-35975db6]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-b98bc113]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-b98bc113] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-b98bc113] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-b98bc113] .group:last-child{padding-bottom:0}.VPMenu[data-v-b98bc113] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-b98bc113] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-b98bc113] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-b98bc113] .action{padding-left:24px}.VPFlyout[data-v-cf11d7a2]{position:relative}.VPFlyout[data-v-cf11d7a2]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-cf11d7a2]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-cf11d7a2]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-cf11d7a2]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-cf11d7a2]{color:var(--vp-c-brand-2)}.button[aria-expanded=false]+.menu[data-v-cf11d7a2]{opacity:0;visibility:hidden;transform:translateY(0)}.VPFlyout:hover .menu[data-v-cf11d7a2],.button[aria-expanded=true]+.menu[data-v-cf11d7a2]{opacity:1;visibility:visible;transform:translateY(0)}.button[data-v-cf11d7a2]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-cf11d7a2]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-cf11d7a2]{margin-right:0;font-size:16px}.text-icon[data-v-cf11d7a2]{margin-left:4px;font-size:14px}.icon[data-v-cf11d7a2]{font-size:20px;transition:fill .25s}.menu[data-v-cf11d7a2]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-bd121fe5]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-bd121fe5]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-bd121fe5]>svg,.VPSocialLink[data-v-bd121fe5]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarExtra[data-v-bb2aa2f0]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-bb2aa2f0]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-bb2aa2f0]{display:none}}.trans-title[data-v-bb2aa2f0]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-bb2aa2f0],.item.social-links[data-v-bb2aa2f0]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-bb2aa2f0]{min-width:176px}.appearance-action[data-v-bb2aa2f0]{margin-right:-2px}.social-links-list[data-v-bb2aa2f0]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-e56f3d57]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-e56f3d57],.VPNavBarMenuLink[data-v-e56f3d57]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-dc692963]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-dc692963]{display:flex}}/*! @docsearch/css 3.8.2 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch-Button-Key--pressed{box-shadow:var(--docsearch-key-pressed-shadow);transform:translate3d(0,1px,0)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.title[data-v-1168a8e4]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-1168a8e4]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-1168a8e4]{border-bottom-color:var(--vp-c-divider)}}[data-v-1168a8e4] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-88af2de4]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-88af2de4]{display:flex;align-items:center}}.title[data-v-88af2de4]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-6aa21345]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .25s}.VPNavBar.screen-open[data-v-6aa21345]{transition:none;background-color:var(--vp-nav-bg-color);border-bottom:1px solid var(--vp-c-divider)}.VPNavBar[data-v-6aa21345]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-6aa21345]:not(.home){background-color:transparent}.VPNavBar[data-v-6aa21345]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-6aa21345]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-6aa21345]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-6aa21345]{padding:0}}.container[data-v-6aa21345]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-6aa21345],.container>.content[data-v-6aa21345]{pointer-events:none}.container[data-v-6aa21345] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-6aa21345]{max-width:100%}}.title[data-v-6aa21345]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-6aa21345]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-6aa21345]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-6aa21345]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-6aa21345]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-6aa21345]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-6aa21345]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-6aa21345]{column-gap:.5rem}}.menu+.translations[data-v-6aa21345]:before,.menu+.appearance[data-v-6aa21345]:before,.menu+.social-links[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before,.appearance+.social-links[data-v-6aa21345]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-6aa21345]:before,.translations+.appearance[data-v-6aa21345]:before{margin-right:16px}.appearance+.social-links[data-v-6aa21345]:before{margin-left:16px}.social-links[data-v-6aa21345]{margin-right:-8px}.divider[data-v-6aa21345]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-6aa21345]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-6aa21345]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-6aa21345]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-6aa21345]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-b44890b2]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-b44890b2]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-df37e6dd]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-df37e6dd]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-3e9c20e4]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-3e9c20e4]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-b9ab8c58]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-b9ab8c58]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-b9ab8c58]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-b9ab8c58]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-b9ab8c58]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-b9ab8c58]{transform:rotate(45deg)}.button[data-v-b9ab8c58]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-b9ab8c58]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-b9ab8c58]{transition:transform .25s}.group[data-v-b9ab8c58]:first-child{padding-top:0}.group+.group[data-v-b9ab8c58],.group+.item[data-v-b9ab8c58]{padding-top:4px}.VPNavScreenTranslations[data-v-858fe1a4]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-858fe1a4]{height:auto}.title[data-v-858fe1a4]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-858fe1a4]{font-size:16px}.icon.lang[data-v-858fe1a4]{margin-right:8px}.icon.chevron[data-v-858fe1a4]{margin-left:4px}.list[data-v-858fe1a4]{padding:4px 0 0 24px}.link[data-v-858fe1a4]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-f2779853]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .25s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-f2779853],.VPNavScreen.fade-leave-active[data-v-f2779853]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-f2779853],.VPNavScreen.fade-leave-active .container[data-v-f2779853]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-f2779853],.VPNavScreen.fade-leave-to[data-v-f2779853]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-f2779853],.VPNavScreen.fade-leave-to .container[data-v-f2779853]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-f2779853]{display:none}}.container[data-v-f2779853]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-f2779853],.menu+.appearance[data-v-f2779853],.translations+.appearance[data-v-f2779853]{margin-top:24px}.menu+.social-links[data-v-f2779853]{margin-top:16px}.appearance+.social-links[data-v-f2779853]{margin-top:16px}.VPNav[data-v-ae24b3ad]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-ae24b3ad]{position:fixed}}.VPSidebarItem.level-0[data-v-b3fd67f8]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-b3fd67f8]{padding-bottom:10px}.item[data-v-b3fd67f8]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-b3fd67f8]{cursor:pointer}.indicator[data-v-b3fd67f8]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-b3fd67f8],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-b3fd67f8]{background-color:var(--vp-c-brand-1)}.link[data-v-b3fd67f8]{display:flex;align-items:center;flex-grow:1}.text[data-v-b3fd67f8]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-b3fd67f8]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-b3fd67f8],.VPSidebarItem.level-2 .text[data-v-b3fd67f8],.VPSidebarItem.level-3 .text[data-v-b3fd67f8],.VPSidebarItem.level-4 .text[data-v-b3fd67f8],.VPSidebarItem.level-5 .text[data-v-b3fd67f8]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-b3fd67f8],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-b3fd67f8]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.has-active>.item>.text[data-v-b3fd67f8],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-b3fd67f8]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-b3fd67f8],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-b3fd67f8]{color:var(--vp-c-brand-1)}.caret[data-v-b3fd67f8]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-b3fd67f8]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-b3fd67f8]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-b3fd67f8]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-b3fd67f8]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-b3fd67f8],.VPSidebarItem.level-2 .items[data-v-b3fd67f8],.VPSidebarItem.level-3 .items[data-v-b3fd67f8],.VPSidebarItem.level-4 .items[data-v-b3fd67f8],.VPSidebarItem.level-5 .items[data-v-b3fd67f8]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-b3fd67f8]{display:none}.no-transition[data-v-c40bc020] .caret-icon{transition:none}.group+.group[data-v-c40bc020]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-c40bc020]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSidebar[data-v-319d5ca6]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-319d5ca6]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-319d5ca6]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-319d5ca6]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-319d5ca6]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-319d5ca6]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-319d5ca6]{outline:0}.VPSkipLink[data-v-0b0ada53]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-0b0ada53]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-0b0ada53]{top:14px;left:16px}}.Layout[data-v-5d98c3a5]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3d121b4a]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-3d121b4a]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{margin:128px 0}}.VPHomeSponsors[data-v-3d121b4a]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 64px}}.container[data-v-3d121b4a]{margin:0 auto;max-width:1152px}.love[data-v-3d121b4a]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-3d121b4a]{display:inline-block}.message[data-v-3d121b4a]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3d121b4a]{padding-top:32px}.action[data-v-3d121b4a]{padding-top:40px;text-align:center}.VPTeamMembersItem[data-v-f3fa364a]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f3fa364a]{padding:32px}.VPTeamMembersItem.small .data[data-v-f3fa364a]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f3fa364a]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f3fa364a]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f3fa364a]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f3fa364a]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f3fa364a]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f3fa364a]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f3fa364a]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f3fa364a]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f3fa364a]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f3fa364a]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f3fa364a]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f3fa364a]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f3fa364a]{text-align:center}.avatar[data-v-f3fa364a]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f3fa364a]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f3fa364a]{margin:0;font-weight:600}.affiliation[data-v-f3fa364a]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f3fa364a]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f3fa364a]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f3fa364a]{margin:0 auto}.desc[data-v-f3fa364a] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f3fa364a]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f3fa364a]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f3fa364a]:hover,.sp .sp-link.link[data-v-f3fa364a]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f3fa364a]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4]{max-width:876px}.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4]{max-width:760px}.container[data-v-6cb0dbc4]{display:grid;gap:24px;margin:0 auto;max-width:1152px}.VPTeamPage[data-v-7c57f839]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-7c57f839]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-7c57f839-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-7c57f839-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:96px}}.VPTeamMembers[data-v-7c57f839-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 64px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );--vp-home-hero-image-background-image: linear-gradient( -45deg, #bd34fe 50%, #47caff 50% );--vp-home-hero-image-filter: blur(44px)}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(68px)}}:root{--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-brand-soft);--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft)}.DocSearch{--docsearch-primary-color: var(--vp-c-brand-1) !important}.VPDoc .container{margin:0!important}@media (min-width: 960px){.VPDoc:not(.has-sidebar) .content{max-width:1552px!important}}.VPDoc.has-aside .content-container{max-width:1488px!important}@media (min-width: 960px){.VPDoc:not(.has-sidebar) .container{display:flex;justify-content:center;max-width:1562px!important}}.aside-container{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 10px)!important;width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.vp-doc h2{margin:0 0 16px;padding-top:24px;border:none}.VPLocalSearchBox[data-v-ce626c7c]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-ce626c7c]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-ce626c7c]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-ce626c7c]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-ce626c7c]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-ce626c7c]{padding:0 8px}}.search-bar[data-v-ce626c7c]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-ce626c7c]{display:block;font-size:18px}.navigate-icon[data-v-ce626c7c]{display:block;font-size:14px}.search-icon[data-v-ce626c7c]{margin:8px}@media (max-width: 767px){.search-icon[data-v-ce626c7c]{display:none}}.search-input[data-v-ce626c7c]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-ce626c7c]{padding:6px 4px}}.search-actions[data-v-ce626c7c]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-ce626c7c]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-ce626c7c]{display:none}}.search-actions button[data-v-ce626c7c]{padding:8px}.search-actions button[data-v-ce626c7c]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-ce626c7c]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-ce626c7c]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-ce626c7c]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-ce626c7c]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-ce626c7c]{display:none}}.search-keyboard-shortcuts kbd[data-v-ce626c7c]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-ce626c7c]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-ce626c7c]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-ce626c7c]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-ce626c7c]{margin:8px}}.titles[data-v-ce626c7c]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-ce626c7c]{display:flex;align-items:center;gap:4px}.title.main[data-v-ce626c7c]{font-weight:500}.title-icon[data-v-ce626c7c]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-ce626c7c]{opacity:.5}.result.selected[data-v-ce626c7c]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-ce626c7c]{position:relative}.excerpt[data-v-ce626c7c]{opacity:50%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;margin-top:4px}.result.selected .excerpt[data-v-ce626c7c]{opacity:1}.excerpt[data-v-ce626c7c] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-ce626c7c] mark,.excerpt[data-v-ce626c7c] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-ce626c7c] .vp-code-group .tabs{display:none}.excerpt[data-v-ce626c7c] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-ce626c7c]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-ce626c7c]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-ce626c7c],.result.selected .title-icon[data-v-ce626c7c]{color:var(--vp-c-brand-1)!important}.no-results[data-v-ce626c7c]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-ce626c7c]{flex:none} diff --git a/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.js b/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.js new file mode 100644 index 0000000..58b9f23 --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.js @@ -0,0 +1,292 @@ +import{_ as n,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"git 使用汇总","description":"","frontmatter":{},"headers":[],"relativePath":"utils/git-tips.md","filePath":"utils/git-tips.md"}'),i={name:"utils/git-tips.md"};function l(t,s,c,o,r,g){return p(),a("div",null,s[0]||(s[0]=[e(`

git 使用汇总

Git配置多个SSH-Key

当有多个git账号时,比如:

a. 一个gitlab,用于公司内部的工作开发;

b. 一个github,用于自己进行一些开发活动;

解决方法

(1) 生成一个公司用的SSH-Key

# 在~/.ssh/目录会生成gitlab_id-rsa和gitlab_id-rsa.pub私钥和公钥。我们将gitlab_id-rsa.pub中的内容粘帖到公司GitLab服务器的SSH-key的配置中
+$ ssh-keygen -t rsa -C 'xxxxx@company.com' -f ~/.ssh/gitlab_id_rsa

(2) 生成一个github用的SSH-Key

ssh-keygen -t rsa -C 'xxxxx@qq.com' -f ~/.ssh/github_id_rsa

(3) 在 ~/.ssh 目录下新建一个config文件,添加如下内容(其中Host和HostName填写git服务器的域名,IdentityFile指定私钥的路径)

# 添加config配置文件
+# vi ~/.ssh/config
+# 或者
+# touch ~/.ssh/config
+
+# 文件内容如下
+# gitlab
+Host gitlab.com
+HostName gitlab.com
+PreferredAuthentications publickey
+IdentityFile ~/.ssh/gitlab_id_rsa
+# github
+Host github.com
+HostName github.com
+PreferredAuthentications publickey
+IdentityFile ~/.ssh/github_id_rsa

(4) 用ssh命令分别测试

$ ssh -T git@gitlab.com
+$ ssh -T git@github.com

常见的git命令

新建代码库

# 在当前目录新建一个Git代码库
+$ git init
+
+# 新建一个目录,将其初始化为Git代码库
+$ git init [project-name]
+
+# 下载一个项目和它的整个代码历史
+$ git clone [url]

配置

# 显示当前的Git配置
+$ git config --list
+
+# 编辑Git配置文件
+$ git config -e [--global]
+
+# 设置提交代码时的用户信息
+$ git config [--global] user.name "[name]"
+$ git config [--global] user.email "[email address]"

增加/删除文件

# 添加指定文件到暂存区
+$ git add [file1] [file2] ...
+
+# 添加指定目录到暂存区,包括子目录
+$ git add [dir]
+
+# 添加当前目录的所有文件到暂存区
+$ git add .
+
+# 添加每个变化前,都会要求确认
+# 对于同一个文件的多处变化,可以实现分次提交
+$ git add -p
+
+# 删除工作区文件,并且将这次删除放入暂存区
+$ git rm [file1] [file2] ...
+
+# 停止追踪指定文件,但该文件会保留在工作区
+$ git rm --cached [file]
+
+# 改名文件,并且将这个改名放入暂存区
+$ git mv [file-original] [file-renamed]

代码提交

# 提交暂存区到仓库区
+$ git commit -m [message]
+
+# 提交暂存区的指定文件到仓库区
+$ git commit [file1] [file2] ... -m [message]
+
+# 提交工作区自上次commit之后的变化,直接到仓库区
+$ git commit -a
+
+# 提交时显示所有diff信息
+$ git commit -v
+
+# 使用一次新的commit,替代上一次提交
+# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
+$ git commit --amend -m [message]
+
+# 重做上一次commit,并包括指定文件的新变化
+$ git commit --amend [file1] [file2] ...

分支

# 列出所有本地分支
+$ git branch
+
+# 列出所有远程分支
+$ git branch -r
+
+# 列出所有本地分支和远程分支
+$ git branch -a
+
+# 新建一个分支,但依然停留在当前分支
+$ git branch [branch-name]
+
+# 新建一个分支,并切换到该分支
+$ git checkout -b [branch]
+
+# 新建一个分支,指向指定commit
+$ git branch [branch] [commit]
+
+# 新建一个分支,与指定的远程分支建立追踪关系
+$ git branch --track [branch] [remote-branch]
+
+# 切换到指定分支,并更新工作区
+$ git checkout [branch-name]
+
+# 切换到上一个分支
+$ git checkout -
+
+# 建立追踪关系,在现有分支与指定的远程分支之间
+$ git branch --set-upstream [branch] [remote-branch]
+
+# 合并指定分支到当前分支
+$ git merge [branch]
+
+# 选择一个commit,合并进当前分支
+$ git cherry-pick [commit]
+
+# 删除分支
+$ git branch -d [branch-name]
+
+# 删除远程分支
+$ git push origin --delete [branch-name]
+$ git branch -dr [remote/branch]

标签

# 列出所有tag
+$ git tag
+
+# 新建一个tag在当前commit
+$ git tag [tag]
+
+# 新建一个tag在指定commit
+$ git tag [tag] [commit]
+
+# 删除本地tag
+$ git tag -d [tag]
+
+# 删除远程tag
+$ git push origin :refs/tags/[tagName]
+
+# 查看tag信息
+$ git show [tag]
+
+# 提交指定tag
+$ git push [remote] [tag]
+
+# 提交所有tag
+$ git push [remote] --tags
+
+# 新建一个分支,指向某个tag
+$ git checkout -b [branch] [tag]
+
+# 切换为由远程创建的分支
+$ git checkout -b [branch] [remote/branch]

查看信息

# 显示有变更的文件
+$ git status
+
+# 显示当前分支的版本历史
+$ git log

远程同步

# 下载远程仓库的所有变动
+$ git fetch [remote]
+
+# 显示所有远程仓库
+$ git remote -v
+
+# 显示某个远程仓库的信息
+$ git remote show [remote]
+
+# 增加一个新的远程仓库,并命名
+$ git remote add [shortname] [url]
+
+# 更新远程仓库地址
+$ git remote set-url [shortname] [url]
+$ git remote set-url origin http://originproject.git
+
+# 修改远程仓库名
+$ git remote rename [current-shortname] [new-shortname]
+
+# 取回远程仓库的变化,并与本地分支合并,
+$ git pull [remote] [branch]
+
+# 上传本地指定分支到远程仓库,默认提交到与本地分支对应的远程分支上
+$ git push [remote] [branch]
+
+上传本地指定分支到远程仓库,创建与到与本地分支对应的远程分支上
+$  git push --set-upstream [remote] [branch]
+
+# 强行推送当前分支到远程仓库,即使有冲突
+$ git push [remote] --force
+
+# 推送所有分支到远程仓库
+$ git push [remote] --all
+
+# 推送某一个commit 到远程仓库
+$ git push [remote name] [commit hash]:[remote branch name]
+
+# 推送所有tag到远程仓库
+$ git push [remote] --tags

回滚

# 回退到上个版本
+$ git reset --hard HEAD^
+# 回退到前3次提交之前,以此类推,回退到n次提交之前  
+$ git reset --hard HEAD~3
+# 退到/进到 指定commit的sha码        
+$ git reset --hard [commit_id] 
+# 强制推到远程
+$ git push origin HEAD --force

date: 2019-04-15 14:00:00 author: "Gao Fei"

pull request 基本操作流程

<!--远程代码-->
+$ git remote -v
+
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (fetch)
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (push)
$ git remote add http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git
+
+usage: git remote add [<options>] <name> <url>
+
+   
+\`-f, --fetch           fetch the remote branches
+    --tags                import all tags and associated objects when fetching
+                          or do not fetch any tag at all (--no-tags)
+    -t, --track <branch>  branch(es) to track
+    -m, --master <branch>
+                          master branch
+    --mirror[=<push|fetch>]
+                          set up remote as a mirror to push to or fetch from\`
+                          
+$ git remote add upstream http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git
+
+$ git remote -v
+
+origin	http://58\`.250.71.52:8081/gaofei/FSMobileAssistant.git (fetch)
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (push)
+upstream	http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git (fetch)
+upstream	http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git (push)\`
+bogon:FSMobileAssistant awei$ git fetch --all
+
+\`Fetching origin
+Fetching upstream
+remote: Counting objects: 166, done.
+remote: Compressing objects: 100% (98/98), done.
+remote: Total 166 (delta 124), reused 99 (delta 66)
+Receiving objects: 100% (166/166), 69.78 KiB | 0 bytes/s, done.
+Resolving deltas: 100% (124/124), completed with 48 local objects.
+From http://58.250.71.52:8081/iOS_Group/FSMobileAssistant
+ * [new branch]      master     -> upstream/master
+ * [new branch]      mvvm       -> upstream/mvvm\`
+$ git merge upstream/master origin/master
+\`Auto-merging MobileAssistant/Vendors/XHDatePicker/XHDatePickerView.m
+Auto-merging MobileAssistant/Vendors/FSAlertTools/FSAlertTools.m
+Auto-merging MobileAssistant/Vendors/FSAlertTools/FSAlertTools.h
+CONFLICT (modify/delete): MobileAssistant/Util/AlertUtil.m deleted in upstream/master and modified in HEAD. Version HEAD of MobileAssistant/Util/AlertUtil.m left in tree.
+CONFLICT (modify/delete): MobileAssistant/Util/AlertUtil.h deleted in upstream/master and modified in HEAD. Version HEAD of MobileAssistant/Util/AlertUtil.h left in tree.
+Auto-merging MobileAssistant/Sections/Personal Center/ViewController/AboutVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/TouchIDUtil/TouchIDUtil.m
+Auto-merging MobileAssistant/Sections/Personal Center/TouchIDUtil/KeyChainManager.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/SetNewPwdVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/RegisterVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/PwdInputVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/ForgetPwdVC.m
+Auto-merging MobileAssistant/Sections/Main/CompanyInfo/Controller/FSCompanyInfoController.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailReasonCell.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailNameCell.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailDescriptionCell.m
+Automatic merge failed; fix conflicts and then commit the result.\`
整体流程如下:
+第一步:
+bogon:FSMobileAssistant awei$ git add .
+第二步:
+bogon:FSMobileAssistant awei$ git commit -m "sure delete AlertUtil"
+[master b989627] sure delete AlertUtil
+第三步:
+bogon:FSMobileAssistant awei$ git fetch --all
+Fetching origin
+Fetching upstream
+第四步:
+bogon:FSMobileAssistant awei$ git merge upstream/master origin/master
+Already up-to-date.
+第五步:
+bogon:FSMobileAssistant awei$ git push\`
+\`Counting objects: 209, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (84/84), done.
+Writing objects: 100% (209/209), 171.21 KiB | 0 bytes/s, done.
+Total 209 (delta 153), reused 162 (delta 123)
+To http://58.250.71.52:8081/gaofei/FSMobileAssistant.git
+   1e7ae50..b989627  master -> master
+bogon:FSMobileAssistant awei$

一. 在合并远程代码的时候,或许会出现以下问题:

I'm in the process of learning github on mac (command-line) and whenever I do git pull origin master i get this

# Please enter a commit message to explain why this merge is necessary,
+# especially if it merges an updated upstream into a topic branch.
+#
+# Lines starting with '#' will be ignored, and an empty message aborts
+# the commit.
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+".git/MERGE_MSG" 7L, 293C

两种解决方式: 方式一:

You're in the text editor, vim! It's a modal text editor, so you would need to:

	1.	Press ==i== to enter insert mode.
+	2.	Now you can type your message, as if you were in a normal (non-modal) text editor.
+	3.	Press ==esc== to go back to command mode.
+	4.	Then type *:w* followed by ==enter== to save.
+	5.	Finally *:q* followed by ==enter== to quit.

方式二:

Make it simple.
+
+Type *:wq* and ==enter==

2017-04-20 高飞

`,47)]))}const m=n(i,[["render",l]]);export{d as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.lean.js b/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.lean.js new file mode 100644 index 0000000..a5923ab --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_git-tips.md.Cst2ESAN.lean.js @@ -0,0 +1 @@ +import{_ as n,c as a,o as p,ag as e}from"./chunks/framework.BHpayLOB.js";const d=JSON.parse('{"title":"git 使用汇总","description":"","frontmatter":{},"headers":[],"relativePath":"utils/git-tips.md","filePath":"utils/git-tips.md"}'),i={name:"utils/git-tips.md"};function l(t,s,c,o,r,g){return p(),a("div",null,s[0]||(s[0]=[e("",47)]))}const m=n(i,[["render",l]]);export{d as __pageData,m as default}; diff --git a/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.js b/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.js new file mode 100644 index 0000000..710e081 --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as r,j as a,a as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Mac Tips","description":"","frontmatter":{},"headers":[],"relativePath":"utils/mac-tips.md","filePath":"utils/mac-tips.md"}'),c={name:"utils/mac-tips.md"};function o(l,e,n,p,d,m){return r(),i("div",null,e[0]||(e[0]=[a("h1",{id:"mac-tips",tabindex:"-1"},[t("Mac Tips "),a("a",{class:"header-anchor",href:"#mac-tips","aria-label":'Permalink to "Mac Tips"'},"​")],-1),a("h2",{id:"显示任何来源",tabindex:"-1"},[t("显示任何来源 "),a("a",{class:"header-anchor",href:"#显示任何来源","aria-label":'Permalink to "显示任何来源"'},"​")],-1),a("p",null,"macos 安全性与隐私中设置 显示 任何来源 使用如下命令: sudo spctl --master-disable",-1),a("p",null,'date: 2016-04-28 16:00:00 author: "Gao Fei"',-1)]))}const f=s(c,[["render",o]]);export{h as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.lean.js b/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.lean.js new file mode 100644 index 0000000..710e081 --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_mac-tips.md.BSmTDcFx.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as r,j as a,a as t}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Mac Tips","description":"","frontmatter":{},"headers":[],"relativePath":"utils/mac-tips.md","filePath":"utils/mac-tips.md"}'),c={name:"utils/mac-tips.md"};function o(l,e,n,p,d,m){return r(),i("div",null,e[0]||(e[0]=[a("h1",{id:"mac-tips",tabindex:"-1"},[t("Mac Tips "),a("a",{class:"header-anchor",href:"#mac-tips","aria-label":'Permalink to "Mac Tips"'},"​")],-1),a("h2",{id:"显示任何来源",tabindex:"-1"},[t("显示任何来源 "),a("a",{class:"header-anchor",href:"#显示任何来源","aria-label":'Permalink to "显示任何来源"'},"​")],-1),a("p",null,"macos 安全性与隐私中设置 显示 任何来源 使用如下命令: sudo spctl --master-disable",-1),a("p",null,'date: 2016-04-28 16:00:00 author: "Gao Fei"',-1)]))}const f=s(c,[["render",o]]);export{h as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.js b/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.js new file mode 100644 index 0000000..7684285 --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.js @@ -0,0 +1,5 @@ +import{_ as o,c as a,o as t,ag as s}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Xcode Tips","description":"","frontmatter":{},"headers":[],"relativePath":"utils/xcode-tips.md","filePath":"utils/xcode-tips.md"}'),i={name:"utils/xcode-tips.md"};function n(r,e,c,l,d,p){return t(),a("div",null,e[0]||(e[0]=[s(`

Xcode Tips

Xcode IDE

Xcode: symbol(s) not found for architecture armv7

log : Undefined symbols for architecture armv7:"OBJC_CLASS$_ViewController", referenced from:objc-class-ref in AppDelegate.o

ld: symbol(s) not found for architecture armv7

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Check if your Compile Sources section within the Build Phases of your project shows ViewController.m

参考: http://stackoverflow.com/questions/12522571/xcode-symbols-not-found-for-architecture-armv7

How to trap on UIViewAlertForUnsatisfiableConstraints?

I added UIViewAlertForUnsatisfiableConstraints symbolic breakpoint with suggested action: Obj-C project

po [[UIWindow keyWindow] _autolayoutTrace]

Swift project

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

参考:http://stackoverflow.com/questions/26389273/how-to-trap-on-uiviewalertforunsatisfiableconstraints

How to define Preprocessor Macros in Xcode

  1. Find TARGETS -> Build Settings , search Preprocessor Macros , By default we have tow:Debug and Release, Notice that the Dubug configuration already has a Macro defined - it's called DEBUG=1. therefore out of the box you can already check in your code if it has been complied with the Debug or Release configuration.
  2. To define your own Macro, click the little plus sign next Debug (and Release) and add something specific. I’m using IS_PRO=1, but you can choose anything you like really. I don’t know if you can set values other than boolean. Make sure you set your Macro in BOTH configurations, otherwise you’ll find different results when you submit your app
  3. Now that our Macro is defined, you can check if it’s present in your code like so:
#ifdef IS_PRO
+    NSLog(@&quot;It&#039;s the PRO version&quot;);
+#else
+    NSLog(@&quot;Must be the LITE version&quot;);
+#endif

date: 2017-03-28 16:00:00 author: "Gao Fei"

`,18)]))}const f=o(i,[["render",n]]);export{h as __pageData,f as default}; diff --git a/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.lean.js b/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.lean.js new file mode 100644 index 0000000..822037d --- /dev/null +++ b/docs/.vitepress/dist/assets/utils_xcode-tips.md.D-lHTeox.lean.js @@ -0,0 +1 @@ +import{_ as o,c as a,o as t,ag as s}from"./chunks/framework.BHpayLOB.js";const h=JSON.parse('{"title":"Xcode Tips","description":"","frontmatter":{},"headers":[],"relativePath":"utils/xcode-tips.md","filePath":"utils/xcode-tips.md"}'),i={name:"utils/xcode-tips.md"};function n(r,e,c,l,d,p){return t(),a("div",null,e[0]||(e[0]=[s("",18)]))}const f=o(i,[["render",n]]);export{h as __pageData,f as default}; diff --git a/docs/.vitepress/dist/backend/container/tomcat.html b/docs/.vitepress/dist/backend/container/tomcat.html new file mode 100644 index 0000000..8a9ee75 --- /dev/null +++ b/docs/.vitepress/dist/backend/container/tomcat.html @@ -0,0 +1,39 @@ + + + + + + Tomcat 介绍 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Tomcat 介绍

Tomcat用户密码 修改conf-> tomcat-users.xml 文件,添加角色、用户、密码

<tomcat-users>
+<!--
+  NOTE:  By default, no user is included in the "manager-gui" role required
+  to operate the "/manager/html" web application.  If you wish to use this app,
+  you must define such a user - the username and password are arbitrary. It is
+  strongly recommended that you do NOT use one of the users in the commented out
+  section below since they are intended for use with the examples web
+  application.
+-->
+
+<role rolename="manager-gui"/>
+<role rolename="manager-script"/>
+<user username="tomcat" password="123456" roles="manager-gui,manager-script"/>
+
+</tomcat-users>

注意:使用Linux 开发过程 需要修改tomcat的访问权限

1.get 请求传送的参数包含中文字符

常用的解决方式: 1.当客户端使用的UTF-8编码 将中文参数传送过来时,tomcat 默认采用iso8859-1解码 ''' String name = request.getParameter("name"); name = new String(name.getBytes("iso8859-1"),"utf-8"); '''

2.在tomcat中找到server.xml文件 增加字段 URIEncoding useBodyEncodingForURI '''

'''

date: 2018-08-12 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/backend/release/maven-first.html b/docs/.vitepress/dist/backend/release/maven-first.html new file mode 100644 index 0000000..2611e7e --- /dev/null +++ b/docs/.vitepress/dist/backend/release/maven-first.html @@ -0,0 +1,28 @@ + + + + + + maven 介绍 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

maven 介绍

maven 安装

  1. 下载 maven
  2. 解压
mv apache-maven-3.5.4 /usr/local/maven3
# maven home
+MAVEN_HOME=/usr/local/maven3
+export MAVEN_HOME
+export PATH=$PATH:$MAVEN_HOME/bin

date: 2017-11-27 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/background.svg b/docs/.vitepress/dist/background.svg new file mode 100644 index 0000000..de0d154 --- /dev/null +++ b/docs/.vitepress/dist/background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/.vitepress/dist/engineering/index.html b/docs/.vitepress/dist/engineering/index.html new file mode 100644 index 0000000..086f1e4 --- /dev/null +++ b/docs/.vitepress/dist/engineering/index.html @@ -0,0 +1,25 @@ + + + + + + 前端工程化 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

前端工程化

待更新...

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/base/xml-tips.html b/docs/.vitepress/dist/frontend/base/xml-tips.html new file mode 100644 index 0000000..bffefa8 --- /dev/null +++ b/docs/.vitepress/dist/frontend/base/xml-tips.html @@ -0,0 +1,25 @@ + + + + + + XML 常见转义字符 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

XML 常见转义字符

XML常见用转义字符

html 转义字符

字符转义字符描述
&&amp;
<&lt;小于号
>&gt;大于号
"&quot;双引号
'&apos;单引号
&nbsp;空格
©&copy;版权符
®&reg;注册符

在iOS 开发中,如遇到native与js交互的时候,使用js向web传值的时候就会遇到js报错。使用转义字符转义后的字符串就可以正常的传递。

date: 2019-04-25 10:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/apple-update-cert.html b/docs/.vitepress/dist/frontend/ios/apple-update-cert.html new file mode 100644 index 0000000..ce7a1c5 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/apple-update-cert.html @@ -0,0 +1,25 @@ + + + + + + 更新 App store 发布证书 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

更新 App store 发布证书

分三步去更新

  1. 首先找到已过期的APP ID;
  2. 根据APP ID重新生成Certifictes;
  3. 更新Provisioning Profiles.

示例

1.确定已过期的 APP ID

1.1 找到已过期或者即将过期的 APP ID(Xcode 中为bundle id),位于图图1-1中3所在位置。将该 APP ID (以下简称id)记录下来。 图1-1

2.根据APP ID重新生成Certifictes

2.1 点击 Certificates 中的 Production可以看到所有的生产环境的证书,同时也可以看到是否过期。选择右上角的新建+,如下图所示。

选择证书的适用的场景, (1)Development 对应 xcode 中的debug环境,开发调试的使用,包含了推送与非推送版本。 (2)Production 对应 xcode 中的 release 环境,也即是上线 app store 的环境, 常用的是有不带推送的、带推送的、带apple pay的证书。 示例就以生产中带推送的做参考,选择 Apple Push Notification, 点击Continue。 选择需要更新的APP ID, 点击Continue 出现创建CSR文件的界面,里面说明了创建的步骤。下面我们按照步骤创建CSR。 在mac应用程序中找到 “钥匙串访问”,打开“钥匙串访问”app, 在导航栏中点击“钥匙串访问”-> "证书助理" -> "从证书颁发机构请求证书", 输入邮箱地址,常用名称,选择存储到磁盘,点击“继续”.其中常用名称可以采用公司名称+app名称+环境名 输入名称名称, 选择存储位置, 点击"存储". 将请求下来的的CSR证书保存在桌面上。 回到创建证书的页面,点击"Continu" 出现选择证书的页面,点击"Choose File..." 找到之前创建的CSR文件,点击"选取" 上传CSR文件, 点击“Continue” 上传完成之后,证书就生成完毕, 点击"Download",下载到本地磁盘。 下载完毕后会得到一个aps.cer证书, 但是不能直接发给别人使用, 需要双击cer文件,安装到钥匙串中,然后导出为.p12文件.

接下来说明一下导出P12文件给服务器使用。 在钥匙串中找到对应id的证书(可以通过id+证书名称确定) 选择导出“Apple Push Service: xxxxx” 弹出保存框, 输入存储名称,选择存储位置,点击"存储"。存储名称建议使用公司名称+app名称+环境+apns的形式,方便以管理。 输入导出的密码, 此密码用于其他人员读取P12文件时使用。 输入电脑登录用户的密码,点击“允许”。此处成功导出P12推送证书。备注:有的服务器只识别pem格式的文件,需要将P12格式转换为pem格式的。 再次回到apple deleloper 页面,找到已过期的的描述文件(Provisioning Profiles),点击“Edit”, 选择对应的App ID 以及 Certificates, 点击 “Generate” 到此新的Provisioning Profiles 已生成,点击"Download" 刚才已过期的 Provisioning Profiles 的 Status has changed to Active 按照同样的方式,更新development 下的Certificates & Provisioning Profiles 一共产生了5个文件,如下图所示

序列示例名称说明
1BOCI_appName_development_apns.p12Apple Push Development Certificatexcode debug app
2BOCI_appName_distribution_apns.p12Apple Push Production Certificatexcode release app/backend push server
3BOCI_appName_distribution_apns.mobileprovisionProduction Provisioning Profilesxcode release app
4BOCI_appName_development_apns.mobileprovisionDevelopment Provisioning Profilesxcode debug app
5BOCI_appName_distribution_apns.certSigningRequestCSR自己保留

将1-4的文件发送给开发人员,开发人员根据新的证书重新打包ipa,上线发布app就可以了。

2019-04-28

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/appstore-share.html b/docs/.vitepress/dist/frontend/ios/appstore-share.html new file mode 100644 index 0000000..88cbbc5 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/appstore-share.html @@ -0,0 +1,25 @@ + + + + + + Appstore | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Appstore


##关于app强制更新的itunes地址

通过微信的测试结果 https://itunes.apple.com/cn/app/we--chat/id414478124?mt=8https://itunes.apple.com/cn/app/id414478124?mt=8https://itunes.apple.com/cn/app/微信/id414478124?mt=8 都可以找到app的下载地址 格式如下 https://itunes.apple.com/cn/app/应用名称/id?mt=8 应用的名称:可以没有 id414478124 :必须有,id后面的数值 为Apple ID,开发者账号中可以查看到该应用的地址 mt=8 :参数可以没有,也可以等于其他值,即mt=7等等。

date: 2017-09-15 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/autoPackage-tips.html b/docs/.vitepress/dist/frontend/ios/autoPackage-tips.html new file mode 100644 index 0000000..6dbd24d --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/autoPackage-tips.html @@ -0,0 +1,32 @@ + + + + + + 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

#自动打包测试流程 1、将AutoPackageShell文件夹放到项目根目录下 2、打开autoPackageShell.sh文件,修改下列项目参数成你要打包的项目:

# 是否编译工作空间 (例:若是用Cocopods管理的.xcworkspace项目,赋值true;用Xcode默认创建的.xcodeproj,赋值false)
+is_workspace="false"
+#scheme名(一般是Target名)
+scheme_name="MobileAssistant_SIT"
+#指定项目名称
+project_name="MobileAssistant"
+# 指定要打包编译的方式 : Release,Debug...
+build_configuration="Release"

3、打开exportOptionsPlist.plist文件,把teamID改成打包证书的teamID

4、打开终端,cd到AutoPackageShell文件夹,输入命令 sh autoPackageShell.sh  回车

备注:Xcode 安装了多个版本之后,可以将目标打包的Xcode名称(eg:Xcode8.2.app)改为Xcode.app teamID可以在xxx.xcodeproj包文件中==project.pbxproj==,找到==DEVELOPMENT_TEAM==的值

date: 2017-06-01 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/cocoapods.html b/docs/.vitepress/dist/frontend/ios/cocoapods.html new file mode 100644 index 0000000..f19a48a --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/cocoapods.html @@ -0,0 +1,50 @@ + + + + + + cocoapods 入门 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

cocoapods 入门

COCOAPODS 入门

1. cocoapods

特点

# 查看gem源地址,如果显示为默认源 https://rubygems.org/,需要考虑替换
+$ $gem sources -l
+# 移除系统 ruby 默认源
+$gem sources --remove https://rubygems.org/
+# 使用新的源
+$gem source -a https://gems.ruby-china.com
+# 验证是否安装成功
+$gem sources -l
+# 安装最新版本
+$sudo gem install -n /usr/local/bin cocoapods
+
+# 安装指定版本
+$sudo gem install -n /usr/local/bin cocoapods -v 1.0.0
+# 安装
+$pod setup

2. 初始化项目

cd 到需要创建项目的目录下
+$ ng new <projectname>
+# 1. 先创建,再安装
+$ ng new <projectname> --skip-install
+$ cd <projectname>
+$ cnpm install
+
+#运行
+$ ng serve --open
+
+#创建组件,在app目录下,创建components目录并创建home组件
+$ ng g component components/home

date: 2020-03-24 14:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/download-share.html b/docs/.vitepress/dist/frontend/ios/download-share.html new file mode 100644 index 0000000..782970e --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/download-share.html @@ -0,0 +1,31 @@ + + + + + + Download issues | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Download issues

下载问题

  • (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location; 使用该方法的时候,注意事项: 1. location 为一个零时的目录,在当前线程中出了{},就会立即清除。 2. 如果下载的delegate队列为 [NSOperationQueue mainQueue],在该方法中使用异步队列复制或移动下载的零时文件(CFNetworkDownload_OCZZDW.tmp)时,会提示找不到location目录(该零时文件)。 3. 如果下载的队列为[[NSOperationQueue alloc] init],该方法已经在异步队列中,记得在主队列中返回数据
			// NSOperation
+			[[NSOperationQueue mainQueue] addOperationWithBlock:^{
+       		 // 需要回调的结果
+    		}];
			// GCD
+			dispatch_barrier_async(dispatch_get_main_queue(), ^{
+        		// 需要回调的结果
+    		});

NSOperation 的使用

load...

date: 2017-09-18 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/flutter.html b/docs/.vitepress/dist/frontend/ios/flutter.html new file mode 100644 index 0000000..7d1336a --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/flutter.html @@ -0,0 +1,39 @@ + + + + + + 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Flutter 入门

1. Flutter 介绍

  • 三重缓存
  • Skia 渲染引擎
  • Dart 语言学习
  • Flutter 学习
  1. 下载 flutter SDK

  2. 配置环境变量, 在~/.bash_profile 下增加如下内容:

# flutter
+#国内用户需要设置
+export PUB_HOSTED_URL=https://pub.flutter-io.cn
+export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+# flutter bin
+export FLUTTER_HOME=/Users/gaofei/development/flutter/bin
+# dart bin
+export DART_HOME=$FLUTTER_HOME/cache/dart-sdk/bin
+export PATH=$FLUTTER_HOME:$PATH
+export PATH="${DART_HOME}:${PATH}"

在环境配置完毕后,一般是重新电脑才会生效,如果想要立即生效,执行以下指令

source <相应文件配置文件>
+
+#示例
+source ~/.bash_profile

注意: 如果你使用的是zsh,终端启动时 ~/.bash_profile 将不会被加载,解决办法就是修改 ~/.zshrc ,在其中添加与 ~/.bash_profile 内相同的环境

vi ~/.zshrc
+# 输入环境后保存,然后再启动
+source ~/.zshrc

2. Flutter

添加的仓库包括 http://apt.saurik.com

3. Dart

3.1 变量 var const final dynamic 定义字符串,可以是 单引号,双引号,三引号 ${} 替换变量 集合 接口与抽象类 函数的返回值 函数的可选参数 - 位置可选参数[],命名可选参数{} 函数只有可选参数 有默认值 没有的函数的重载 函数是一等公民,函数A可以作为另外一个B的参数,也可以作为函数B的返回值。 匿名函数,箭头函数(函数体只有1行);

赋值运算符 ??= 当原来的变量有值时,就不执行 ?? 前面的数据有值,那么就使用??前面的数据,相当于三目运算符的简写 级联运算符

面向对象 类

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/framework-share.html b/docs/.vitepress/dist/frontend/ios/framework-share.html new file mode 100644 index 0000000..f729508 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/framework-share.html @@ -0,0 +1,25 @@ + + + + + + Cocoa Touch Framework | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Cocoa Touch Framework

###打包framework(Cocoa Touch Framework)

xcode打包需要配置

1.检查基本的配置

2.选择支持的最低版本

  1. 改为静态打包(对于ios8以上的系统,可以使用动态库(Dynamic Library))
  1. 导入工程中.m与 .h文件

合并模拟器与真机版本

在终端输入

lipo -create 【模拟器打包path】 【真机打包path】 -output 【导出兼容版本path】 如下: lipo -create /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/Release-iphonesimulator/FSNetworkAccesser.framework/FSNetworkAccesser /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/Release-iphoneos/FSNetworkAccesser.framework/FSNetworkAccesser -output /Users/awei/Library/Developer/Xcode/DerivedData/FSTools-dpccvvatsquaxidgmdutjxwkmggy/Build/Products/FSNetworkAccesser

对于打包到Bundle中的文件,在其他地方使用[NSBundle mainBundle]不能访问库文件中bundle的资源文件

静态库(Cocoa Touch Static Library)

date: 2017-09-18 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/get-ipa.html b/docs/.vitepress/dist/frontend/ios/get-ipa.html new file mode 100644 index 0000000..c3512d1 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/get-ipa.html @@ -0,0 +1,25 @@ + + + + + + 使用iTunes获取ipa | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

使用iTunes获取ipa

目前使用iTunes 12.7以上的版本已经无法下载ipa包,故需要安装iTunes 12.6以下的版本 安装连接:https://support.apple.com/en-us/HT208079 注意: 最新的安装版本为12.6.5,不支持macOS Mojave

步骤:

  1. 下载旧版本的 iTunes 12.6

  2. 卸载原有的iTunes 12.7 以上的版本 (如果在提示不能删除iTunes,则需要按以下的步骤进行)

    • 重启电脑,在重启的过程中按住command+R组合键进入到恢复工具界面,然后点击“实用工具”选项卡中的“终端”一栏,
    • 进入终端以后,在终端中csrutil disable命令,看到提示成功以后就解除权限控制了,
    • 再次重启电脑,打开终端,在终端中输入命令:cd /Applications,
    • 输入命令:rm -rf iTunes.app,
    • 重启电脑,然后按住command+R进入进入到恢复工具界面,打开终端,在终端中输入命令:csrutil enable.
  3. 删除Music/iTunes 目录下的所有所有文件

  4. 安装下载好的iTunes 12.6.5.dmg

  5. 任意下载自己需要的app

date: 2018-12-31 14:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/im-first.html b/docs/.vitepress/dist/frontend/ios/im-first.html new file mode 100644 index 0000000..fdc72d6 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/im-first.html @@ -0,0 +1,25 @@ + + + + + + IM Introduction | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

IM Introduction

IM 即时通讯技术 介绍

应用场景

即时通信的常用应用场景:即实时性要求高的场景,常见的如下: 视频会议、聊天、私信 弹幕、抽奖 互动游戏 协同编辑 股票基金实时报价、体育实况更新、 基于位置的应用:Uber、滴滴司机位置 在线教育 智能家居

基本的发展阶段

轮询-》长轮询-》长连接

注意长短连接与长短轮询的区别 概念范畴:长短轮询是应用层概念、长短连接是传输层概念 协商方式:一个 TCP 连接是否为长连接,是通过设置 HTTP 的 Connection Header 来决定的,而且是需要两边都设置才有效。而一种轮询方式是否为长轮询,是根据服务端的处理方式来决定的,与客户端没有关系。 实现方式:连接的长短是通过协议来规定和实现的。而轮询的长短,是服务器通过编程的方式手动挂起请求来实现的

数据传输格式

自定义二进制 开源协议:protocol buffers 文本协议(json\xml)

常见的实现方式

  1. 基于Scoket:代表框架:CocoaAsyncSocket
  2. 基于WebScoket: SocketRocket
  3. 基于MQTT: MQTTKit
  4. 基于XMPP: XMPPFramework
名称协议举例优点缺点
SocketSocket+protocol buffers
WebScoketWebScoket+json高效、节约流量(比如使用protocol buffers,或压缩json格式),ios Android web三端通用对设计者要求高
MQTT协议简单,流量少、订阅+推送模式并不是专门为IM设计的协议,多用于推送
XMPPScoket+xml开源、可扩展性强、方便接入XML表现力差、额外信息多、流量耗费大

重连机制

TCP KeepAlive机制心跳机制
检测连接的状态检测通信双方的存活状态
在定时的时间(一般为7200s)到后, 发送相应的KeepAlive探针,
失败后重试10次,每次超时时间75s通常可设置3-5min发Ping

date: 2017-11-27 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/image-on-iphone.html b/docs/.vitepress/dist/frontend/ios/image-on-iphone.html new file mode 100644 index 0000000..27b4ca2 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/image-on-iphone.html @@ -0,0 +1,131 @@ + + + + + + Image | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Image

The record related to Image

iPhone拍照的部分图片在windows上显示被旋转的问题

/**
 旋转图片
+
+ 解决在window 系统中 不能识别UIImageOrientationRight时的方向值,
+ 会出现逆时针90,所以
+ 
+ @param image 原图
+ @return 新图
+ */
++ (UIImage *)rotateImage:(UIImage *) image
+{
+   
+    @autoreleasepool {
+        CGImageRef imgRef = image.CGImage;
+        
+        CGFloat width = CGImageGetWidth(imgRef);
+        CGFloat height = CGImageGetHeight(imgRef);
+        
+        
+        CGAffineTransform transform = CGAffineTransformIdentity;
+        CGRect bounds = CGRectMake(0, 0, width, height);
+
+        CGFloat scaleRatio = bounds.size.width / width;
+        CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
+        CGFloat boundHeight;
+        UIImageOrientation orient = image.imageOrientation;
+        switch(orient) {
+                
+            case UIImageOrientationUp: //EXIF = 1
+                transform = CGAffineTransformIdentity;
+                break;
+                
+            case UIImageOrientationUpMirrored: //EXIF = 2
+                transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
+                transform = CGAffineTransformScale(transform, -1.0, 1.0);
+                break;
+                
+            case UIImageOrientationDown: //EXIF = 3
+                transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
+                transform = CGAffineTransformRotate(transform, M_PI);
+                break;
+                
+            case UIImageOrientationDownMirrored: //EXIF = 4
+                transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
+                transform = CGAffineTransformScale(transform, 1.0, -1.0);
+                break;
+                
+            case UIImageOrientationLeftMirrored: //EXIF = 5
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
+                transform = CGAffineTransformScale(transform, -1.0, 1.0);
+                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationLeft: //EXIF = 8
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
+                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationRightMirrored: //EXIF = 7
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeScale(-1.0, 1.0);
+                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
+                break;
+                
+            case UIImageOrientationRight: //EXIF = 6
+                boundHeight = bounds.size.height;
+                bounds.size.height = bounds.size.width;
+                bounds.size.width = boundHeight;
+                transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
+                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
+                break;
+                
+            default:
+                [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
+                
+        }
+        
+        UIGraphicsBeginImageContext(bounds.size);
+        
+        CGContextRef context = UIGraphicsGetCurrentContext();
+        
+        if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
+            CGContextScaleCTM(context, -scaleRatio, scaleRatio);
+            CGContextTranslateCTM(context, -height, 0);
+        }
+        else {
+            CGContextScaleCTM(context, scaleRatio, -scaleRatio);
+            CGContextTranslateCTM(context, 0, -height);
+        }
+        
+        CGContextConcatCTM(context, transform);
+        
+        CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
+        UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
+        UIGraphicsEndImageContext();
+        
+        return imageCopy;
+
+    }
+}

date: 2017-11-27 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/index.html b/docs/.vitepress/dist/frontend/ios/index.html new file mode 100644 index 0000000..7f6e4d0 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/index.html @@ -0,0 +1,25 @@ + + + + + + iOS App 程序启动过程 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

iOS App 程序启动过程

在main函数中进行的设置UIApplication对象的代理。 App容易受到干扰。正在玩游戏,一个电话打过来了。

  • 应用程序的生命周期事件(如程序启动和关闭)
  • 系统事件(如来电)
  • 内存警告
  • … … ** 处理这些干扰事件,就要用到AppDelegate代理对象了。 ** 总结: AppDelegate的主要作用就是处理(监听)应用程序本身的各种事件:
  • 应用程序启动完毕
  • 应用程序进入后台
  • 应用程序进入前台
  • 内存警告
  • 等等, 都是应用程序自身的一些事件 ** 要想成为UIApplication的代理对象, 必须遵守:UIApplicationDelegate协议。 ** 代理中的若干方法介绍:
    • (BOOL)application: didFinishLaunchingWithOptions: // app第一次启动完毕后就会调用(当程序启动后会显示一张启动图片, 当这个图片显示完毕, 消失后, 就开始调用这个方法)
    • (void)applicationDidEnterBackground:(UIApplication *)application // 当程序进入后台时, 调用该方法。(比如:按了Home键, 或者一个电话打过来了, 当前程序都会进入后台。) // 在这个方法中可以做一些保存当前程序数据, 暂停程序的操作。
    • (void)applicationWillEnterForeground:(UIApplication *)application // 当程序再次进入前台的时候调用。
    • (void)applicationDidReceiveMemoryWarning:(UIApplication *)application // 当发生内存警告时触发该事件。 程序启动后: didFinishLaunchingWithOptions-->applicationDidBecomeActive 按home键使程序进入后台:applicationWillResignActive--->applicationDidEnterBackground 让程序会到主界面:applicationWillEnterForeground--->applicationDidBecomeActive 在主界面时让程序退出:applicationDidEnterBackground--->applicationWillTerminate 在后台时退出:applicationWillTerminate

date: 2017-04-22 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/jailbreak.html b/docs/.vitepress/dist/frontend/ios/jailbreak.html new file mode 100644 index 0000000..cbd811f --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/jailbreak.html @@ -0,0 +1,28 @@ + + + + + + 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Jailbreak 入门

1. Jailbreak 工具

  • ios 10 推荐 安装 meridia 来越狱,越狱为 非完美越狱,在手机系统从新启动时 需要从新 越狱操作
  • iOS 11 以上 推荐安装 unc0ver
#  ios 10 Jailbreak 工具,使用手机 safari 打开一下连接
+https://kubadownload.com/news/meridian-jailbreak/
+#   unc0ver 工具
+https://unc0ver.dev

2. 添加仓库源

添加的仓库包括 http://apt.saurik.com

date: 2020-05-12 14:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/lock-share.html b/docs/.vitepress/dist/frontend/ios/lock-share.html new file mode 100644 index 0000000..9fbdd5c --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/lock-share.html @@ -0,0 +1,25 @@ + + + + + + 琐碎的记录 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

琐碎的记录

数据存储方式对比

  1. plist文件 可以存储的数据类型:Number(interger,real),String,Boolean(false,true),Date,Data,Array,Dictionary

  2. NSUserDefaults 数据类型 NSString, NSData, NSNumber(NSInteger,float,double), NSDate, NSArray, NSDictionary and NSURL

  3. NSKeyedArchiver / NSKeyedUnarchiver 数据类型 NSData

  4. Sqlite

  5. CoreData

关于锁:

OSSpinLock 自旋锁,性能最高的锁。原理很简单,就是一直 do while 忙等。它的缺点是当等待时会消耗大量 CPU 资源,所以它不适用于较长时间的任务。对于内存缓存的存取来说,它非常合适。 NSDictionary + OSSpinLock 实现高性能缓存

dispatch_semaphore 是信号量,但当信号总量设为 1 时也可以当作锁来。在没有等待情况出现时,它的性能比 pthread_mutex 还要高,但一旦有等待情况出现时,性能就会下降许多。相对于 OSSpinLock 来说,它的优势在于等待时不会消耗 CPU 资源。对磁盘缓存来说,它比较合适。

磁盘缓存

1 基于文件读写 SDWebImage、 TMDiskCache、 PINDiskCache 等缓存,都是基于文件系统的,即一个 Value 对应一个文件,通过文件读写来缓存数据。他们的实现都比较简单,性能也都相近,缺点:不方便扩展、没有元数据、难以实现较好的淘汰算法、数据统计缓慢。

2 基于 mmap 文件内存映射 FastImageCache 采用的是 mmap 将文件映射到内存。mmap 性能非常高, 缺点:热数据的文件不要超过物理内存大小,不然 mmap 会导致内存交换严重降低性能(MongoDB也有同样的问题);另外内存中的数据是定时 flush 到文件的,如果数据还未同步时程序挂掉,就会导致数据错误。

3 基于数据库 NSURLCache、YYDiskCache、FBDiskCache 都是基于 SQLite 数据库的。基于数据库的缓存可以很好的支持元数据、扩展方便、数据统计速度快,也很容易实现 LRU 或其他淘汰算法,当单条数据小于 20K 时,数据越小 SQLite 读取性能越高;单条数据大于 20K 时,直接写为文件速度会更快一些,直接从官网下载最新的 SQLite 源码编译,会比 iOS 系统自带的 sqlite3.dylib 性能要高很多 磁盘缓存最好是把 SQLite 和文件存储结合起来:key-value 元数据保存在 SQLite 中,而 value 数据则根据大小不同选择 SQLite 或文件存储。NSURLCache 选定的数据大小的阈值是 16K;FBDiskCache 则把所有 value 数据都保存成了文件。

##常用的文件头编码 JPEG(jpg) 文件头:FFD8FFE1 PNG(png) 文件头:89504E47 GIF(gif) 文件头:47494638 Windows Bitmap(bmp) 文件头:424D WebP : 524946462A73010057454250

Adobe Photoshop (psd),文件头:38425053  Rich Text Format (rtf),文件头:7B5C727466  XML (xml),文件头:3C3F786D6C  HTML (html),文件头:68746D6C3E  Adobe Acrobat (pdf),文件头:255044462D312E ZIP Archive (zip),文件头:504B0304 RAR Archive (rar),文件头:52617221

Wave (wav),文件头:57415645  Quicktime (mov),文件头:6D6F6F76 AVI (avi),文件头:41564920 Real Audio (ram),文件头:2E7261FD Real Media (rm),文件头:2E524D46  MPEG (mpg),文件头:000001BA  MPEG (mpg),文件头:000001B3

date: 2017-08-11 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/macro-define.html b/docs/.vitepress/dist/frontend/ios/macro-define.html new file mode 100644 index 0000000..2f5ed01 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/macro-define.html @@ -0,0 +1,66 @@ + + + + + + Macro Define | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Macro Define

常用的宏定义

1. DEBUG Log

#ifdef DEBUG
+#define LLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+#else
+#define LLog(fmt, ...) while(0){}
+#endif

ios开发中难免会遇到一些oc与c混编的时候,当使用了pch文件时,c文件是不会识别上面的条件编译和#import等指令的,这时候应该使用另外一个条件编译来避免出现问题:

#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif

2. ios版本兼容

编译设置

Base SDK 当前编译所使用的SDK版本 Deployment Target 运行APP所需要的最低的操作系统版本 Base SDK 可以设置为Xcode默认的设置,比如Latest iOS(iOS10.2),Deployment Target设置为iOS 8.0,目前大多数APP都支持到该版本

iOS宏定义

静态检查

在编译阶段就检查当前SDK编译与构建应用是否能使用某个API 编译常量 __IPHONE_OS_VERSION_MIN_REQUIRED 系统最低版本(也就是iOS Deployment Target选择的版本) __IPHONE_OS_VERSION_MAX_ALLOWED 系统最高版本(当前手机系统允许使用的SDK的最高版本)

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0
+    // 系统版本在iOS9.0及以上则编译此部分代码
+#else
+    // 如果低于iOS9.0则编译此部分代码
+#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0
+// 如果选择(iOS Deployment Target)的最低支持版本在iOS8.0及以上才可以使用
+#endif

动态检查

CoreFoudation/NSFoundation版本宏

定义的宏如下,可以看出某些系统版本的值是一样的,而且没有对ios 10.0以上版本进行定义,需要自己定义

#define kCFCoreFoundationVersionNumber_iOS_8_0 1140.1
+#define kCFCoreFoundationVersionNumber_iOS_8_1 1141.14
+#define kCFCoreFoundationVersionNumber_iOS_8_2 1142.16
+#define kCFCoreFoundationVersionNumber_iOS_8_3 1144.17
+#define kCFCoreFoundationVersionNumber_iOS_8_4 1145.15
+#define kCFCoreFoundationVersionNumber_iOS_8_x_Max 1199
+#define kCFCoreFoundationVersionNumber_iOS_9_0 1240.1
+#define kCFCoreFoundationVersionNumber_iOS_9_1 1241.11
+#define kCFCoreFoundationVersionNumber_iOS_9_2 1242.13
+#define kCFCoreFoundationVersionNumber_iOS_9_3 1242.13
+#define kCFCoreFoundationVersionNumber_iOS_9_4 1280.38
+#define kCFCoreFoundationVersionNumber_iOS_9_x_Max 1299

使用方式

if (kCFCoreFoundationVersionNumber <kCFCoreFoundationVersionNumber_iOS_9_0) {
+        //系统版本低于iOS9.0
+    }

综合而论,不推荐使用

检查运行的iOS系统版本

转换为基本数据类型比较

if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
+        
+    }

使用systemVersion方法获取到的值为8.1 ,如比较8.1.1和8.1.2,就很困难了

字符串比较

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
+#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
+#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
+#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

使用字符串的比较 存在的问题 比如8.1 相对于8.1.0 结果为NSOrderedAscending, 即8.1 < 8.1.0

使用NSOperatingSystemVersion(iOS 8.0)

NSOperatingSystemVersion 为结构体,如下所示

typedef struct {
+    NSInteger majorVersion;
+    NSInteger minorVersion;
+    NSInteger patchVersion;
+} NSOperatingSystemVersion;
NSOperatingSystemVersion version = (NSOperatingSystemVersion){8,2,0};
+    if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
+        // 高于该版本
+    }else {
+        // 低于该版本
+    }

date: 2017-04-22 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/network-share.html b/docs/.vitepress/dist/frontend/ios/network-share.html new file mode 100644 index 0000000..b67833d --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/network-share.html @@ -0,0 +1,42 @@ + + + + + + iOS 网络状态检测 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

iOS 网络状态检测

导入CoreTelephony.framework框架

CTCellularData *cellularData = [[CTCellularData alloc]init];
+    cellularData.cellularDataRestrictionDidUpdateNotifier =  ^(CTCellularDataRestrictedState state){
+        //状态改变时进行相关操作
+    };
    CTCellularData *cellularData = [[CTCellularData alloc]init];
+    CTCellularDataRestrictedState state = cellularData.restrictedState;
+    switch (state) {
+        case kCTCellularDataRestricted:
+            NSLog(@"Restricrted");
+            break;
+        case kCTCellularDataNotRestricted:
+            NSLog(@"Not Restricted");
+            break;
+        case kCTCellularDataRestrictedStateUnknown:
+            NSLog(@"Unknown");
+            break;
+        default:
+            break;
+    }

date: 2017-07-16 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/note-share.html b/docs/.vitepress/dist/frontend/ios/note-share.html new file mode 100644 index 0000000..664f1da --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/note-share.html @@ -0,0 +1,25 @@ + + + + + + 琐碎的记录 | 前端技术知识库 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-current-controller.html b/docs/.vitepress/dist/frontend/ios/post-current-controller.html new file mode 100644 index 0000000..f7b7f0f --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-current-controller.html @@ -0,0 +1,85 @@ + + + + + + Get Current ViewController | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Get Current ViewController

"Get the current view controller from the app delegate"

1.Get the current view controller from the app delegate

参考:http://stackoverflow.com/questions/24825123/get-the-current-view-controller-from-the-app-delegate%EF%BC%89

扩展一个方法:

UIViewController+Utils.h

#import <UIKit/UIKit.h>
+
+@interface UIViewController (Utils)
+
++(UIViewController*) currentViewController;
+
+@end

UIViewController+Utils.m

#import

+@implementation UIViewController (Utils)
+
++(UIViewController*) findBestViewController:(UIViewController*)vc {
+
+    if (vc.presentedViewController) {
+
+        // Return presented view controller
+        return [UIViewController findBestViewController:vc.presentedViewController];
+
+    } else if ([vc isKindOfClass:[UISplitViewController class]]) {
+
+        // Return right hand side
+        UISplitViewController* svc = (UISplitViewController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.viewControllers.lastObject];
+        else
+            return vc;
+
+    } else if ([vc isKindOfClass:[UINavigationController class]]) {
+
+        // Return top view
+        UINavigationController* svc = (UINavigationController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.topViewController];
+        else
+            return vc;
+
+    } else if ([vc isKindOfClass:[UITabBarController class]]) {
+
+        // Return visible view
+        UITabBarController* svc = (UITabBarController*) vc;
+        if (svc.viewControllers.count > 0)
+            return [UIViewController findBestViewController:svc.selectedViewController];
+        else
+            return vc;
+
+    } else {
+
+        // Unknown view controller type, return last child view controller
+        return vc;
+
+    }
+
+}
+
++(UIViewController*) currentViewController {
+
+    // Find best view controller
+    UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
+    return [UIViewController findBestViewController:viewController];
+
+}
+
+@end

date: 2017-04-07 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-dispatch-group.html b/docs/.vitepress/dist/frontend/ios/post-dispatch-group.html new file mode 100644 index 0000000..cbde870 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-dispatch-group.html @@ -0,0 +1,79 @@ + + + + + + "Dispatch Group" | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

"Dispatch Group"

dispatch_group 日常使用

#1.常见书写方式

dispatch_group_t group = dispatch_group_create();   
+dispatch_queue_t queue = dispatch_queue_create("com.formssi.get_product_detail", NULL);
+dispatch_group_async(group,queue, ^{
+         <!--do work-->
+    });
+dispatch_group_async(group,queue, ^{
+         <!--do work-->
+    });
+    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+     <!--main thread-->
+     <!--do work-->
+      
+    });

#2.如果做的事包含block任务,就需要给没个block任务添加入组与出组的操作

dispatch_group_t group = dispatch_group_create();   
+dispatch_queue_t queue = dispatch_queue_create("com.baidu.detail", NULL);
+dispatch_group_enter(group);
+dispatch_group_async(group,queue, ^{
+         <!--do block work-->
+        dispatch_group_leave(group);
+    });
+    dispatch_group_enter(group);
+dispatch_group_async(group,queue, ^{
+         <!--do block work-->
+        dispatch_group_leave(group);
+    });
+    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+      <!--main thread-->
+      <!--do work-->
+    });

#3.当我们使用其他的三方库做网络请求或则图片下载时,而请求的任务包含多个,需要 等待这些任务都执行完成之后,再返回结果,如下列子:

dispatch_group_t group = dispatch_group_create();
+    __block BOOL isSuccess = NO;
+    for (CellModel *cellModel in modelArray) {
+         <!--异步下载图片-->
+        dispatch_group_enter(group);
+        [[SDWebImageManager sharedManager] downloadImageWithURL:cellModel.url options:SDWebImageRetryFailed | SDWebImageLowPriority progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
+            NSLog(@"downloadError = %@-%@",error,[NSThread currentThread]);
+            if (error) {
+                isSuccess = NO;
+            }else{
+                isSuccess = YES;
+                <!-- 获取图片大小-->
+                cellModel.cellHeight = WidthOfWindow * image.size.height / image.size.width;
+            }
+            dispatch_group_leave(group);
+        }];
+    }
+    
+
+dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+         <!-- more -->
+        if (isSuccess) {
+            completion(NetWorkingResultTypeSuccess,@"success");
+        }else{
+            completion(NetWorkingResultTypeNoData, @"error");
+        }
+        
+    });

date: 2017-03-17 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-facebook-share.html b/docs/.vitepress/dist/frontend/ios/post-facebook-share.html new file mode 100644 index 0000000..0aae207 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-facebook-share.html @@ -0,0 +1,124 @@ + + + + + + Facebook 分享 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Facebook 分享

官方文档: https://developers.facebook.com/docs/sharing/overview

在移动平台上分享 — 分步指南

  • “分享”按钮:显示的时候没有分享计数器。用户轻触“分享”按钮将打开一个新窗口(也称为快速应用切换)。

  • 分享对话框:窗口将显示帖子编辑器,其中包含分享链接的预览。如果用户安装了 iOS 版 Facebook 应用,分享对话框将由 Facebook 应用提供,否则将由 Safari 浏览器提供。轻触“分享”按钮即表示用户确认分享,然后系统将切换回您的应用。

  • 现在,SDK 将自动检查设备上是否安装了原生 Facebook 应用。如果未安装,SDK 会将用户切换到默认浏览器并打开动态发布对话框。如果用户想要分享开放图谱动态,SDK 会打开网页分享对话框。

  • 如果安装了原生 Facebook 应用,4.0-4.4 版的 SDK 会切换到原生 iOS 版 Facebook 应用,并在发布帖子后将控制权交还您的应用。如果使用 4.5+ 版 SDK,除非分享内容是开放图谱动态,否则用户会看到 iOS 分享表,而不会切换到原生 iOS 版 Facebook 应用。 说明: 目前下载的最新SDK版本为4.21.0,想要使用跳转到Facebook应用分享,需要申请public-action权限,才能使用图谱,否则只能使用web显示分享,目前还没申请下来该权限,只能做到web分享

第一步:info.plist 文件配置

将以下 XML 代码片段插入文件正文,位于最后的 ==</dict>== 元素前

<key>CFBundleURLTypes</key>
+<array>
+  <dict>
+    <key>CFBundleURLSchemes</key>
+    <array>
+      <string>fb{your-app-id}</string>
+    </array>
+  </dict>
+</array>
+<key>FacebookAppID</key>
+<string>{your-app-id}</string>
+<key>FacebookDisplayName</key>
+<string>{your-app-name}</string>
+<!-- URL Scheme , 返回应用-->
+<key>LSApplicationQueriesSchemes</key>
+	<array>
+        <!--Facebook URL Scheme-->
+		<string>fbapi</string>
+		<string>fb-messenger-api</string>
+		<string>fbauth2</string>
+		<string>fbshareextension</string>
+        <!-- whatsapp URL Scheme 白名单-->
+		<string>whatsapp</string>
+        <!-- instagram URL Scheme 白名单-->
+		<string>instagram</string>
+        <!-- wechat URL Scheme 白名单-->
+		<string>wechat</string>
+		<string>weixin</string>
+	</array>
+<key>NSPhotoLibraryUsageDescription</key>
+  <string>{human-readable reason for photo access}</string>

info.plist 配置说明 (1)将 ==fb{your-app-id}== 替换为 Facebook 应用编号,加上前缀 ==fb==。例如,==fb1767503776894317==。您可以通过 Facebook 应用面板找到应用编号。 (2)使用应用编号替换 =={your-app-id}==。 (3)使用您在应用面板中指定的显示名称替换 =={your-app-name}==。 (4)将 =={human-readable reason for photo access}== 替换为您的应用需要获取照片访问权限的理由

第二步:注册Facebook

AppDelegate.m 文件的实现 #import <FBSDKCoreKit/FBSDKCoreKit.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+    
+    [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
+    
+    return YES;
+}
+// 仅支持iOS9以上系统,iOS8及以下系统不会回调
+-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
+    NSLog(@"%s,load app options = %@", __func__, options);
+    BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
+    return result;
+}
+
+// 所有平台,但ios9以后不推荐使用
+- (BOOL)application:(UIApplication *)application
+            openURL:(NSURL *)url
+  sourceApplication:(NSString *)sourceApplication
+         annotation:(id)annotation {
+    NSLog(@"%s,load app sourceApplication = %@",__func__,sourceApplication);
+    BOOL isSuccess = [[FBSDKApplicationDelegate sharedInstance] application:application
+                                                          openURL:url
+                                                sourceApplication:sourceApplication
+                                                       annotation:annotation];
+    return isSuccess;
+}

第三步:实现分享功能

3.1 使用SDK中的分享按钮FBSDKShareButton 需要==public_profile==,默认已通过 创建如下:

FBSDKShareButton *shareButton = [[FBSDKShareButton alloc] init];
+shareButton.shareContent = content;  
+shareButton.center = self.view.center;
+  [self.view addSubview:shareButton];

3.2 对于分享的内容content 可以使用分为

  • FBSDKShareLinkContent 链接:大部分内容为引用 HTML 页面的网址。要提供最相关的信息,您应使用 Facebook 特定元标签标记您的页面

  • FBSDKSharePhotoContent
    照片:直接上传一张或多张由用户拍摄的照片

  • FBSDKShareVideoContent
    视频:直接上传由用户拍摄的视频

  • FBSDKShareMediaContent 多媒体:直接上传同时包含照片和视频的内容

创建方式:

FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
+content.contentURL = [NSURL URLWithString:@"https://developers.facebook.com"];

SDK中定义的分享按钮如下图:

3.3 使用自定义的分享按钮

要使用专属分享界面,您需要:

  • 构建发布到图谱 API 端点 ==/me/feed== 的自定义界面
  • 将 Facebook 登录功能添加至您的应用
  • 请求 ==publish_actions== 权限,需要申请

对自定义的分享按钮的样式的说明:

申请权限需要注意的事项:

上传视频的注意事项如图所示:

3.4 自定义分享内容

  • 使用开放图谱标签。
  • 调整 FBSDKShareLinkContent 选择器

图谱示例

if ([[FBSDKAccessToken currentAccessToken] hasGranted:@"publish_actions"]) {
+        [[[FBSDKGraphRequest alloc]initWithGraphPath:@"me/feed" parameters:@{@"message":@"hello world!"} HTTPMethod:@"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
+            NSLog(@"result=%@",result);
+        }];
+    }else{
+        NSLog(@"did not have publish_actions");
+    }

FBSDKShareLinkContent 示例

NSURL *contentURL = [[NSURL alloc] initWithString:
+  @"http://en.wikipedia.org/wiki/Facebook"];
+
+NSURL *imageURL = 
+  [NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Facebook_Headquarters_Menlo_Park.jpg/2880px-Facebook_Headquarters_Menlo_Park.jpg"];
+  
+button.shareContent = [[FBSDKShareLinkContent alloc]
+  initWithContentURL: contentURL
+  contentTitle: @"My Share Title"
+  contentDescription: @"Lorem ipsum dolor sit amet."
+  imageURL: imageURL
+  peopleIDs: @[@"1561082740838259"]
+  placeID: @"166793820034304"
+  ref: @"myRefId"
+];

3.5 分享对话框

  • 在移动平台上,当用户使用分享对话框分享内容时,对话框会执行快速应用切换操作,切换到设备上的 Facebook 应用。我们还提供网页对话框作为回退选项,以防用户未安装原生 Facebook 应用
  • 使用原生 Facebook 对话框时,无需添加 Facebook 登录即可启用分享
- (void)facebookShareWithMessage:(NSDictionary *)dictionary {
+    NSString *contentUrlString = dictionary[@"content_url"];
+    NSString *imageUrlString = dictionary[@"image_url"];
+    NSString *description = dictionary[@"description"];
+    NSString *title = dictionary[@"title"];
+    NSString *quote = dictionary[@"quote"];
+    
+    FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
+    content.contentURL = [NSURL URLWithString:contentUrlString];
+    content.imageURL = [NSURL URLWithString:imageUrlString];
+    content.contentDescription = description;
+    content.contentTitle = title;
+    content.quote = quote;
+    
+    FBSDKShareDialog *dialog = [[FBSDKShareDialog alloc] init];
+    dialog.shareContent = content;
+    dialog.fromViewController = self;
+    dialog.delegate = self;
+    dialog.mode = FBSDKShareDialogModeBrowser;
+    [dialog show];
+}

3.6 自定义分享界面 可以使用自定义按钮和调用图谱 API 的自定义对话框

                                    2017-04-19 高飞
+

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-instagram-share.html b/docs/.vitepress/dist/frontend/ios/post-instagram-share.html new file mode 100644 index 0000000..aa0cdc8 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-instagram-share.html @@ -0,0 +1,103 @@ + + + + + + Instagram 分享 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-twitter-share.html b/docs/.vitepress/dist/frontend/ios/post-twitter-share.html new file mode 100644 index 0000000..c41c69d --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-twitter-share.html @@ -0,0 +1,79 @@ + + + + + + "Twitter share" | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

"Twitter share"

Twitter 分享

参考文档:https://fabric.io/kits/ios/twitterkit/installhttps://fabric.io/kits/ios/twitterkit/manual-install

1 开发者账号申请注意事项:

![]/img/in-post/media/14925836417059/14925860141113.jpg)

2 安装步骤:

2.1 Download, unzip, and drag 下载,解压,拖拽到工程文件 2.2 Add a Run Script Build Phase

2.3 Add API Key to Info.plist

2.4 Initialize Twitter and Run

3 重要注解:

4 twitter 分享文档:

https://docs.fabric.io/apple/twitter/compose-tweets.html 分享参考:

- (void)showTwitterCompose{
+    TWTRComposer *composer = [[TWTRComposer alloc] init];
+    
+    [composer setText:@"I am big big man"];
+    [composer setURL:[NSURL URLWithString:@"https//:www.baidu.com"]];
+    if (composer) {
+        NSLog(@"composer = %@",composer);
+        [composer showFromViewController:self completion:^(TWTRComposerResult result) {
+            if (result == TWTRComposerResultDone) {
+                NSLog(@"twitter share done");
+            }else if (result == TWTRComposerResultCancelled){
+                NSLog(@"twitter share cancell");
+            }
+        }];
+    }
+
+}
+
+- (void)showTwitterSessionShare{
+    // Objective-C
+    // Users must be logged-in to compose Tweets
+    TWTRSession *session = [Twitter sharedInstance].sessionStore.session;
+    
+    // User generated image
+    UIImage *image = [UIImage imageNamed:@"XXXXX"];
+    
+    // Create the card and composer
+    TWTRCardConfiguration *card = [TWTRCardConfiguration appCardConfigurationWithPromoImage:image iPhoneAppID:nil iPadAppID:nil googlePlayAppID:nil];
+    TWTRComposerViewController *composer = [[TWTRComposerViewController alloc] initWithUserID:session.userID cardConfiguration:card];
+    
+    // Optionally set yourself as the delegate
+    composer.delegate = self;
+    
+    // Show the view controller
+    [self presentViewController:composer animated:YES completion:nil];
+}

5 问题:

在ios 9.2.1 上测试,如果用户没登录Twitter账号,点击Twitter分享会崩溃。 出现的错误日志如下:

***
*** First throw call stack:
+(0x239ab91b 0x23146e17 0x28294ab1 0x28296d25 0x28296f91 0x2801ddb9 0x1928b5 0x906e5 0x9057b 0x27f5c755 0x27f5c6e1 0x27f446d3 0x27f5c005 0x27f5bc7f 0x27f5468f 0x27f25125 0x27f236d3 0x2396ddff 0x2396d9ed 0x2396bd5b 0x238bb229 0x238bb015 0x24eabac9 0x27f8d189 0x92def 0x23563873)
+libc++abi.dylib: terminating with uncaught exception of type NSException

暂时的解决方式:

  1. 申请访问Account权限(ios 10,要添加到info.plist中);
  2. 访问Account的实现代码:
// ios 10 在info.plist添加访问权限
+    ACAccountStore *store = [[ACAccountStore alloc]init];
+    ACAccountType *twitterType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
+    [store requestAccessToAccountsWithType:twitterType options:nil completion:^(BOOL granted, NSError *error) {
+        if (granted){
+         NSArray *array =   [store accountsWithAccountType:twitterType];
+            NSLog(@"accounts = %@",array);
+            if (array.count > 0) {// 显示Twitter分享功能
+                [self showTwitterCompose];
+            }else{
+                // 提示用户添加账号信息
+            }
+        }else{
+            NSLog(@"----no----");
+        
+            // 提示用户允许访问账号信息
+        }
+    }];

2017-04-20 高飞

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-view-tips.html b/docs/.vitepress/dist/frontend/ios/post-view-tips.html new file mode 100644 index 0000000..426c714 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-view-tips.html @@ -0,0 +1,37 @@ + + + + + + View Tips | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

View Tips

将视图显示在最前方

[self.view addSubview:view];
+[self.view bringSubviewToFront:view];

下拉取消回弹效果

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
+    
+    //限制下拉没有回弹效果
+    if (scrollView.contentOffset.y <= 0){
+        
+        CGPoint point = scrollView.contentOffset;
+        point.y = 0;
+        [scrollView setContentOffset:point];
+    }
+}

检测某个API是否可用

1.使用respondsToSelector:方法检测是否有某个方法;

respondsToSelector:@selector(method)

  1. 使用<objc/runtime.h>检测是否有某个属性;
    if (class_getProperty([ClassName class], "propertyName")) {
+        // it has that property!
+    }

date: 2017-03-28 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/post-whatsapp-share.html b/docs/.vitepress/dist/frontend/ios/post-whatsapp-share.html new file mode 100644 index 0000000..4bee6fd --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/post-whatsapp-share.html @@ -0,0 +1,72 @@ + + + + + + WhatsApp 分享 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

WhatsApp 分享

没有开发者平台,分享通过系统自带的

1 添加URL Scheme 白名单

<key>LSApplicationQueriesSchemes</key>
+	<array>
+		<string>whatsapp</string>
+	</array>

2 分享文字:使用open URL Scheme

- (void)shareToWhatsAppWithTxt:(NSString *)txt{
+   
+    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"whatsapp://"]]) {
+        NSString *str = [NSString stringWithFormat:@"whatsapp://send?text=%@",[txt stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]];
+        NSURL *msgUrl = [NSURL URLWithString:str];
+        [[UIApplication sharedApplication] openURL:msgUrl];
+    }else{
+        NSLog(@"no whatsapp install");
+        [self showAlterWithStr:@"no whatsapp install"];
+    }
+}

3 分享照片与视频 使用UIDocumentInteractionController

- (void)shareToWhatsAppWithImg:(UIImage *)img{
+    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"whatsapp://app"]]) {
+        
+        dispatch_async(dispatch_get_global_queue(0, 0), ^{
+            
+            NSString *name = [NSString stringWithFormat:@"%f%u.png",[NSDate timeIntervalSinceReferenceDate],arc4random_uniform(1000)];
+            NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:name];
+            BOOL result = [UIImagePNGRepresentation(img) writeToFile:savePath atomically:YES];
+            if (result) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    UIDocumentInteractionController *intent = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+                    intent.UTI = @"net.whatsapp.image";
+                    intent.delegate = self;
+                    [intent presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
+                });
+            }else{
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [self showAlterWithStr:@"error"];
+                
+                });
+            }
+            
+            
+        });
+   
+    }else{
+        [self showAlterWithStr:@"no whatsapp install"];
+    }
+}
- (void)showAlterWithStr:(NSString *)str{
+    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:str preferredStyle:UIAlertControllerStyleAlert];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
+    [alertController addAction:cancelAction];
+    
+    [self presentViewController:alertController animated:YES completion:nil];
+}

2017-04-20 高飞

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/reactnative.html b/docs/.vitepress/dist/frontend/ios/reactnative.html new file mode 100644 index 0000000..e6df996 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/reactnative.html @@ -0,0 +1,43 @@ + + + + + + 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

React Native 入门

1. 配置环境

特点

1.1 切换淘宝镜像

# 如果安装下载速度过慢,可以设置使用国内淘宝提供的镜像
+$ npm config set registry https://registry.npm.taobao.org --global
+$ npm config set disturl https://npm.taobao.org/dist --global
+
+# Yarn是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载
+$ sudo npm install -g yarn
#官方提供了一键生成项目初始结构的脚手架react-native-cli
+$ sudo npm install -g react-native-cli
+
+# 安装指定版本的 react native
+$ sudo npm install -save react-native@0.60

1.2 CocoaPods 镜像使用帮助

若果cocoapods 安装太慢,可以尝试切换到清华站点

下面示例的创建 本地名为 tuna 的仓库

$ pod repo add tuna https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git
+$ pod repo update tuna

最后进入自己的工程,在自己工程的podFile第一行加上:

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

2. 初始化项目

cd 到需要创建项目的目录下
+$ react-native init demo
+$ cd demo
+#运行
+$ react-native run-ios
+# 如果运行失败,直接找到 iOS 文件夹,使用xcode 直接编译工程,如果发现第三方库没有安装,则先使用pod install
+$ pod install

3.使用

导入定时器
+#在项目文件夹 安装定时器
+$  npm i react-timer-mixin --save

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/url-codeing.html b/docs/.vitepress/dist/frontend/ios/url-codeing.html new file mode 100644 index 0000000..d1b8c26 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/url-codeing.html @@ -0,0 +1,34 @@ + + + + + + "Url Coding" | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

"Url Coding"

subtitle: "与url相关的处理"

#Encoding and Decoding URL Data

To percent-encode part of a URL string, use the ==NSString== method ==stringByAddingPercentEncodingWithAllowedCharacters==:, passing the appropriate character set for the URL component or subcomponent: • User: ==URLUserAllowedCharacterSet== • Password: ==URLPasswordAllowedCharacterSet== • Host: ==URLHostAllowedCharacterSet== • Path: ==URLPathAllowedCharacterSet== • Fragment: ==URLFragmentAllowedCharacterSet== • Query: ==URLQueryAllowedCharacterSet==

Important: Don’t use stringByAddingPercentEncodingWithAllowedCharacters: to encode an entire URL string, because each URL component or subcomponent has different rules for what characters are valid.

For example, to percent-encode a UTF-8 string for inclusion in a URL path, you do the following:

  NSString *str = @"http://192.168.2.123:80/u=142020185,2790987080&fm=26&gp=0的副本.jpg";
+    NSString *urlStr = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+    [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
+    NSURL *url = [NSURL URLWithString:urlStr];

If you want to decode a percent-encoded URL component, use NSURLComponents to split the URL into its constituent parts and access the corresponding property. For example, to get the UTF-8 string value for a percent-encoded URL path, you do the following:

NSString *encodeStr = @"http://192.168.2.123:80/u=142020185,2790987080&fm=26&gp=0%E7%9A%84%E5%89%AF%E6%9C%AC.jpg";
+
+//   NSURL *url2 = [NSURL URLWithString:encodeStr];
+//    NSURLComponents *component = [NSURLComponents componentsWithURL:url2 resolvingAgainstBaseURL:NO];
+    NSURLComponents *component = [NSURLComponents componentsWithString:encodeStr];
+    NSString *path = component.path;
+    NSLog(@"path=%@",path);

The user component of a URL is an optional component that precedes the host component, and ends at either a colon (if a password is specified) or an @ sign (if no password is specified). For example, in the URL http://username:password@www.example.com/index.html#jumpLocation, the user component is username the pass component is password the host component is www.example.com the path component is /index.html the fragment is jumpLocation

date: 2017-06-06 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/version-share.html b/docs/.vitepress/dist/frontend/ios/version-share.html new file mode 100644 index 0000000..ffee872 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/version-share.html @@ -0,0 +1,25 @@ + + + + + + Version | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Version

开发版本对比

DEV : Development System 开发 SIT : System Integration Testing 系统集成 UAT : User Acceptance Testing 用户测试 QAS : Quality Assurance System 质量保证体系 PRD : Production System 生产系统

Load Testing 负载测试 Stress Testing 压力测试 Performance Evaluation Testing(PET)性能测试

date: 2017-09-18 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/webScoket.html b/docs/.vitepress/dist/frontend/ios/webScoket.html new file mode 100644 index 0000000..a496920 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/webScoket.html @@ -0,0 +1,428 @@ + + + + + + WebScoket Introduction | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

WebScoket Introduction

WebScoket

ios示例:

SocketManager.h 文件

#import <Foundation/Foundation.h>
+// 替换为自己的IP地址
+static NSString *kHost = @"192.168.2.22";
+static NSInteger kPort = 8080;
+static NSString *kAdress = @"/websocket/message";
+
+typedef enum : NSUInteger {
+    disConnectByUser ,
+    disConnectByServer,
+} DisConnectType;
+
+
+@interface SocketManager : NSObject
+
++ (instancetype)shared;
+
+- (void)connect;
+- (void)disConnect;
+
+- (void)sendMessage:(NSString *)message;
+
+- (void)receiveMessage:(void(^)(NSString *str))measge;
+
+- (void)ping;
+
+@end

SocketManager.m 文件

#import "SocketManager.h"
+#import <SocketRocket/SocketRocket.h>
+
+
+#define dispatch_main_async_safe(block)\
+        if ([NSThread isMainThread]) {\
+        block();\
+        }else{\
+            dispatch_async(dispatch_get_main_queue(), block);\
+        }
+
+
+@interface SocketManager()<SRWebSocketDelegate>
+
+@property(nonatomic,strong)SRWebSocket *webSocket;
+@property(nonatomic,strong)NSTimer *heartBeat;
+@property(nonatomic,assign)NSTimeInterval reConnectTime;
+@property(nonatomic,copy)void(^receiveMsg)(NSString *str);
+@end
+
+
+@implementation SocketManager
+
++(instancetype)shared
+{
+    static SocketManager *instance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        instance = [[self alloc] init];
+        
+    });
+    return instance;
+}
+
+- (void)initSocket
+{
+    if (self.webSocket) {
+        return;
+    }
+    
+    self.webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"ws://%@:%ld%@",kHost,(long)kPort,kAdress]]];
+    self.webSocket.delegate = self;
+    
+    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+    queue.maxConcurrentOperationCount = 1;
+    
+    [self.webSocket setDelegateOperationQueue:queue];
+    
+    [_webSocket open];
+    
+    
+    
+}
+
+
+- (void)initHeartBeat
+{
+    dispatch_main_async_safe(^{
+        [self destoryHeartBeat];
+        
+        self.heartBeat = [NSTimer scheduledTimerWithTimeInterval:3*60 target:self selector:@selector(sendHeartMessage) userInfo:nil repeats:YES];
+        [[NSRunLoop currentRunLoop] addTimer:self.heartBeat forMode:NSRunLoopCommonModes];
+    })
+}
+
+- (void)sendHeartMessage
+{
+//    [self sendMessage:@"heart"];
+    [self ping];
+}
+
+
+- (void)destoryHeartBeat
+{
+    dispatch_main_async_safe(^{
+        if (self.heartBeat) {
+            [self.heartBeat invalidate];
+            self.heartBeat = nil;
+        }
+    })
+}
+
+// 建立连接
+- (void)connect
+{
+    [self initSocket];
+    
+    self.reConnectTime = 0;
+}
+
+//重连机制
+- (void)reConnect
+{
+    [self disConnect];
+    
+    if (_reConnectTime >64) {
+        return;
+    }
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        self.webSocket = nil;
+        [self initSocket];
+    });
+    
+    if (_reConnectTime == 0) {
+        _reConnectTime = 2;
+    }else
+    {
+        _reConnectTime *= 2;
+    }
+    
+    
+}
+
+- (void)disConnect
+{
+    if (self.webSocket) {
+        [self.webSocket close];
+        _webSocket = nil;
+    }
+}
+
+- (void)sendMessage:(NSString *)message
+{
+    
+    NSLog(@"readyState=%ld",(long)self.webSocket.readyState);
+    // 发送文本数据
+    [self.webSocket send:message];
+    // 发送二进制数据
+//    [self.webSocket send:[message dataUsingEncoding:NSUTF8StringEncoding]];
+  
+}
+
+- (void)ping
+{
+    NSError *error = nil;
+    
+    [self.webSocket sendPing:nil];
+    NSLog(@"sendpingError=%@",error);
+}
+
+- (void)receiveMessage:(void (^)(NSString *))measge
+{
+    self.receiveMsg = measge;
+}
+
+#pragma mark - SRWebSocketDelegate
+- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
+{
+    NSLog(@"服务器返回收到消息:%@",message);
+    dispatch_main_async_safe(^{
+        if (message) {
+            self.receiveMsg(message);
+//            [self receiveMessage:(message)];
+        }
+ 
+    }
+    )
+    
+}
+
+- (void)webSocketDidOpen:(SRWebSocket *)webSocket
+{
+    NSLog(@"连接成功");
+    
+    //连接成功了开始发送心跳
+    [self initHeartBeat];
+}
+
+//open失败的时候调用
+-(void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
+{
+    NSLog(@"连接失败.....\n%@",error);
+    
+    //失败了就去重连
+    [self reConnect];
+}
+
+//网络连接中断被调用
+- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean
+{
+    NSLog(@"被关闭连接,code:%ld,reason:%@,wasClean:%d",code,reason,wasClean);
+    
+    //如果是被用户自己中断的那么直接断开连接,否则开始重连
+    if (code == disConnectByUser) {
+        [self disConnect];
+    }else{
+        
+        [self reConnect];
+    }
+    //断开连接时销毁心跳
+    [self destoryHeartBeat];
+    
+}
+
+//sendPing的时候,如果网络通的话,则会收到回调,但是必须保证ScoketOpen,否则会crash
+- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload
+{
+    NSLog(@"收到pong回调");
+    
+}
+
+
+@end

本例使用Tomcat7作为服务器容器 java 服务端示例

创建Message类来接受客户端发来的websocket请求

import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.PongMessage;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+@ServerEndpoint("/message")
+public class Message {
+
+	
+	private static Set<Client> clientSet = new CopyOnWriteArraySet<>();
+	
+	
+	@OnOpen
+	public void onOpen(Session session) {
+		String id = session.getId();
+		System.out.println("onOpen,id:"+session.getId());
+		Client client = new Client(session, id);
+		clientSet.add(client);
+		
+		System.out.println(clientSet);
+	}
+	
+	@OnClose
+	public void onClose(Session session) {
+		System.out.println("onClose,id:"+session.getId());
+		for(Client client:clientSet) {
+			if(client.getSession().equals(session))
+			{
+				clientSet.remove(client);
+				break;
+			}
+		}
+	}
+	// 文本消息 String 类型
+	@OnMessage
+	public void onMessage(Session session, String msg,boolean last) {
+		System.out.println("onMessage,id="+session.getId()+",msg="+msg);
+		
+		try {
+			if(session.isOpen()) {
+				broadcast(session, msg);
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+		
+	}
+	// 对于二进制数据 使用byte[]或ByteBuffer
+	@OnMessage
+	public void onMesasge(Session session,byte[] data,boolean isLast) {
+//	public void onMesasge(Session session,ByteBuffer buf,boolean isLast) {
+		
+		String msg = new String(data);
+		System.out.println("dataOnMessage,id="+session.getId()+",msg="+msg);
+		try {
+			if(session.isOpen()) {
+				broadcast(session, msg);
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+	}
+
+	// 使用PongMessage接受pong消息
+	@OnMessage
+	public void onMessage(Session session,PongMessage pong) {
+		System.out.println("pong:"+pong.toString());
+		ByteBuffer buf = pong.getApplicationData();
+		Charset charset = Charset.forName("UTF-8");
+		CharsetDecoder decoder = charset.newDecoder();
+		try {
+			CharBuffer charBuffer = decoder.decode(buf.asReadOnlyBuffer());
+			String pon = charBuffer.toString();
+			System.out.println("pong:"+pon);
+		} catch (CharacterCodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		
+	}
+//	
+	@OnError
+	public void onError(Throwable t) throws Throwable
+    {
+        System.out.println("WebSocket 服务端错误" + t);
+    }
+	
+	private static void broadcast(Session currentSession,String msg) {
+		for(Client client:clientSet) {
+			if(client.getSession().equals(currentSession)) {
+				continue;
+			}
+			
+			try {
+				synchronized (client) {
+					client.getSession().getBasicRemote().sendText(msg);
+					
+				}
+			} catch (Exception e) {
+				// TODO: handle exception
+				System.out.println("向客户端"+client.getClientID()+"发送消息错误");
+				clientSet.remove(client);
+				try {
+					client.getSession().close();
+				} catch (IOException e1) {
+					// TODO Auto-generated catch block
+					e1.printStackTrace();
+					
+				}
+			}
+		}
+	}
+
+}

使用浏览器模拟客户端的文件如下: jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+服务器返回的信息:  
+<input type="text" id="show"/>  
+  
+浏览器发送的信息:  
+<input type="text" id="msg"/>  
+<input type="button" value="send" id="send" onclick="q()"/>  
+
+<script>  
+    var ws = null ;  
+    // 替换为自己的IP地址
+    var target="ws://192.168.2.22:8080/websocket/message";  
+    if ('WebSocket' in window) {  
+        ws = new WebSocket(target);  
+    } else if ('MozWebSocket' in window) {  
+        ws = new MozWebSocket(target);  
+    } else {  
+        alert('WebSocket is not supported by this browser.');  
+    }  
+  
+    ws.onopen = function(obj){  
+        console.info('open') ;  
+        console.info(obj) ;  
+    } ;  
+      
+    ws.onclose = function (obj) {  
+        console.info('close') ;  
+        console.info(obj) ;  
+    } ;  
+    ws.onmessage = function(obj){  
+        console.info(obj) ;  
+        document.getElementById('show').value=obj.data;  
+    } ;  
+    function q(){  
+        ws.send(document.getElementById('msg').value);  
+    }  
+</script>  
+</body>
+</html>

date: 2017-11-27 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/webview-share.html b/docs/.vitepress/dist/frontend/ios/webview-share.html new file mode 100644 index 0000000..ff85608 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/webview-share.html @@ -0,0 +1,78 @@ + + + + + + "WebView" | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

"WebView"

WKWebView 发送Post请求

在ios8中 使用如下代码 设置请求体仅在UIWebView中好使,在WKWebView中设置的Content-Length始终为0;也就是发送请求的时候,请求体的内容并没携带一起发送给服务器。 备注:在UIWebView中Content-Length与Content-Type默认会自动创建出来

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
+    NSData *bodyData = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
+    
+    [request setHTTPMethod:@"POST"];
+    [request setValue:[NSString stringWithFormat:@"%ld",bodyData.length] forHTTPHeaderField:@"Content-Length"];
+    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
+    
+    [request setHTTPBody:bodyData];

在WKWebView中需要换种方式处理,即使用js发送post请求,而当webView已经创建的时候,即可执行js。 所以在viewDidLoad方法中调用执行js的方法

js的宏定义如下:

#define POST_JS @"function postWebRequest(path, params) {\
+var method = \"POST\";\
+var form = document.createElement(\"form\");\
+form.setAttribute(\"method\", method);\
+form.setAttribute(\"action\", path);\
+for(var key in params){\
+if (params.hasOwnProperty(key)) {\
+var hiddenFild = document.createElement(\"input\");\
+hiddenFild.setAttribute(\"type\", \"hidden\");\
+hiddenFild.setAttribute(\"name\", key);\
+hiddenFild.setAttribute(\"value\", params[key]);\
+}\
+form.appendChild(hiddenFild);\
+}\
+document.body.appendChild(form);\
+form.submit();\
+}"
- (WKWebView *)wkWebView
+{
+    if (!_wkWebView){
+        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
+        WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
+        webView.navigationDelegate = self;
+
+        [self.view addSubview:webView];
+        
+        _wkWebView = webView;
+    }
+    return _wkWebView;
+}
+
+- (void)makeWKWebViewPostRequestWithUrl:(NSString *)url param:(NSString *)bodyStr
+{
+
+    
+    NSString *js = [NSString stringWithFormat:@"%@postWebRequest('%@',%@)",POST_JS,url,bodyStr];
+    [self.wkWebView evaluateJavaScript:js completionHandler:^(id _Nullable msg, NSError * _Nullable error) {
+        DLog(@"JavaScriptError=%@",error);
+        
+    }];
+}
- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    NSString *url = @"http://www.xxx.com";
+    NSString *bodyStr = [NSString stringWithFormat:@"{'username':'%@','password':'%@'}",@"zhangsan",@"12345678"];
+    
+   [self makeWKWebViewPostRequestWithUrl:url param:bodyStr];
+}

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/ios/xcode build.html b/docs/.vitepress/dist/frontend/ios/xcode build.html new file mode 100644 index 0000000..fb0b186 --- /dev/null +++ b/docs/.vitepress/dist/frontend/ios/xcode build.html @@ -0,0 +1,171 @@ + + + + + + ios 自动打包脚本 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

ios 自动打包脚本

1. 配置导出plist文件

在项目工程相同的目录下创建 ExportOptions_UAT.plist 文件,文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>compileBitcode</key>
+	<false/>
+	<key>destination</key>
+	<string>export</string>
+	<key>method</key>
+	<!-- 企业证书打包 -->
+	<string>enterprise</string>
+	<key>provisioningProfiles</key>
+	<dict>
+		<!-- bundle id -->
+		<key>com.xxx.xxxx.xxxx.uat</key>
+		<!-- 描述文件的名称 -->
+		<string>DemoUAT_Distribution</string>
+	</dict>
+	<key>signingCertificate</key>
+	<string>iPhone Distribution</string>
+	<key>signingStyle</key>
+	<string>manual</string>
+	<key>stripSwiftSymbols</key>
+	<true/>
+	<key>teamID</key>
+	<string>P*******3X</string>
+</dict>
+</plist>

1. 配置shell脚本

在项目工程相同的目录下创建 uat_shell.sh 文件,文件的内容如下:

#使用方法
+
+if [ ! -d ./IPADir ];
+then
+mkdir -p IPADir;
+fi
+
+#工程绝对路径
+project_path=$(cd `dirname $0`; pwd)
+
+#工程名 将XXX替换成自己的工程名,比如 Demo
+project_name=XXX
+
+#scheme名 将XXX替换成自己的工程的sheme名, 为 target name,比如 Demo_Uat
+scheme_name=XXX
+
+#打包模式 Debug/Release
+development_mode=Release
+
+#build文件夹路径
+build_path=${project_path}/build
+
+#plist文件所在路径
+exportOptionsPlistPath=${project_path}/ExportOptions_UAT.plist
+
+#导出.ipa文件所在路径
+exportIpaPath=${project_path}/IPADir/${development_mode}
+
+
+echo "Place enter the number you want to export ? [ 1:app-store 2:enterprise] "
+
+##
+read number
+while([[ $number != 1 ]] && [[ $number != 2 ]])
+do
+echo "Error! Should enter 1 or 2"
+echo "Place enter the number you want to export ? [ 1:app-store 2:enterprise] "
+read number
+done
+
+if [ $number == 1 ];then
+development_mode=Release
+exportOptionsPlistPath=${project_path}/exportAppstore.plist
+else
+development_mode=Release
+exportOptionsPlistPath=${project_path}/ExportOptions_UAT.plist
+fi
+
+
+echo '///-----------'
+echo '/// 正在清理工程'
+echo '///-----------'
+xcodebuild \
+clean -configuration ${development_mode} -quiet  || exit
+
+
+echo '///--------'
+echo '/// 清理完成'
+echo '///--------'
+echo ''
+
+echo '///-----------'
+echo '/// 正在编译工程:'${development_mode}
+echo '///-----------'
+xcodebuild \
+archive -workspace ${project_path}/${project_name}.xcworkspace \
+-scheme ${scheme_name} \
+-configuration ${development_mode} \
+-archivePath ${build_path}/${project_name}.xcarchive  -quiet  || exit
+
+echo '///--------'
+echo '/// 编译完成'
+echo '///--------'
+echo ''
+
+echo '///----------'
+echo '/// 开始ipa打包'
+echo '///----------'
+xcodebuild -exportArchive -archivePath ${build_path}/${project_name}.xcarchive \
+-configuration ${development_mode} \
+-exportPath ${exportIpaPath} \
+-exportOptionsPlist ${exportOptionsPlistPath} \
+-quiet || exit
+
+if [ -e $exportIpaPath/$scheme_name.ipa ]; then
+echo '///----------'
+echo '/// ipa包已导出'
+echo '///----------'
+open $exportIpaPath
+else
+echo '///-------------'
+echo '/// ipa包导出失败 '
+echo '///-------------'
+fi
+echo '///------------'
+echo '/// 打包ipa完成  '
+echo '///-----------='
+echo ''
+
+echo '///-------------'
+echo '/// 开始发布ipa包 '
+echo '///-------------'
+
+if [ $number == 1 ];then
+
+#验证并上传到App Store
+# 将-u 后面的XXX替换成自己的AppleID的账号,-p后面的XXX替换成自己的密码
+altoolPath="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
+"$altoolPath" --validate-app -f ${exportIpaPath}/${scheme_name}.ipa -u XXX -p XXX -t ios --output-format xml
+"$altoolPath" --upload-app -f ${exportIpaPath}/${scheme_name}.ipa -u  XXX -p XXX -t ios --output-format xml
+else
+
+#上传到Fir
+# 将XXX替换成自己的Fir平台的token
+fir login -T XXX
+fir publish $exportIpaPath/$scheme_name.ipa
+
+fi
+
+exit 0

date: 2020-12-17 14:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/js/index.html b/docs/.vitepress/dist/frontend/js/index.html new file mode 100644 index 0000000..b561600 --- /dev/null +++ b/docs/.vitepress/dist/frontend/js/index.html @@ -0,0 +1,25 @@ + + + + + + JS 的使用 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

JS 的使用

Web JS的组成

ECMAScript + DOM + BOM

  • ECMAScript(前身为欧洲计算机制造商协会)
  • JavaScript的语法规范
  • DOM(Document Object Model 的简称)
  • JavaScript操作网页上元素的API
  • BOM(Browser Object Model 的简称)
  • JavaScript操作浏览器部分功能的API

输出语句

  • console.log(“内容”)在控制台打印输出内容
  • console.error(“错误”)在控制台打印输出错误内容
  • console.warn(“警告”)在控制台打印输出警告内容
  • alert(“内容”)弹窗显示内容
  • document.write(“内容”)在页面书写内容
  • prompt(“输入”)
  • confirm(“”)

数据类型

  1. 值类型
  • 字符串 数字 布尔 未定义
  • String Number Boolean undefined
  1. 引用类型
    • Object function Array Date null ...

3.1. 值类型介绍

函数

js中没有方法重载 函数也是一种类型

date: 2018-10-05 14:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/other/2020-03-12-ionic.html b/docs/.vitepress/dist/frontend/other/2020-03-12-ionic.html new file mode 100644 index 0000000..f974410 --- /dev/null +++ b/docs/.vitepress/dist/frontend/other/2020-03-12-ionic.html @@ -0,0 +1,25 @@ + + + + + + ionic 入门 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/other/2020-03-22-angular.html b/docs/.vitepress/dist/frontend/other/2020-03-22-angular.html new file mode 100644 index 0000000..d6da270 --- /dev/null +++ b/docs/.vitepress/dist/frontend/other/2020-03-22-angular.html @@ -0,0 +1,25 @@ + + + + + + angular 入门 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/other/index.html b/docs/.vitepress/dist/frontend/other/index.html new file mode 100644 index 0000000..16b9c7d --- /dev/null +++ b/docs/.vitepress/dist/frontend/other/index.html @@ -0,0 +1,25 @@ + + + + + + react 入门 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/01-Getting Started/Basic Setup.html b/docs/.vitepress/dist/frontend/swift/01-Getting Started/Basic Setup.html new file mode 100644 index 0000000..f612fc6 --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/01-Getting Started/Basic Setup.html @@ -0,0 +1,25 @@ + + + + + + 基本设置 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

基本设置

Swift 可无缝兼容 Cocoa 和 Objective-C。在 Swift,可以使用 Objective-C API,也可以在 Objective-C 中使用 Swift API。这种兼容性能让 Swift 作为一个简洁、易用、强大的工具集成到你的 Cocoa 应用开发流程中。

这篇指南包括了三个有关兼容性的重要方面,能够帮你更好地利用这种兼容性来开发 Cocoa 应用:

  • 交互 可以将 Swift 和 Objective-C 相接合,在 Objective-C 中使用 Swift 类,并利用熟悉的 Cocoa 类、设计模式以及各种实践经验。
  • 混搭 可以创建结合了 Swift 和 Objective-C 文件的混合语言应用,并且它们能跟彼此进行通信。
  • 迁移 由于以上两点,从现有的 Objective-C 代码迁移到 Swift 会非常简单,这使运用最新的 Swift 特性取代你的 Objective-C 应用中的部分内容成为了可能。

在开始学习这些特性前,需要对如何搭建 Swift 环境来使用 Cocoa 系统框架有个大致了解。

搭建 Swift 环境

为了开始体验在 Swift 中访问 Cocoa 框架,使用 Xcode 的一个模板来创建一个基于 Swift 的应用。

在 Xcode 中创建一个 Swift 项目

1.选择File > New > Project > (iOS,watchOS,tvOS 或 OS X) > Application,然后选择一个模板。

2.点击Language下拉菜单并选择 Swift。

Swift 项目的结构几乎和 Objective-C 项目一模一样,只有一个重要的区别:Swift 没有头文件。在接口和实现之间没有显式划分,一个类中的所有信息都在一个单独的.swift文件中,详情请参阅 在项目中同时使用 Swift 和 Objective-C 章节。

现在可以开始尝试在AppDelegate中编写 Swift 代码,或者可以选择File > New > File > (iOS,watchOS,tvOS 或 OS X) > Source > Swift来创建一个新的 Swift 文件。

要求

使用 Swift 3.0 创建应用需要使用 Xcode 8.0 或更高版本,而且使用的 SDK 有如下要求:

平台SDK 要求
macOS10.12
iOS10.0
watchOS3.0
tvOS10.0

Swift 编译器和 Xcode 强制要求最低部署版本为iOS 7macOS 10.9,设置更早的部署版本会导致编译错误。

注意
由命令行构建的 Swift 可执行文件必须能在它的@rpath下找到 Swift 标准库,因此发布时需要同时包含 Swift 动态库。由 Xcode 构建的 Swift 可执行文件则自带静态链接的运行时库。

理解 Swift 导入过程

在你建立 Xcode 项目后,可以在 Swift 里导入任何 Cocoa 或者 Cocoa Touch 的框架。

任何 Objective-C 框架或 C 语言类库,都将作为一个module直接导入到 Swift 中。这包括了所有 Objective-C 系统框架——比如 Foundation、UIKit 和 SpriteKit,以及系统支持的 C 语言类库。例如,想导入 Foundation,只要简单地添加导入语句到 Swift 文件的顶部:

swift
import Foundation

通过这个导入语句,Swift 文件现在可以访问所有 Foundation 中的类、协议、方法、属性以及常量。

导入过程非常简单。Objective-C 框架在头文件中公开 API。在 Swift,那些头文件被编译成 Objective-C 模块,接着被导入到 Swift 作为 Swift 的 API。导入过程决定了 Objective-C 代码中的函数、类、方法以及声明的类型如何在 Swift 中呈现。对于函数和方法,这个过程将影响它们的参数和返回值的类型。对于类型来说,导入过程会做以下处理:

  • 重映射 Objective-C 类型到 Swift 中的同等类型,例如id映射为Any
  • 重映射 Objective-C 核心类型到 Swift 中的替代类型,例如NSString映射为String
  • 重映射 Objective-C 概念到 Swift 中相对应的概念,例如指针映射为可选类型

想了解更多信息,请参阅 与 Objective-C API 交互 章节。

注意
C++ 代码无法直接导入 Swift,必须为其创建 Objective-C 或者 C 的封装。

导入 Swift 模块到 Objective-C 和上述过程非常相似。Swift 公开它的 API,例如来自系统框架的 API,作为 Swift 模块。随着这些 Swift 模块还会生成 Objective-C 头文件。这些头文件公开了那些可以映射回 Objective-C 的 API。一些 Swift API 无法映射回 Objective-C,因为它们使用了 Objective-C 中不存在的语言特性。

想了解更多信息,请参阅 在项目中同时使用 Swift 和 Objective-C 章节。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html b/docs/.vitepress/dist/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html new file mode 100644 index 0000000..fbab7a6 --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.html @@ -0,0 +1,261 @@ + + + + + + 与 Objective-C API 交互 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

与 Objective-C API 交互

互用性是能让 Swift 和 Objective-C 相接合的特性,这使你能够在一种语言编写的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,学会如何利用互用性来重新定义、改善并提高你编写 Cocoa 应用的方法,不失为一个好主意。

互用性很重要的一点就是允许你在编写 Swift 代码时使用 Objective-C API。导入一个 Objective-C 框架后,可以使用原生的 Swift 语法实例化这些类并与之交互。

初始化

要在 Swift 中实例化一个 Objective-C 类,你应该使用 Swift 语法调用它的一个构造器。

Objective-C 构造器以init开头,如果它接收参数,则会以initWith开头。Objective-C 构造器导入到 Swift 后,init前缀变为init关键字,以此表明该方法是 Swift 构造方法。如果构造器接收参数,With单词会被移除,方法名的其余部分则会被分配为相应的命名参数。

例如,思考如下 Objective-C 构造器声明:

objective-c
- (instancetype)init;
+- (instancetype)initWithFrame:(CGRect)frame
+                        style:(UITableViewStyle)style;

Swift 中等价的构造器声明如下所示:

swift
init() { /* ... */ }
+init(frame: CGRect, style: UITableViewStyle) { /* ... */ }

Objective-C 和 Swift 构造器语法的区别在实例化对象时将更为明显:

在 Objective-C 这样写:

objective-c
UITableView *myTableView = [[UITableView alloc] initWithFrame:.zero 
+                                                        style:UITableViewStyleGrouped];

在 Swift 则应该这样写:

swift
let myTableView: UITableView = UITableView(frame: .zero, style: .grouped)

注意,你不需要调用alloc,Swift 会为你处理。另外,调用任何 Swift 构造方法时都不会出现init单词。

你可以在赋值时显式地声明类型,也可以省略类型,Swift 能从构造器自动推断出类型。

swift
let myTextField = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 40.0))

此处的UITableViewUITextField对象和你在 Objective-C 中实例化的一样。你可以用同样的方式使用它们,例如访问属性或者调用各自类中的方法。

类工厂方法和便利构造器

为了统一和简洁,Objective-C 中的类工厂方法被导入为 Swift 中的便利构造器,从而能使用同样简洁的构造器语法。

例如,在 Objective-C 像这样调用一个工厂方法:

objective-c
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

在 Swift 应该这样写:

swift
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

可失败初始化

在 Objective-C,构造器会直接返回它们初始化的对象。初始化失败时,为了告知调用者,Objective-C 构造器会返回nil。在 Swift,这种模式被内置到语言特性中,被称为可失败初始化

许多系统框架中的 Objective-C 构造器在导入到 Swift 时会被检查初始化是否会失败。你可以在你的 Objective-C 类中,使用为空性标注来指明初始化是否会失败,请参阅 为空性和可选类型 小节。如果初始化不会失败,这些 Objective-C 构造器会作为init(...)导入,而如果初始化会失败,则会作为init?(...)导入。在没有任何为空性标注的情况下,Objective-C 构造器会作为init!(...)导入。

例如,当指定路径的图片文件不存在时,使用UIImage(contentsOfFile:)构造器初始化UIImage对象便会失败。你可以用可选绑定语法对这种构造器的可选类型的返回值进行解包,从而判断初始化是否成功。

swift
if let image = UIImage(contentsOfFile: "MyImage.png") {
+    // 加载图片成功
+} else {
+    // 无法加载图片
+}

访问属性

在 Objective-C 中使用@property语法声明的属性会以如下方式导入到 Swift:

  • 具有为空性属性特性的属性(nonnullnullablenull_resettable),作为可选类型或者非可选类型的属性导入。请参阅 为空性和可选类型 小节。
  • 具有readonly属性特性的属性,作为只读计算型属性({ get })导入。
  • 具有weak属性特性的属性,作为标记weak关键字(weak var)的属性导入。
  • 具有assigncopystrongunsafe_unretained属性特性的属性,导入后会具有相应的内存管理策略。
  • 具有class属性特性的属性,作为类型属性导入。
  • 原子属性特性(atomicnonatomic)在 Swift 属性声明中并无相应体现,不过 Objective-C 中具有原子性的属性在 Swift 中将保持其原子性。
  • 存取器属性特性(getter=setter=)会被 Swift 忽略。

在 Swift 中使用点语法对属性进行存取,直接使用属性名即可,不需要附加圆括号。

例如,如下代码设置了UITextField对象的textColortext属性:

swift
myTextField.textColor = UIColor.darkGray
+myTextField.text = "Hello world"

在 Objective-C,一个有返回值的无参数方法可以像属性那样使用点语法调用。然而,它们会被导入为 Swift 中的实例方法,只有在 Objective-C 中使用@property声明的属性才会导入为 Swift 中的属性。方法的导入和调用请参阅 方法 小节。

方法

在 Swift 中使用点语法调用方法。

当 Objective-C 方法导入到 Swift 时,Objective-C 选择器的第一部分将会成为基本方法名并出现在圆括号的前面。第一个参数将直接在圆括号中出现,并且没有参数名。选择器的其余部分作为相应的参数名,出现在方法的圆括号内。选择器的所有部分在调用时都必须写上。

例如,在 Objective-C 这样写:

objective-c
[myTableView insertSubview:mySubview atIndex:2];

在 Swift 则应该这样写:

swift
myTableView.insertSubview(mySubview, atIndex: 2)

如果调用一个无参数的方法,仍须在方法名后面跟上一对圆括号:

swift
myTableView.layoutIfNeeded()

id 兼容性

Objective-C 中的id类型会作为 Swift 中的Any类型导入。无论在编译期还是运行期,当 Swift 值或者对象作为id参数传入 Objective-C 时,编译器都会引入一种通用的桥接转换操作。当id类型作为Any类型导入到 Swift 时,运行时会自动处理桥接回相应的 Swift 类类型或值类型的工作。

swift
var x: Any = "hello" as String
+x as? String   // 值为 "hello" 的 String 
+x as? NSString // 值为 "hello" 的 NSString
+
+x = "goodbye" as NSString
+x as? String   // 值为 "goodbye" 的 String
+x as? NSString // 值为 "goodbye" 的 NSString

将 Any 向下转换

使用一个Any类型的对象时,如果其具体类型已知或者可以断定,将其向下转换到具体类型往往会更有用处。然而,由于Any类型可以引用任何类型,因此无法保证向下转换到具体类型一定成功。

可以使用条件转换操作符(as?),这将返回目标类型的可选值:

swift
let userDefaults = UserDefaults.standard
+let lastRefreshDate = userDefaults.object(forKey: "LastRefreshDate") // lastRefreshDate 类型为 Any?
+if let date = lastRefreshDate as? Date {
+    print("\(date.timeIntervalSinceReferenceDate)")
+}

如果确信对象的类型,可以使用强制下转操作符(as!):

swift
let myDate = lastRefreshDate as! Date
+let timeInterval = myDate.timeIntervalSinceReferenceDate

然而,一旦强制下转失败,将触发一个运行时错误:

swift
let myDate = lastRefreshDate as! String // Error

动态方法查找

Swift 还引入了AnyObject类型来表示一种对象类型,这种对象具有能够动态查找@objc方法的能力。这使你在访问返回值为id类型的 Objective-C 方法时能保持无类型的灵活性。

例如,你可以将任意类型的对象赋值给一个AnyObject类型的常量或者变量,如果是变量,你还可以再用其他类型的对象为其赋值。你还可以在AnyObject类型的值上调用任意 Objective-C 方法以及访问属性,而无需将其转换为具体类型。

swift
var myObject: AnyObject = UITableViewCell()
+myObject = NSDate()
+let futureDate = myObject.addingTimeInterval(10)
+let timeSinceNow = myObject.timeIntervalSinceNow

无法识别的选择器和可选链语法

因为AnyObject类型的值在运行时才能确定其真实类型,所以有可能在不经意间写出不安全代码。在 Swift,和 Objective-C 一样,试图调用不存在的方法将触发未识别的选择器错误。

例如,如下代码在编译时没有任何编译警告,但是会在运行时触发一个错误:

swift
myObject.character(at: 5)
+// 崩溃,myObject 无法响应该方法

Swift 使用可选来防止这种不安全的行为。当用AnyObject类型的值调用一个 Objective-C 方法时,方法调用在行为上类似于隐式解包可选。可以像调用协议中的可选方法那样,使用可选链语法在AnyObject上调用方法。

例如,在下面的代码中,第一和第二行代码不会被执行,因为count属性和character(at:)方法不存在于NSDate对象中。myCount常量会被推断为Int?,并被赋值为nil。你也可以使用if-let语句来有条件地解包这种可能无法被响应的方法的返回值,就像第三行所做的一样。

swift
// myObject 类型为 AnyObject,保存着 NSDate 类型的值
+let myCount = myObject.count // myCount 类型为 Int?,其值为 nil
+let myChar = myObject.character?(at: 5) // myChar 类型为 unichar?,其值为 nil
+if let fifthCharacter = myObject.character?(at: 5) { 
+    print("Found \(fifthCharacter) at index 5") // 条件分支不会被执行
+}

注意
尽管在使用AnyObject类型的值调用方法时不需要强制解包,但建议使用强制解包的方式来防止一些意想不到的行为。

为空性和可选类型

在 Objective-C,用于操作对象的原始指针的值可能会是NULL(在 Objective-C 中称为nil)。而在 Swift,所有的值,包括结构体与对象的引用,都能确保是非空值。作为替代,可以将可能会值缺失的值包装为该类型的可选类型。当你需要表示值缺失的情况时,你可以将其赋值为nil。请参阅 The Swift Programming Language 中文版 中的 可选类型 小节获取更多关于可选类型的信息。

在 Objective-C 可以使用为空性标注来指明一个参数类型、属性类型或者返回值类型是否可以为NULLnil值。单个类型声明可以使用_Nullable_Nonnull标注,单个属性声明可以使用nullablenonnullnull_resettable属性特性,批量标注可以使用NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END宏。如果一个类型没有任何为空性标注,Swift 就无法辨别它是可选类型还是非可选类型,因此将其作为隐式解包可选类型导入。

  • _Nonnull或者范围宏标注的类型,会作为非可选类型导入到 Swift。
  • _Nullable标注的类型,会作为可选类型导入到 Swift。
  • 没有为空性标注的类型,会作为隐式解包可选类型导入到 Swift。

举个例子,思考如下 Objective-C 声明:

objective-c
@property (nullable) id nullableProperty;
+@property (nonnull) id nonNullProperty;
+@property id unannotatedProperty;
+ 
+NS_ASSUME_NONNULL_BEGIN
+- (id)returnsNonNullValue;
+- (void)takesNonNullParameter:(id)value;
+NS_ASSUME_NONNULL_END
+ 
+- (nullable id)returnsNullableValue;
+- (void)takesNullableParameter:(nullable id)value;
+ 
+- (id)returnsUnannotatedValue;
+- (void)takesUnannotatedParameter:(id)value;

导入到 Swift 后将如下所示:

swift
var nullableProperty: Any?
+var nonNullProperty: Any
+var unannotatedProperty: Any!
+
+func returnsNonNullValue() -> Any
+func takesNonNullParameter(value: Any)
+
+func returnsNullableValue() -> Any?
+func takesNullableParameter(value: Any?)
+
+func returnsUnannotatedValue() -> Any!
+func takesUnannotatedParameter(value: Any!)

大多数 Objective-C 系统框架,包括 Foundation,都已经提供了为空性标注,这使你能以更加类型安全的方式去操作各种值。

将可选值桥接为 NSNull 实例

Swift 会根据可选值是否有值来决定是否将其桥接为 Objective-C 的NSNull实例。如果可选值的值为nil,Swift 会将nil值桥接为NSNull实例。否则,Swift 会将可选值桥接为它所包装的值。例如,当一个可选值传给一个接受非空id类型参数的 Objective-C API 时,或者将一个元素为可选类型的数组([T?])桥接为NSArray时。

如下代码展示了String?实例如何根据它是否有值来桥接到 Objective-C。

objective-c
@implementation OptionalBridging
++ (void)logSomeValue:(nonnull id)valueFromSwift {
+    if ([valueFromSwift isKindOfClass: [NSNull class]]) {
+        os_log(OS_LOG_DEFAULT, "Received an NSNull value.");
+    } else {
+        os_log(OS_LOG_DEFAULT, "%s", [valueFromSwift UTF8String]);
+    }
+}
+@end

因为valueFromSwift参数的类型是id,它会作为Any类型导入到 Swift。由于很少将可选值传递给Any类型,因此在将可选值传递给类方法logSomeValue(_:)时需要将参数显式转换为Any类型,从而消除编译警告。

swift
let someValue: String? = "Bridge me, please."
+let nilValue: String? = nil
+
+OptionalBridging.logSomeValue(someValue as Any)  // Bridge me, please.
+OptionalBridging.logSomeValue(nilValue as Any)   // Received an NSNull value.

协议限定类

Objective-C 中被一个或多个协议限定的类会作为协议组合类型导入到 Swift。例如,如下 Objective-C 属性引用一个视图控制器:

objective-c
@property UIViewController<UITableViewDataSource, UITableViewDelegate> * myController;

该属性会以如下形式导入到 Swift:

swift
var myController: UIViewController & UITableViewDataSource & UITableViewDelegate

Objective-C 中的协议限定元类会作为协议元类导入到 Swift。例如,如下 Objective-C 方法会在指定类上执行一个操作:

objective-c
- (void)doSomethingForClass:(Class<NSCoding>)codingClass;

如下代码展示了 Swift 如何导入它:

swift
func doSomething(for codingClass: NSCoding.Type)

轻量泛型

Objective-C 的NSArrayNSSet以及NSDictionary类型的声明在使用轻量泛型参数化后,被导入到 Swift 时会附带容器中元素的类型信息。

例如,思考如下 Objective-C 属性声明:

objective-c
@property NSArray<NSDate *> *dates;
+@property NSCache<NSObject *, id<NSDiscardableContent>> *cachedData;
+@property NSDictionary <NSString *, NSArray<NSLocale *>> *supportedLocales;

导入到 Swift 后将如下所示:

swift
var dates: [Date]
+var cachedData: NSCache<AnyObject, NSDiscardableContent>
+var supportedLocales: [String: [Locale]]

使用了轻量泛型的 Objective-C 类会作为泛型类导入到 Swift。所有 Objective-C 泛型类型参数导入到 Swift 后,都会带有类型约束来要求该类型必须是一个类类型。如果 Objective-C 泛型参数化带有类限定,导入到 Swift 后,它会带有一个类型约束来要求该类必须是指定类的子类。与之类似,如果带有协议限定,导入到 Swift 后,它会带有一个类型约束来要求该类必须符合指定协议。如果未特别指定类型限定,Swift 会将根据泛型类的类型约束来推断泛型参数化。例如,思考如下 Objective-C 类声明和分类声明:

objective-c
@interface List<T: id<NSCopying>> : NSObject
+- (List<T> *)listByAppendingItemsInList:(List<T> *)otherList;
+@end
+
+@interface ListContainer : NSObject
+- (List<NSValue *> *)listOfValues;
+@end
+
+@interface ListContainer (ObjectList)
+- (List *)listOfObjects;
+@end

上述声明将以如下形式导入到 swift:

swift
class List<T: NSCopying> : NSObject {
+    func listByAppendingItemsInList(otherList: List<T>) -> List<T>
+}
+
+class ListContainer : NSObject {
+    func listOfValues() -> List<NSValue>
+}
+
+extension ListContainer {
+    func listOfObjects() -> List<NSCopying>
+}

扩展

Swift 扩展和 Objective-C 分类相似。扩展可以为既有类,结构和枚举扩充功能,即使它们是在 Objective-C 中定义的。通过导入相应的模块,还可以为系统框架中的类型或者自定义类型定义扩展。

例如,可以扩展UIBezierPath类,基于三角形的边长与起点来创建一个简单的三角形路径。

swift
extension UIBezierPath {
+    convenience init(triangleSideLength: CGFloat, origin: CGPoint) {
+        self.init()
+        let squareRoot = CGFloat(sqrt(3.0))
+        let altitude = (squareRoot * triangleSideLength) / 2
+        move(to: origin)
+        addLine(to: CGPoint(x: origin.x + triangleSideLength, y: origin.y))
+        addLine(to: CGPoint(x: origin.x + triangleSideLength / 2, y: origin.y + altitude))
+        close()
+    }
+}

还可以利用扩展来增加属性(包括类型属性和静态属性)。然而,这些属性必须是计算型属性,因为扩展不能为类,结构体,枚举添加存储型属性。

下面这个例子为CGRect结构增加了一个叫area的计算型属性:

swift
extension CGRect {
+    var area: CGFloat {
+        return width * height
+    }
+}
+let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
+let area = rect.area

甚至可以利用扩展为类添加协议一致性而无需子类化。如果协议是在 Swift 中定义的,还可以为结构或是枚举添加协议一致性,即使它们是在 Objective-C 中定义的。

无法通过扩展覆盖类型中既有的方法与属性。

闭包

Objective-C 的块会作为符合其调用约定的 Swift 闭包导入,通过@convention(block)特性表示。例如,下面是一个 Objective-C 的块变量:

objective-c
void (^completionBlock)(NSData *) = ^(NSData *data) {
+    // ...
+}

它在 Swift 中如下所示:

swift
let completionBlock: (Data) -> Void = { data in
+    // ...
+}

Swift 闭包与 Objective-C 块兼容,因此可以把一个 Swift 闭包传递给一个接受块作为参数的 Objective-C 方法。而且因为 Swift 闭包与函数具有相同类型,因此甚至可以直接传递一个 Swift 函数的函数名。

闭包与块有相似的捕获语义,但有个关键的不同:被捕获的变量可以直接修改,而不是一份值拷贝。换言之,Objective-C __block变量的行为是 Swift 变量的默认行为。

在捕获 self 时避免强引用循环

在 Objective-C,如果块捕获了self,一定要慎重考虑内存管理问题。

块会保持对被捕获对象的强引用,包括self。一旦self也持有对块的强引用,例如通过一个拷贝语义的块属性,就将导致强引用循环。可以通过让块捕获self的弱引用来避免此问题:

objective-c
__weak typeof(self) weakSelf = self;
+self.block = ^{
+    __strong typeof(self) strongSelf = weakSelf;
+    [strongSelf doSomething];
+};

和 Objective-C 块类似,Swift 闭包也会保持对被捕获对象的强引用,包括self。为了避免强引用循环,可以在闭包的捕获列表中指定selfunowned

swift
self.closure = { [unowned self] in
+    self.doSomething()
+}

请参阅 The Swift Programming Language 中文版 中的 解决闭包引起的循环强引用 小节获取更多信息。

对象比较

在 Swift,比较两个对象可以使用两种方式。第一种,使用==运算符,比较两个对象内容是否相同。第二种,使用===运算符,判断常量或者变量是否引用同一对象。

Swift 为源自NSObject的类实现了Equatable协议,并提供了==运算符和===运算符的默认实现。==运算符的默认实现会调用isEqual:方法,===运算符的默认实现则会检查指针是否相同。你不应该为 Objective-C 类型重写这两个运算符。

NSObject类为isEqual:方法提供的基本实现仅仅是比较两个指针是否相同。可以根据需要在子类中重写isEqual:方法,基于对象内容进行比较,而不是比较指针。关于如何实现对象比较逻辑的更多信息,请参阅 Object comparison

注意
Swift 会自动为!=!==运算符提供实现,无需再进行重写。

哈希

如果NSDictionary的键类型不带有类限定,Swift 会将其导入为键类型为AnyHashableDictionary。与之类似,如果NSSet中的元素没有类型限定,Swift 会将其导入为元素类型为AnyHashableSet。如果NSDictionaryNSSet对其键或元素的类型做了参数化,那么 Swift 导入它们时则会使用相应的类型作为键或元素的类型。例如,考虑如下 Objective-C 声明:

objective-c
@property NSDictionary *unqualifiedDictionary;
+@property NSDictionary<NSString *, NSDate *> *qualifiedDictionary;
+
+@property NSSet *unqualifiedSet;
+@property NSSet<NSString *> *qualifiedSet;

Swift 会以如下形式导入它们:

swift
var unqualifiedDictionary: [AnyHashable: Any]
+var qualifiedDictionary: [String: Date]
+
+var unqualifiedSet: Set<AnyHashable>
+var qualifiedSet: Set<String>

Swift 在导入 Objective-C 中未指定的类型或id类型时,如果这种类型必须符合Hashable协议,就会将之导入为AnyHashable类型。AnyHashable由任意Hashable类型隐式转换而来,并可以使用as?as!操作符将其转换为更具体的类型。

Swift 类型兼容性

在 Swift 中继承 Objective-C 类时,该 Swift 子类及其成员,即属性、方法、下标和构造器,只要兼容于 Objective-C,就可在 Objective-C 中直接使用。但这不包括一些 Swift 独有特性,如下列所示:

  • 泛型
  • 元组
  • 原始值类型不是Int类型的枚举
  • 结构体
  • 顶级函数
  • 全局变量
  • 类型别名
  • 可变参数
  • 嵌套类型
  • 柯里化函数

Swift API 转换到 Objective-C 时:

  • Swift 可选类型会被标注__nullable
  • Swift 非可选类型会被标注__nonnull
  • Swift 常量存储属性和计算属性会成为 Objective-C 只读属性。
  • Swift 变量存储属性会成为 Objective-C 读写属性。
  • Swift 类型属性会成为 Objective-C 中具有class特性的属性。
  • Swift 类型方法会成为 Objective-C 类方法。
  • Swift 构造器和实例方法会成为 Objective-C 实例方法。
  • Swift 中抛出错误的方法会成为接受NSError **参数的 Objective-C 方法。如果 Swift 方法没有参数,AndReturnError:会被拼接到 Objective-C 方法名上,否则,error:会被拼接在方法名上。如果 Swift 方法没有指定返回类型,那么相应的 Objective-C 方法会拥有 BOOL 类型的返回值。如果 Swift 方法返回非可选值,那么对应的 Objective-C 方法会返回可选值。

例如,思考如下 Swift 声明:

swift
class Jukebox: NSObject {
+    var library: Set<String>
+
+    var nowPlaying: String?
+
+    var isCurrentlyPlaying: Bool {
+        return nowPlaying != nil
+    }
+
+    class var favoritesPlaylist: [String] {
+        // return an array of song names
+    }
+
+    init(songs: String...) {
+        self.library = Set<String>(songs)
+    }
+
+    func playSong(named name: String) throws {
+        // play song or throw an error if unavailable
+    }
+}

上述声明导入到 Objective-C 后如下所示:

objective-c
@interface Jukebox : NSObject
+@property (nonatomic, strong, nonnull) NSSet<NSString *> *library;
+@property (nonatomic, copy, nullable) NSString *nowPlaying;
+@property (nonatomic, readonly, getter=isCurrentlyPlaying) BOOL currentlyPlaying;
+@property (nonatomic, class, readonly, nonnull) NSArray<NSString *> * favoritesPlaylist;
+- (nonnull instancetype)initWithSongs:(NSArray<NSString *> * __nonnull)songs OBJC_DESIGNATED_INITIALIZER;
+- (BOOL)playSong:(NSString * __nonnull)name error:(NSError * __nullable * __null_unspecified)error;
+@end

注意
无法在 Objective-C 中继承一个 Swift 类。

配置 Swift 在 Objective-C 中的接口

在某些情况下,需要更精确地控制如何将 Swift API 暴露给 Objective-C。你可以使用@objc(name)特性来改变类、属性、方法、枚举类型以及枚举用例暴露给 Objective-C 代码的声明。

例如,如果 Swift 类的类名包含 Objective-C 中不支持的字符,就可以为其提供一个在 Objective-C 中的别名。如果要为 Swift 函数提供 Objective-C 别名,使用 Objective-C 选择器语法,并记得在选择器参数片段后添加冒号(:)。

swift
@objc(Color)
+enum Цвет: Int {
+
+    @objc(Red)
+    case Красный
+
+    @objc(Black)
+    case Черный
+}
+
+@objc(Squirrel)
+class Белка: NSObject {
+
+    @objc(color)
+    var цвет: Цвет = .Красный
+
+    @objc(initWithName:)
+    init (имя: String) {
+        // ...
+    }
+
+    @objc(hideNuts:inTree:)
+    func прячьОрехи(количество: Int, вДереве дерево: Дерево) {
+        // ...
+    }
+}

对 Swift 类使用@objc(name)特性时,该类将在 Objective-C 中可用并且没有任何命名空间。因此,这个特性在迁徙被归档的 Objecive-C 类到 Swift 时会非常有用。由于归档文件中存储了被归档对象的类名,因此应该使用@objc(name)特性来指定被归档的 Objective-C 对象的类名,这样归档文件才能通过新的 Swift 类解档。

注意
相反,Swift 还提供了@nonobjc特性,可以让一个 Swift 声明在 Objective-C 中不可用。可以利用它来解决桥接方法循环,以及重载由 Objective-C 中导入的类中的方法。另外,如果一个 Objective-C 方法在 Swift 中被重写后,无法再以 Objective-C 的语言特性呈现,例如将参数变为了 Swift 中的可变参数,那么这个方法必须标记为@nonobjc

需要动态分派

可在 Objective-C 中调用的 Swift API 必须通过动态分派提供。不过,在 Swift 中调用这些 API 时,动态分派的可用性并不妨碍 Swift 编译器选择更高效的分派方法。

你可以使用 @objc 特性和 dynamic 修饰符来要求通过 Objective-C 运行时动态分派对成员的访问操作。一般很少需要这种动态分派,但是,在使用类似键值监听(KVO)这类 API,以及使用 Objective-C 运行时库中的 method_exchangeImplementations 这类需要在运行时动态替换方法实现的函数时,则必须使用动态分派。

使用 dynamic 修饰符标记的声明还必须显式标记 @objc 特性,除非声明所在的上下文为其隐式添加了 @objc 特性。关于 @objc 特性何时会被隐式添加的相关信息,请参阅 The Swift Programming Language 中文版 中的声明特性部分。

选择器

Objective-C 选择器是一种用于引用 Objective-C 方法名的类型。在 Swift,Objective-C 选择器用Selector结构体表示。可以使用#selector表达式创建一个选择器,将方法名传入即可,例如#selector(MyViewController.tappedButton(sender:))。创建 Objective-C 存取方法的选择器时,为了区分,将属性名加上getter:setter:标签,例如#selector(getter: MyViewController.myButton)

swift
import UIKit
+class MyViewController: UIViewController {
+    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
+
+    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
+        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
+        let action = #selector(MyViewController.tappedButton)
+        myButton.addTarget(self, action: action, for: .touchUpInside)
+    }
+
+    func tappedButton(sender: UIButton?) {
+        print("tapped button")
+    }
+
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+    }
+}

注意
Objective-C 方法引用还可以加上圆括号,并使用as运算符来消除重载方法之间的歧义,例如#selector(((UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -> Void))

Objective-C 方法的不安全调用

可以使用perform(_:)方法以及它的变体在兼容 Objective-C 的对象上调用方法。使用选择器调用方法并非内在安全的,因为编译器无法保证结果,甚至无法保证对象能否响应选择器。因此,坚决不提倡使用这些 API,除非代码确实依赖于 Objective-C 运行时提供的动态方法决议。例如,实现一个类似NSResponder这种在接口中使用了目标-行为设计模式的类。绝大多数情况下,将对象转换为AnyObject类型,再使用可选链语法调用方法会更为安全和方便,请参阅 id 兼容性 小节获取更多信息。

swift
let string: NSString = "Hello, Cocoa!"
+let selector = #selector(NSString.lowercased(with:))
+let locale = Locale.current
+if let result = string.perform(selector, with: locale) {
+    print(result.takeUnretainedValue())
+}
+// 打印输出 "hello, cocoa!"

向一个对象发送无法识别的选择器将造成接收者调用doesNotRecognizeSelector(_:)方法,其默认实现是抛出NSInvalidArgumentException异常。

swift
let array: NSArray = ["delta", "alpha", "zulu"]
+// 下面这句代码不会导致编译错误,因为该选择器存在于 NSDictionary 中
+let selector = #selector(NSDictionary.allKeysForObject)
+// 下面这句代码将抛出异常,因为 NSArray 无法响应该选择器
+array.performSelector(selector)

键和键路径

在 Objective-C,键是一个表示某个对象特定属性的字符串。键路径是一个由多个键构成的字符串,键之间用点分隔,表示一条能访问到某个对象特定属性的路径。键和键路径经常用于键值编码(KVC),这是一种通过字符串来访问某个对象的属性的机制。键和键路径也常用于键值监听(KVO),这是一种能让某个对象在另一个对象的特定属性改变时获得通知的机制。

在 Swift,可以用 key-path 表达式创建键路径来访问属性。例如,可以用 \Animal.name 这样的 key-path 表达式来访问 Animal 类中的 name 属性。键路径通过 key-path 表达式创建,其中包含了属性所在类型的类型信息。对一个实例使用键路径所得到的结果就如同直接访问该实例的对应属性一样。key-path 表达式接受属性引用以及链式属性引用,例如 \Animal.name.count

swift
let llama = Animal(name: "Llama")
+let nameAccessor = \Animal.name
+let nameCountAccessor = \Animal.name.count
+
+llama[keyPath: nameAccessor]
+// "Llama"
+llama[keyPath: nameCountAccessor]
+// "5"

在 Swift,还可以用 #keyPath 字符串表达式生成可被编译器检查的键和键路径,并可将之用于 KVC 方法 value(forKey:) 和  value(forKeyPath:),以及 KVO 方法 addObserver(_:forKeyPath:options:context:)#keyPath 字符串表达式接受链式的方法或属性引用。它还支持可选值链式引用,例如 #keyPath(Person.bestFriend.name)。与使用 key-path 表达式这种创建方式不同的是,#keyPath 字符串表达式不会将属性或方法所属类型的类型信息传递给接受键路径的 API。

注意
#keyPath 表达式语法类似 #selector 表达式语法,请参阅 选择器

swift
class Person: NSObject {
+    @objc var name: String
+    @objc var friends: [Person] = []
+    @objc var bestFriend: Person? = nil
+
+    init(name: String) {
+        self.name = name
+    }
+}
+
+let gabrielle = Person(name: "Gabrielle")
+let jim = Person(name: "Jim")
+let yuanyuan = Person(name: "Yuanyuan")
+gabrielle.friends = [jim, yuanyuan]
+gabrielle.bestFriend = yuanyuan
+
+#keyPath(Person.name)
+// "name"
+gabrielle.value(forKey: #keyPath(Person.name))
+// "Gabrielle"
+#keyPath(Person.bestFriend.name)
+// "bestFriend.name"
+gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))
+// "Yuanyuan"
+#keyPath(Person.friends.name)
+// "friends.name"
+gabrielle.value(forKeyPath: #keyPath(Person.friends.name))
+// ["Yuanyuan", "Jim"]

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html b/docs/.vitepress/dist/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html new file mode 100644 index 0000000..73186cb --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.html @@ -0,0 +1,73 @@ + + + + + + 使用 Objective-C 特性编写 Swift 类和协议 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

使用 Objective-C 特性编写 Swift 类和协议

互用性让你在编写 Swift 代码时可以融合 Objective-C 语言特性。在编写 Swift 代码时,不仅可以继承 Objective-C 类,声明和采用 Objective-C 协议,还可以使用 Objective-C 的一些其它功能。这意味着不但可以基于 Objective-C 中耳熟能详的既有特性来编写 Swift 代码,还可以利用 Swift 更为强大的现代化语言特性来改善代码。

继承 Objective-C 类

在 Swift,可以定义一个继承自 Objective-C 类的 Swift 子类。在 Swift 的类名后面加上一个冒号(:),冒号后面跟上 Objective-C 类的类名即可。

swift
import UIKit
+class MySwiftViewController: UIViewController {
+    // 定义类
+}

Swift 子类可以从 Objective-C 父类中继承所有的功能。

如果要覆盖父类中的实现,可以使用 override 修饰符。编译器会根据 Swift 方法名来自动推断被重写的父类方法。也可以使用 @objc(name) 特性来明确指定相对应的 Objective-C 符号。

当 Swift 类引入了许多需要 Objective-C 运行时行为的新方法或属性时,请在该类的声明中使用 @objcMembers 特性。对类使用 @objcMembers 特性会隐式地将 @objc 特性添加到类中所有兼容 Objective-C 的成员。由于使用 @objc 特性会增加应用程序编译后的体积并对性能产生不利影响,因此只有在每个成员都需要使用 @objc 特性时才应在类声明中使用 @objcMembers 特性。

NSCoding 协议

NSCoding协议要求采用协议的类型实现其所要求的构造器init(coder:)以及其所要求的方法encode(with:)。直接采用NSCoding协议的类必须实现这个方法。对于采用NSCoding协议的类的子类,如果有一个或者多个自定义的构造器或者有不具有默认初始值的属性,那么也必须实现这个方法。Xcode 提供了下面这个fix-it来提供一个占位实现:

swift
required init(coder aDecoder: NSCoder) {
+    fatalError("init(coder:) has not been implemented")
+}

对于那些从 Storyboards 里加载的对象,或者用NSUserDefaultsNSKeyedArchiver归档到硬盘的对象,则必须提供该构造器的完整实现。当然,如果一个类型不会以此种方式实例化时,就不需要提供该构造器的完整实现。

采用协议

Objective-C 协议会被导入为 Swift 协议。所有协议都写在一个用逗号分隔的列表中,跟在父类类名后面(如果该类有父类的话)。

swift
class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
+    // 定义类
+}

声明符合单个协议的类型时,直接使用协议名作为其类型,类似于 Objective-C 中id<SomeProtocol>这种形式。声明符合多个协议的类型时,使用SomeProtocol & AnotherProtocol这种协议组合的形式,类似于 Objective-C 中id<SomeProtocol, AnotherProtocol>这种形式。

swift
var textFieldDelegate: UITextFieldDelegate
+var tableViewController: UITableViewDataSource & UITableViewDelegate

注意
在 Swift,类和协议的命名空间是统一的,因此 Objective-C 的NSObject协议会被重映射为 Swift 的NSObjectProtocol协议。

编写构造器和析构器

Swift 编译器能确保构造器不会遗留任何未初始化的属性,从而增加代码的安全性和可预测性。另外,与 Objective-C 不同,Swift 不提供单独的内存分配方法。你会始终使用原生的 Swift 构造器,即使是使用 Objective-C 类,Swift 会将 Objective-C 构造方法转换为 Swift 构造器。请参阅 The Swift Programming Language 中文版 中的 构造器 章节了解关于如何实现构造器的更多信息。

如果希望在对象释放前进行额外的清理工作,可以实现一个析构器来代替dealloc方法。在对象被释放前,Swift 会自动调用析构器。当 Swift 调用完子类的析构器后,会自动调用父类的析构器。使用 Objective-C 类或者继承自 Objective-C 类的 Swift 类时,Swift 也会自动调用该类父类中的dealloc方法。请参阅 The Swift Programming Language 中文版 中的 析构器 章节了解关于如何实现析构器的更多信息。

兼容使用 Swift 类名的 Objective-C API

Swift 类的命名空间基于其所在的模块,即使是使用来自 Objective-C 的代码。在 Objective-C 中所有的类都是全局命名空间的一部分,名字不能重复。而 Swift 类可以基于其所在模块来消除歧义。例如,MyFramework框架中的DataManager类在 Swift 中的全限定名是MyFramework.DataManager。一个 Swift 应用的target就是一个模块,因此,在一个叫MyGreatApp的应用里,一个叫做Observer的 Swift 类的全限定名是MyGreatApp.Observer

Swift 类在 Objective-C 代码中使用时,为了保持命名空间,Swift 类会将其全限定名暴露给 Objective-C 运行时。因此,使用那些用到 Swift 类名字符串的 API 时,必须使用类的全限定名。例如,你创建了一个基于文档的 Mac 应用,需要在应用的Info.plist里提供NSDocument子类的类名。在 Swift 中,必须使用NSDocument子类的全限定名,即应用名或者框架名加上子类名。

下面的例子中,NSClassFromString(_:)函数用于从一个字符串表示的类名获取该类的引用。为了获取 Swift 类,需要使用全限定名,也就是需要加上应用的名字。

swift
let myPersonClass: AnyClass= NSClassFromString("MyGreatApp.Person")

与 Interface Builder 结合

Swift 编译器包含一些特性,能让 Swift 类使用 Interface Builder 的一些特色功能。和 Objective-C 一样,在 Swift 也可使用 outlet,action 以及实时渲染。

使用 Outlet 和 Action

使用 Outlets 和 Actions 可以连接源代码和 Interface Builder 中的 UI 对象,只需在属性或方法声明前标记@IBOutlet@IBAction特性。声明一个 outlet 集合同样是用@IBOutlet特性,只不过会为该类型指定一个数组。

在 Swift 中声明一个 outlet 时,应该将类型声明为隐式解包可选类型。通过这种方式,Swift 编译器会自动为它分配空值nil,就不需要在构造器中为其分配初始值了。在运行时,构造过程完成后,Interface Builder 会连接各个 outlet。如果从故事版或者xib文件实例化对象,则可以假定这些 outlet 已经连接完毕。

例如,下面的 Swift 代码声明了一个拥有 outlet,outlet 集合和 action 的类:

swift
class MyViewController: UIViewController {
+    @IBOutlet weak var button: UIButton!
+    @IBOutlet var textFields: [UITextField]!
+    @IBAction func buttonTapped(sender: AnyObject) {
+        print("button tapped!")
+    }
+}

实时渲染

可以使用@IBDesignable@IBInspectable特性开启实时渲染,在 Interface Builder 中对自定义视图进行交互式设计。继承UIView或者NSView来自定义一个视图时,可以在类声明前标记@IBDesignable特性。在 Interface Builder 里添加自定义的视图后(在 Identity Inspector 面板的 Class 输入框中进行设置),Interface Builder 将在画布上实时渲染自定义视图。

还可以将@IBInspectable特性添加到类型兼容用户定义运行时属性(可以在 Identity Inspector 面板的 User Defined Runtime Attributes 中查看)的属性前。将自定义的视图添加到 Interface Builder 后,就可以在 Attributes Inspector 面板中编辑这些属性。

swift
@IBDesignable
+class MyCustomView: UIView {
+    @IBInspectable var textColor: UIColor
+    @IBInspectable var iconHeight: CGFloat
+    // ...
+}

指定属性特性

在 Objective-C,属性通常会有一系列用于指定该属性的一些附加信息的属性特性。在 Swift,将通过不同的方式指明这些属性特性。

强引用和弱引用

在 Swift,属性默认都是强引用,可以使用weak关键字指明某个属性持有其所指向对象的弱引用。该关键字仅能修饰可选的类类型。请参阅 The Swift Programming Language 中文版 中的 类和结构 章节了解更多信息。

读写和只读

在 Swift,没有readwritereadonly特性。声明一个存储型属性时,使用let使其只读;使用var使其可读写。声明一个计算型属性时,只为其提供一个读取方法使其只读;同时提供读取方法和写入方法使其可读写。请参阅 The Swift Programming Language 中文版 中的 属性 章节了解更多信息。

拷贝语义

在 Swift,Objective-C 的copy属性特性被转化为@NSCopying。这种类型的属性必须符合NSCopying协议。请参阅 The Swift Programming Language 中文版 中的 类和结构 章节了解更多信息。

实现 Core Data 的 NSManagedObject 子类

Core Data 提供了底层存储以及NSManagedObject子类的属性实现,还提供了在对多关系中添加和移除对象的实例方法实现。可以使用@NSManaged特性告知 Swift 编译器,一个声明的底层存储和实现部分将在运行时由 Core Data 提供。

NSManagedObject子类中,为每一个和 Core Data 实体模型文件中相对应的属性或者方法声明标记@NSManaged特性。例如,思考下面这个叫做Person的 Core Data 实体,它有个叫做nameString类型的属性,以及一个叫做friends的对多关系。

相对应的NSManagedObject子类Person中的代码如下:

swift
import CoreData
+class Person: NSManagedObject {
+    @NSManaged var name: String
+    @NSManaged var friends: NSSet
+        
+    @NSManaged func addFriendsObject(friend: Person)
+    @NSManaged func removeFriendsObject(friend: Person)
+    @NSManaged func addFriends(friends: NSSet)
+    @NSManaged func removeFriends(friends: NSSet)
+}

namefriends属性都标记了@NSManaged特性,以此表明 Core Data 会在运行时提供其实现和存储。由于friends是个对多关系,因此 Core Data 还提供了一些相关的存取方法。

为了在 Swift 中配置一个NSManagedObject的子类供 Core Data 模型实体使用,在 Xcode 中打开 Data Model Inspector,在 Class 输入框中输入类名,并在 Module 输入框的下拉列表中选择Current Product Module

声明协议

在 Swift 中可以定义能让 Objective-C 类采用的协议,在协议声明前添加@objc特性即可。

swift
import UIKit
+@objc protocol MyCustomProtocol {
+    var people: [Person] { get }
+
+    func tableView(_ tableView: UITableView, configure cell: UITableViewCell, forPerson person: Person)
+
+    @objc optional func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forPerson person: Person)
+}

为了符合协议,Objective-C 类必须实现协议中声明的所有构造器,属性,下标,以及方法。可选协议要求必须标记@objc特性以及optional修饰符。

Objective-C 类可以像采用 Objective-C 协议一样采用 Swift 协议,实现所有协议要求即可。

objective-c
@interface MyCustomController: UIViewController <MyCustomProtocol>
+@property (nonatomic, strong) NSArray<Person *> *people;
+@end
+
+@implementation MyCustomController
+@synthesize people;
+
+- (void)tableView:(UITableView *)tableView
+		 configure:(UITableViewCell *)cell
+		 forPerson:(Person *)person
+{
+    // ...
+}
+@end

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html b/docs/.vitepress/dist/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html new file mode 100644 index 0000000..a5643ad --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.html @@ -0,0 +1,67 @@ + + + + + + 使用 Cocoa 框架 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

使用 Cocoa 框架

为了便于与 Objective-C 进行交互,Swift 提供了高效便捷的方式来使用 Cocoa 框架。

Swift 会自动将一些 Objective-C 类型转换为 Swift 类型,也会将一些 Swift 类型转换为 Objective-C 类型。可以在 Objective-C 和 Swift 间相互转换的数据类型被称为桥接类型。例如,在 Swift,可以将一个String类型的值传递给一个接收NSString对象的 Objective-C 方法。除此之外,很多 Cocoa 框架,包括 Foundation,AppKit,以及 UIKit,都改善了它们的 API,从而在 Swift 中使用起来更加自然。例如,NSCoder的方法decodeObjectOfClass(_:forKey:)使用 Swift 泛型来提供强类型的方法签名。

Foundation

Foundation 框架为应用和框架提供了基层功能,包括数据存储,文本处理,日期时间,排序过滤,持久化和网络等。

被桥接的类型

Swift 中的 Foundation 提供了如下桥接值类型用于替代如下 Objective-C 引用类型:

Objective-C 引用类型Swift 值类型
NSAffineTransformAffineTransform
NSArrayArray
NSCalendarCalendar
NSCharacterSetCharacterSet
NSDataData
NSDateComponentsDateComponents
NSDateIntervalDateInterval
NSDateDate
NSDecimalNumberDecimal
NSDictionaryDictionary
NSIndexPathIndexPath
NSIndexSetIndexSet
NSLocaleLocale
NSMeasurementMeasurement
NSNotificationNotification
NSNumberBool, Double, Float, Int, UInt
NSPersonNameComponentsPersonNameComponents
NSSetSet
NSStringString
NSTimeZoneTimeZone
NSURLComponentsURLComponents
NSURLQueryItemURLQueryItem
NSURLURL
NSURLComponentsURLComponents
NSURLQueryItemURLQueryItem
NSURLRequestURLRequest
NSUUIDUUID

这些值类型的功能与其对应的引用类型相同。包含不可变和可变子类的类簇被统一桥接为单个值类型。Swift 代码使用varlet来控制可变性,因此它们不再需要两个类了。原先的引用类型依然可以通过加上NS前缀来访问。

可以使用 Objective-C 桥接引用类型的地方就可以使用 Swift 桥接值类型,从而可以在 Swift 代码中以更加自然的方式使用这些原有的功能。基于这个原因,你应该尽量避免在 Swift 代码中使用 Objective-C 桥接引用类型。事实上,Swift 代码导入 Objective-C API 时,导入器会将引用类型替换为相对应的值类型。与之类似,Objective-C 代码导入 Swift API 时,导入器也会将值类型替换为相对应的引用类型。

如果你需要使用原本的 Foundation 对象,你可以使用as操作符在这些桥接类型间进行转换。

被重命名的类型

Swift 中的 Foundation 重名了一些类,协议,枚举以及常量。

在导入 Foundation 类时,Swift 丢弃了类名的NS前缀,但有如下例外情况:

  • Objective-C 和 Objective-C 运行时中的一些特定类,例如NSObjectNSAutoreleasePoolNSExceptionNSProxy
  • 平台特定类,例如NSBackgroundActivityNSUserNotificationNSXPCConnection
  • 拥有对应的桥接值类型的一些类,例如NSStringNSDictionaryNSURL
  • 目前尚无对应的桥接值类型,但是未来会有的一些类,例如NSAttributedStringNSRegularExpressionNSPredicate

Foundation 中的类经常会声明一些枚举和常量类型。导入这些类型时,Swift 会将它们移到相关类型的内部作为嵌套类型。例如,NSJSONReadingOptions的选项集会被导入为JSONSerialization.ReadingOptions

字符串

字符串可以在String类型和NSString类型之间桥接。你可以使用as运算符将String值转换为NSString对象。你也可以通过提供类型标注的方式利用字符串字面量创建NSString对象。

swift
import Foundation
+let string: String = "abc"
+let bridgedString: NSString = string as NSString
+
+let stringLiteral: NSString = "123"
+if let integerValue = Int(stringLiteral as String) {
+    print("\(stringLiteral) is the integer \(integerValue)")
+}
+// 打印 "123 is the integer 123"

注意
Swift 的String类型由独立编码的 Unicode 字符组成,并提供了在各种 Unicode 表现形式下访问这些字符的支持。NSString类以 UTF-16 码元序列的形式编码兼容 Unicode 的文本字符串。表示字符串长度,字符索引,区间的这些依据 16 位平台字节序值的NSString方法,均有相对应的 Swift 方法,这些方法使用String.IndexRange<String.Index>值而不是IntNSRange值。

数值

Swift 会在 NSNumber 类和 Swift 算术类型之间桥接,包括 IntDoubleBool

你可以使用 as 运算符转换 Swift 数值来创建 NSNumber 对象。由于 NSNumber 可以包含多种不同类型,将其转换为 Swift 数值时必须使用 as? 运算符。例如,将表示数字500的 NSNumber 值转换为 Swift 类型 Int8 将会失败并返回 nil,因为 Int8 值可表示的最大值是127。

你还可以通过显式提供类型标注,使用浮点数、整数或布尔字面量创建 NSNumber 对象。

swift
import Foundation
+let number = 42
+let bridgedNumber: NSNumber = number as NSNumber
+
+let integerLiteral: NSNumber = 5
+let floatLiteral: NSNumber = 3.14159
+let booleanLiteral: NSNumber = true

注意
Objective-C 中具有平台适应性的整数类型,例如 NSUIntegerNSInteger,会被桥接为 Int

数组

Swift 会在Array类型和NSArray类之间桥接。使用轻量泛型的NSArray对象被桥接时,其元素类型也会被桥接过去。如果NSArray对象没有使用轻量泛型,那么它会被桥接为[Any]类型的 Swift 数组。

例如,思考以下 Objective-C 声明:

objective-c
@property NSArray *objects;
+@property NSArray<NSDate *> *dates;
+- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
+- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;

Swift 以如下所示导入它们:

swift
var objects: [Any]
+var dates: [Date]
+func datesBeforeDate(date: Date) -> [Date]
+func addDatesParsedFromTimestamps(timestamps: [String])

还可以直接利用 Swift 数组字面量创建NSArray对象,这同样遵循上面提到的桥接规则。将常量或变量声明为NSArray类型并为其赋值数组字面量时,Swift 将会创建NSArray对象,而不是 Swift 数组。

swift
let schoolSupplies: NSArray = ["Pencil", "Eraser", "Notebkko"]
+// schoolSupplies 是一个包含三个元素的 NSArray 对象

集合

Swift 也会在Set类型和NSSet类之间桥接。使用轻量泛型的NSSet对象会被桥接为Set<ObjectType>类型的 Swift 集合。如果NSSet对象没有使用轻量泛型,那么它会被桥接为Set<AnyHashable>类型的 Swift 集合。

例如,思考以下 Objective-C 声明:

objective-c
@property NSSet *objects;
+@property NSSet<NSString *> *words;
+- (NSSet<NSString *> *)wordsMatchingPredicate:(NSPredicate *)predicate;
+- (void)removeWords:(NSSet<NSString *> *)words;

Swift 以如下所示导入它们:

swift
var objects: Set<AnyHashable>
+var words: Set<String>
+func wordsMatchingPredicate(predicate: NSPredicate) -> Set<String>
+func removeWords(words: Set<String>)

还可以直接利用 Swift 数组字面量创建NSSet对象,这同样遵循上面提到的桥接规则。将常量或者变量声明为NSSet类型,并为其赋值数组字面量时,Swift 将会创建NSSet对象,而不是 Swift 集合。

swift
let amenities: NSSet = ["Sauna", "Steam Room", "Jacuzzi"]
+// amenities 是一个包含三个元素的 NSSet 对象

字典

Swift 同样会在Dictionary类型和NSDictionary类之间桥接。使用轻量泛型的NSDictionary对象会被桥接为[Key: Value]类型的 Swift 字典。如果NSDictionary对象没有使用轻量泛型,那么它会被桥接为[AnyHashable: Any]类型的 Swift 字典。

例如,思考以下 Objective-C 声明:

objective-c
@property NSDictionary *keyedObjects;
+@property NSDictionary<NSURL *, NSData *> *cachedData;
+- (NSDictionary<NSURL *, NSNumber *> *)fileSizesForURLsWithSuffix:(NSString *)suffix;
+- (void)setCacheExpirations:(NSDictionary<NSURL *, NSDate *> *)expirations;

Swift 以如下所示导入它们:

swift
var keyedObjects: [AnyHashable: Any]
+var cachedData: [URL: Data]
+func fileSizesForURLsWithSuffix(suffix: String) -> [URL: NSNumber]
+func setCacheExpirations(expirations: [URL: NSDate])

还可以直接利用 Swift 字典字面量创建NSDictionary对象,这同样遵循上面提到的桥接规则。将常量或者变量声明为NSDictionary类型,并为其赋值字典字面量时,Swift 将会创建NSDictionary对象,而不是 Swift 字典。

swift
let medalRankings: NSDictionary = ["Gold": "1st Place", "Silver": "2nd Place", "Bronze": "3rd Place"]
+// medalRankings 是一个包含三个键值对的 NSDictionary 对象

Core Foundation

Core Foundation 类型会被导入为 Swift 类。无论是否提供了内存管理标注,Swift 都会自动管理 Core Foundation 对象的内存,包括你自己实例化的 Core Foundation 对象。在 Swift,可以将每一对可以桥接的 Fundation 和 Core Foundation 类型互换使用。如果先将 Core Foundation 类型桥接为 Foundation 类型,就可以进一步桥接为 Swift 标准库类型。

重映射类型

Swift 导入 Core Foundation 类型时,会将这些类型的名字重映射,从类型名字的末端移除 Ref,所有的 Swift 类都是引用类型,因此该后缀是多余的。

Core Foundation 的CFTypeRef类型会重映射为Anyobject类型。以前使用CFTypeRef的地方,现在该换成AnyObject了。

内存受管理的对象

对于从带内存管理标注的 API 返回的 Core Foundation 对象,Swift 会自动对其进行内存管理,你不需要再调用CFRetainCFRelease,或者CFAutorelease函数。

如果自定义的 C 函数或 Objective-C 方法返回 Core Foundation 对象,需要用CF_RETURNS_RETAINED或者CF_RETURNS_NOT_RETAINED宏标注这些函数或方法,从而帮助编译器自动插入内存管理函数调用。还可以使用CF_IMPLICIT_BRIDGING_ENABLEDCF_IMPLICIT_BRIDGING_DISABLED宏围住那些遵循 Core Foundation 内存管理命名规定的 C 函数声明,从而能够根据命名推导出内存管理策略。

如果只调用那些带有内存管理标注并且不会间接返回 Core Foundation 对象的 API,那么可以略过本节的剩余部分了。否则,需要进一步学习有关 Core Foundation 非托管对象的知识。

非托管对象

对于那些没有内存管理标注的 API,编译器无法自动对返回的 Core Foundation 对象进行内存管理。Swift 将这些返回的 Core Foundation 对象包装在一个Unmanaged<Instance>结构中。所有被间接返回的 Core Foundation 对象也都是非托管对象。例如,这有个不带内存管理标注的 C 函数:

objective-c
CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)

Swift 以如下所示导入它们:

swift
func StringByAddingTwoStrings(_: CFString!, _: CFString!) -> Unmanaged<CFString>! {
+    // ...
+}

从没有内存管理标注的 API 接收到非托管对象后,在使用它之前,必须将它转换为能够接受内存管理的对象。通过这种方式,Swift 就可以为你对其进行内存管理。Unmanaged<Instance>结构提供了两个方法,用于将一个非托管对象转换为一个可接受内存管理的对象,即takeUnretainedValue()方法和takeRetainedValue()方法。这两个方法均会返回解包后的原始对象,可以根据 API 返回的是非保留对象还是被保留对象来选择对应的方法。

例如,假设上面的 C 函数不会保留CFString对象。在使用这个对象前,应该使用takeUnretainedValue()函数。

swift
let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
+// memoryManagedResult 是一个接受内存管理的 CFString

当然,也可以对一个非托管对象使用retain()release()autorelease()方法,但是这种做法并不推荐。

想要了解更多信息,请参阅 Memory Management Programming Guide for Core Foundation 中的 Core Foundation Object Lifecycle Management 小节。

统一日志

统一日志系统提供了一个 API 来捕获系统各个层级传递的消息,它是 Foundation 框架中NSLog函数的替代者。统一日志只在 iOS 10.0macOS 10.12tvOS 10.0watchOS 3.0,以及更高的系统平台上可用。

在 Swift,你可以通过顶级函数os_log(_:dso:log:type:_:)来使用统一日志系统,该函数声明在os模块的子模块log中。

swift
import os.log
+
+os_log("This is a log message.")

你可以通过使用NSStringprintf格式化字符串连同单个或多个尾参数来格式化日志信息。

swift
let fileSize = 1234567890
+os_log("Finished downloading file. Size: %{iec-bytes}d", fileSize)

你还可以指定一个日志系统中定义的日志级别,例如InfoDebugError,从而根据日志事件的重要性来控制日志信息如何被处理。例如,某条信息可能很有帮助,但是该信息并不是排查错误所必需的,那么这条信息就应该记录在信息级别。

swift
os_log("This is additional info that may be helpful for troubleshooting.", type: .info)

为了将某条信息记录到指定子系统,你可以创建一个新的OSLog对象,指定子系统和类别,并将其作为参数传入os_log函数。

swift
et customLog = OSLog("com.your_company.your_subsystem_name.plist", "your_category_name")
+os_log("This is info that may be helpful during development or debugging.", log: customLog, type: .debug)

想要了解更多关于统一日志的信息,请参阅 Logging

Cocoa 结构体

在 Swift,Coach 和 Foundation 中的一些内建结构体可以和NSValue桥接:

  • CATransform3D
  • CLLocationCoordinate2D
  • CGAffineTransform
  • CGPoint
  • CGRect
  • CGSize
  • CGVector
  • CMTimeMapping
  • CMTimeRange
  • CMTime
  • MKCoordinateSpan
  • NSRange
  • SCNMatrix4
  • SCNVector3
  • SCNVector4
  • UIEdgeInsets
  • UIOffset

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html b/docs/.vitepress/dist/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html new file mode 100644 index 0000000..3c78d48 --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.html @@ -0,0 +1,245 @@ + + + + + + 采用 Cocoa 设计模式 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

采用 Cocoa 设计模式

使用 Cocoa 既有的设计模式,能帮助开发者开发出设计巧妙、扩展性强的应用程序。这些模式很多都依赖于在 Objective-C 中定义的类。由于 Swift 与 Objective-C 的互用性,你依然可以在 Swift 中使用这些设计模式。在许多情况下,你甚至可以使用 Swift 的语言特性扩展或简化这些 Cocoa 设计模式,使这些设计模式更加强大易用。

代理

在 Swift 和 Objective-C,代理通常表现为一个定义交互方法的协议和符合协议的代理属性。就像在 Objective-C,在向代理发送可能无法响应的消息之前,应询问代理能否响应消息。在 Swift,可以使用可选链语法在一个可能为nil的对象上调用可选的代理方法,并使用if-let语法解包可能存在的返回值。下面的代码阐明了这个过程:

  1. 检查myDelegate不为nil
  2. 检查myDelegate是否实现了window:willUseFullScreenContentSize:方法。
  3. 如果步骤1和步骤2的检查顺利通过,那么调用该方法,将返回值赋值给名为fullScreenSize的常量。
  4. 在控制台打印方法的返回值。
swift
class MyDelegate: NSObject, NSWindowDelegate {
+    func window(_ window: NSWindow, willUseFullScreenContentSize proposedSize: NSSize) -> NSSize {
+        return proposedSize
+    }
+}
+myWindow.delegate = MyDelegate()
+if let fullScreenSize = myWindow.delegate?.window(myWindow, willUseFullScreenContentSize: mySize) {
+    print(NSStringFromSize(fullScreenSize))
+}

惰性初始化

惰性属性的值只会在被初次访问时才被初始化。如果属性的初始化过程十分复杂或者代价昂贵,或者属性的初始值无法在实例的构造过程完成前确定时,那么就可以使用惰性属性。

在 Objective-C,一个属性可能会覆写其自动合成的读取方法,只在实例变量为nil时才初始化实例变量:

objective-c
@property NSXMLDocument *XML;
+
+- (NSXMLDocument *)XML {
+    if (_XML == nil) {
+        _XML = [[NSXMLDocument alloc] initWithContentsOfURL:[[Bundle mainBundle] URLForResource:@"/path/to/resource" withExtension:@"xml"] options:0 error:nil];
+    }
+
+    return _XML;
+}

在 Swift,可以使用lazy修饰符声明一个存储属性,这将使计算初始值的表达式只在属性被初次访问时才进行求值:

swift
lazy var XML: XMLDocument = try! XMLDocument(contentsOf: Bundle.main.url(forResource: "document", withExtension: "xml")!, options: 0)

由于惰性属性只在被初次访问时才进行初始化,此时实例本身已被完全初始化,因此在初始化表达式中可以使用self

swift
var pattern: String
+lazy var regex: NSRegularExpression = try! NSRegularExpression(pattern: self.pattern, options: [])

如果还需在初始化的基础上进行额外的设置,可以通过返回属性初始值的自求值闭包给属性赋值:

swift
lazy var currencyFormatter: NumberFormatter = {
+    let formatter = NumberFormatter()
+    formatter.numberStyle = .currency
+    formatter.currencySymbol = "¤"
+    return formatter
+}()

注意
如果一个惰性属性还未被初始化就被多个线程同时访问,那么此时无法保证此惰性属性只被初始化一次。

请参阅 The Swift Programming Language 中文版 中的 延迟存储属性 小节。

错误处理

在 Cocoa 中,会产生错误的方法将 NSError 指针参数作为最后一个参数,当产生错误时,该参数会被 NSError 对象填充。Swift 会自动将 Objective-C 中会产生错误的方法转换为根据 Swift 原生错误处理机制抛出错误的方法。

注意
某些接受错误的方法,例如委托方法,或者接受一个带有 NSError 参数的块作为参数的方法,不会被 Swift 导入为抛出方法。

例如,请考虑如下来自于 NSFileManager 的 Objective-C 方法:

objective-c
- (BOOL)removeItemAtURL:(NSURL *)URL
+                  error:(NSError **)error;

在 Swift,它会被这样导入:

swift
func removeItem(at: URL) throws

注意 removeItem(at:) 方法被 Swift 导入时,返回值类型为 Void,没有 error 参数,并且还有一个 throws 声明。

如果 Objective-C 方法的最后一个非块类型的参数是 NSError ** 类型,Swift 会将之替换为 throws 关键字,以表明该方法可以抛出一个错误。如果 Objective-C 方法的错误参数也是它的第一个参数,Swift 会尝试删除选择器的第一部分中的 “WithError” 或 “AndReturnError” 后缀(如果存在)来进一步简化方法名。如果简化后的方法名会和其他方法名冲突,则不会对方法名进行简化。

如果产生错误的 Objective-C 方法返回一个用来表示方法调用成功或失败的 BOOL 值,Swift 会把返回值转换为 Void。同样,如果产生错误的 Objective-C 方法返回一个nil 值来表明方法调用失败,Swift 会把返回值转换为非可选类型。

否则,如果不能推断任何约定,则该方法保持不变。

注意
在一个产生错误的 Objective-C 方法声明上使用 NS_SWIFT_NOTHROW 宏可以防止该方法被 Swift 作为抛出方法导入。

捕获和处理错误

在 Objective-C,错误处理是可选的,这意味着除非提供了一个错误指针,否则方法产生的错误会被忽略。在 Swift,调用一个会抛出错误的方法时必须明确进行错误处理。

以下示例演示了在 Objective-C 中调用方法时如何处理错误:

objective-c
NSFileManager *fileManager = [NSFileManager defaultManager];
+NSURL *fromURL = [NSURL fileURLWithPath:@"/path/to/old"];
+NSURL *toURL = [NSURL fileURLWithPath:@"/path/to/new"];
+NSError *error = nil;
+BOOL success = [fileManager moveItemAtURL:fromURL toURL:toURL error:&error];
+if (!success) {
+    NSLog(@"Error: %@", error.domain);
+}

Swift 中等效的代码如下所示:

swift
let fileManager = FileManager.default
+let fromURL = URL(fileURLWithPath: "/path/to/old")
+let toURL = URL(fileURLWithPath: "/path/to/new")
+do {
+    try fileManager.moveItem(at: fromURL, to: toURL)
+} catch let error as NSError {
+    print("Error: \(error.domain)")
+}

此外,你可以使用 catch 子句来匹配特定的错误代码以便区分可能的失败情况:

swift
do {
+    try fileManager.moveItem(at: fromURL, to: toURL)
+} catch CocoaError.fileNoSuchFile {
+    print("Error: no such file exists")
+} catch CocoaError.fileReadUnsupportedScheme {
+    print("Error: unsupported scheme (should be 'file://')")
+}

将错误转换为可选值

在 Objective-C 中,当你只关心是否有错误,而不是发生什么特定错误时,你可以传递 NULL 作为错误参数。在 Swift,你可以使用 try? 关键字将抛出表达式转换为返回可选值的表达式,然后检查返回值是否为 nil

例如,NSFileManager 的实例方法 URLForDirectory(_:inDomain:appropriateForURL:create:) 会返回指定搜索路径和域中的 URL,或者如果适当的 URL 不存在且不能创建,则会产生错误。在 Objective-C 中,此方法成功或是失败可以通过是否返回 URL 对象来判断。

objective-c
NSFileManager *fileManager = [NSFileManager defaultManager];
+     
+NSURL *tmpURL = [fileManager URLForDirectory:NSCachesDirectory 
+                                    inDomain:NSUserDomainMask 
+                           appropriateForURL:nil 
+                                      create:YES 
+                                       error:NULL];
+if (tmpURL != nil) {
+    // ...
+}

在 Swfit 中你可以像下面这样做:

swift
let fileManager = FileManager.default
+if let tmpURL = try? fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) {
+    // ...
+}

抛出错误

如果在一个 Objective-C 方法中发生错误,则使用错误对象来填充该方法的错误指针参数:

objective-c
// 发生一个错误
+if (errorPtr) {
+   *errorPtr = [NSError errorWithDomain:NSURLErrorDomain
+                                   code:NSURLErrorCannotOpenFile
+                               userInfo:nil];
+}

如果在一个 Swift 方法中发生错误,则错误会被抛出,并且自动传播给调用者:

swift
// 发生一个错误
+throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)

如果 Objective-C 代码调用会抛出错误的 Swift 方法,则该错误会自动填充到桥接的 Objective-C 方法的错误指针参数。

例如,考虑 NSDocument 中的 read(from:ofType:) 方法。在 Objective-C 中,此方法的最后一个参数是 NSError ** 类型。在 Swift 的 NSDocument 子类中重写此方法时,该方法会以抛出错误的方式替代错误指针参数。

swift
class SerializedDocument: NSDocument {
+    static let ErrorDomain = "com.example.error.serialized-document"
+
+    var representedObject: [String: Any] = [:]
+
+    override func read(from fileWrapper: FileWrapper, ofType typeName: String) throws {
+        guard let data = fileWrapper.regularFileContents else {
+            throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)
+        }
+
+        if case let JSON as [String: Any] = try JSONSerialization.jsonObject(with: data, options: []) {
+            self.representedObject = JSON
+        } else {
+            throw NSError(domain: SerializedDocument.ErrorDomain, code: -1, userInfo: nil)
+        }
+    }
+}

如果该方法无法使用文档的常规文件内容来创建对象,就会抛出一个 NSError 对象。如果该方法在 Swift 中调用,则错误会传播到它的调用域。如果该方法在 Objective-C 中调用,则错误会填充错误指针参数。

处理异常

在 Objective-C 中,异常与错误不同。Objective-C 异常处理使用 @try@catch@throw 语法来标明不可恢复的程序错误。这与司空见惯的 Cocoa 错误模式截然不同,后者使用一个尾随的 NSError 参数来标明你在开发过程中设计的可恢复错误。

在 Swift 中,你可以从使用 Cocoa 错误模式传递的错误中恢复,如前文错误处理中所述。然而,没有可靠的方法可以从 Swift 中的 Objective-C 异常中恢复。要处理 Objective-C 异常,则需编写 Objective-C 代码,以便在异常到达任何 Swift 代码之前捕获异常。

关于 Objective-C 异常的更多信息,请参阅 Exception Programming Topics

捕获和处理自定义错误

Objective-C 框架可以使用自定义错误域和枚举来组织相关的错误类别。

下面的例子展示了使用 Objective-C 中的 NS_ERROR_ENUM 宏定义的自定义错误类型:

objective-c
extern NSErrorDomain const MyErrorDomain;
+typedef NS_ERROR_ENUM(MyErrorDomain, MyError) {
+    specificError1 = 0,
+    specificError2 = 1
+};

如下示例展示了如何在 Swift 中使用该自定义错误类型生成错误:

swift
func customThrow() throws {
+    throw NSError(
+        domain: MyErrorDomain,
+        code: MyError.specificError2.rawValue,
+        userInfo: [
+            NSLocalizedDescriptionKey: "A customized error from MyErrorDomain."
+        ]
+    )
+}
+
+do {
+    try customThrow()
+} catch MyError.specificError1 {
+    print("Caught specific error #1")
+} catch let error as MyError where error.code == .specificError2 {
+    print("Caught specific error #2, ", error.localizedDescription)
+    // Prints "Caught specific error #2. A customized error from MyErrorDomain."
+} let error {
+    fatalError("Some other error: \(error)")
+}

键值观察

键值观察是一种能让某个对象在其他对象指定属性变化时得到通知的机制。只要 Swift 类继承自 NSObject 类,就可以在 Swift 中通过如下两步实现键值观察。

  1. 为想要观察的属性添加 dynamic 修改符和 @objc 属性。关于 dynamic 修饰符的更多信息,请参阅强制动态派发小节。

    swift
    class MyObjectToObserve: NSObject {
    +    @objc dynamic var myDate = NSDate()
    +    func updateDate() {
    +        myDate = NSDate()
    +    }
    +}
  2. 为键路径创建一个对应的观察者并调用 observe(_:options:changeHandler) 方法。关于键路径的更多信息,请参阅键和键路径小节。

    swift
    class MyObjectToObserve: NSObject {
    +    @objc dynamic var myDate = NSDate()
    +    func updateDate() {
    +        myDate = NSDate()
    +    }
    +}
    +
    +class MyObserver: NSObject {
    +    @objc var objectToObserve: MyObjectToObserve
    +    var observation: NSKeyValueObservation?
    +
    +    init(object: MyObjectToObserve) {
    +        objectToObserve = object
    +        super.init()
    +
    +        observation = observe(\.objectToObserve.myDate) { object, change in
    +            print("Observed a change to \(object.objectToObserve).myDate, updated to: \(object.objectToObserve.myDate)")
    +        }
    +    }
    +}
    +
    +let observed = MyObjectToObserve()
    +let observer = MyObserver(object: observed)
    +
    +observed.updateDate()

目标-动作

目标-动作是一种常见的 Cocoa 设计模式,可以在特定事件发生时,让某个对象向另一个对象发送消息。Swift 和 Objective-C 的目标-动作模式基本类似。在 Swift,可以使用Selector类型引用 Objective-C 的选择器。请参阅 选择器 小节查看在 Swift 中使用目标-动作模式的示例。

单例

单例模式提供了一个可全局访问的共享对象。可以自己创建在应用程序内共享的单例对象,从而提供一个统一的资源或服务的访问入口,比如一个播放音效的音频通道或发起 HTTP 请求的网络管理者。

在 Objective-C,可以用dispatch_once函数包裹初始化代码,从而保证在应用程序的生命周期内,块内的代码只会执行一次,这样就确保了只有唯一的实例会被创建:

objective-c
+ (instancetype)sharedInstance {
+    static id _sharedInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _sharedInstance = [[self alloc] init];
+    });
+    
+    return _sharedInstance;
+}

在 Swift,可以简单地使用静态类型属性来实现单例,它能保证延迟初始化只执行一次,即使在多个线程同时访问的情况下:

swift
class Singleton {
+    static let sharedInstance = Singleton()
+}

如果在初始化的基础上还需要进行额外的设置,那么可以通过调用闭包返回初始值的方式来初始化:

swift
class Singleton {
+    static let sharedInstance: Singleton = {
+        let instance = Singleton()
+        // 设置代码
+        return instance
+    }()
+}

请参阅 The Swift Programming Language 中文版 中的 类型属性 小节获取更多信息。

内省

在 Objective-C,使用isKindOfClass:方法检查某个对象是否是特定类型的实例,使用conformsToProtocol:方法检查某个对象是否符合特定协议。在 Swift,可以使用is运算符来检查类型,可以使用as?运算符向下转换到指定类型。

可以使用is运算符检查一个实例是否是指定类或其子类的实例。若是,那么is返回结果为true,反之为false

swift
if object is UIButton {
+    // object 是 UIButton 类型
+} else {
+    // object 不是 UIButton 类型
+}

也可以使用as?运算符尝试向下转换到子类型。as?运算符返回可选类型的值,可结合if-let语句使用。

swift
if let button = object as? UIButton {
+    // object 成功转换为 UIButton 并绑定到 button
+} else {
+    // object 无法转换为 UIButton
+}

请参阅 The Swift Programming Language 中文版 中的 类型转换 章节获取更多信息。

检查协议符合性以及转换到符合协议类型的语法和上述类型检查和转换的语法是完全一样的。如下是使用as?检查协议符合性的示例:

swift
if let dataSource = object as? UITableViewDataSource {
+    // object 符合 UITableViewDataSource 协议并绑定到 dataSource
+} else {
+    // object 不符合 UITableViewDataSource 协议
+}

注意,经过转换之后,dataSource常量的类型为UITableViewDataSource,所以只能访问和调用UITableViewDataSource协议定义的属性和方法。想进行其他操作时,必须将其转换为其他类型。

请参阅 The Swift Programming Language 中文版 中的 协议 章节获取更多信息。

序列化

通过序列化,可以在应用程序中编码和解码对象,将其转换为独立于体系结构的数据形式,例如 JSON 或属性列表,并能从这类数据形式转换回对象。这类数据形式可以写入文件,传给其他本地进程,以及通过网络进行传递。

在 Objective-C 中,可以使用 Foundation 框架的 NSJSONSerialiation 类或 NSPropertyListSerialization 类从 JSON 或者属性列表来实例化对象,通常这种对象会是 NSDictionary<NSString *, id> 类型。

在 Swift 中,标准库定义了一套标准化方法来编码和解码数据。若要使用这套方法,你可以让自定义类型遵守 Encodable 或 Decodable 协议,若要同时遵守这两种协议,更便捷的方式是直接遵守 Codable 协议。你可以通过 Foundation 库中的 JSONEncoderPropertyListEncoder 类将某个实例转化为 JSON 或属性列表数据。与此相似,你可以用 JSONDecoderPropertyListDecoder 类从 JSON 或属性列表数据解码并初始化实例。

例如,一个应用从 web 服务器接收到一些表示食品杂货店商品的 JSON 数据,如下所示:

swift
{
+    "name": "Banana",
+    "points": 200,
+    "description": "A banana grown in Ecuador.",
+    "varieties": [
+    	"yellow",
+    	"green",
+    	"brown"
+    ]
+}

如下代码演示了如何编写一个表示食品杂货店商品的 Swift 类型,该类型可以使用任何提供了编码器和解码器的序列化格式:

swift
struct GroceryProduct: Codable {
+    let name: String
+    let points: Int
+    let description: String
+    let varieties: [String]
+}

你可以从 JSON 数据形式创建 GroceryProduct 实例,只需创建一个 JSONDecoder 实例,然后传入 GroceryProduct.self 类型以及相应的 JSON 数据:

swift
let json = """
+    {
+         "name": "Banana",
+         "points": 200,
+         "description": "A banana grown in Ecuador.",
+         "varieties": [
+             "yellow",
+             "green",
+             "brown"
+          ]
+    }
+""".data(using: .utf8)!
+
+let decoder = JSONDecoder()
+let banana = try decoder.decode(GroceryProduct.self, from: json)
+
+print("\(banana.name) (\(banana.points) points): \(banana.description)")
+// Prints "Banana (200 points): A banana grown in Ecuador."

关于如何编码和解码更复杂的自定义类型的相关信息,请参阅 Encoding and Decoding Custom Types。关于如何编码和解码 JSON 的更多信息,请参阅 Using JSON with Custom Types

本地化

在 Objective-C,通常用NSLocalizedString系列宏来本地化字符串。这套宏包括NSLocalizedStringNSLocalizedStringFromTableNSLocalizedStringFromTableInBundle,以及NSLocalizedStringWithDefaultValue。而在 Swift,NSLocalizedString(_:tableName:bundle:value:comment:)函数就可以实现NSLocalizedString系列宏的这些功能。

Swift 并没有为每个本地化宏单独定义函数,而是为NSLocalizedString(_:tableName:bundle:value:comment:)函数的tableNamebundlevalue参数提供了默认值,以便可以在需要时重写它们。

例如,本地化字符串最常见的形式可能仅仅需要一个本地化键和一句注释:

swift
let format = NSLocalizedString("Hello, %@!", comment: "Hello, {given name}!")
+let name = "Mei"
+let greeting = String(format: format, arguments: [name as CVarArg])
+print(greeting)
+// 打印 "Hello, Mei!"

或者,为了使用单独的包来提供本地化资源,应用可能需要使用更复杂的本地化形式:

swift
if let path = Bundle.main.path(forResource: "Localization", ofType: "strings", inDirectory: nil, forLocalization: "ja"),
+    let bundle = Bundle(path: path) {
+    let translation = NSLocalizedString("Hello", bundle: bundle, comment: "")
+    print(translation)
+}
+// 打印 "こんにちは"

更多信息请参阅 Internationalization and Localization Guide

自动释放池

自动释放池块可以让对象放弃所有权而又不会被立即释放。通常,你不需要创建自己的自动释放池块,但是有的情况下则必须创建,例如生成次级线程时,还有一些时候则最好创建,例如通过循环创建大量临时的自动释放对象时。

在 Objective-C,自动释放池块使用@autoreleasepool标记。在 Swift,你可以使用autoreleasepool(_:)函数在自动释放池块中执行一个闭包。

swift
import Foundation
+
+autoreleasepool {
+    // 创建自动释放对象的相关代码
+}

更多信息请参阅 Advanced Memory Management Programming Guide.

API 可用性

一些 API 并非在所有平台的所有版本中都可用。为了确保应用程序能够适应任何功能上的差异,就需要检查这些 API 的可用性。

在 Objective-C,使用respondsToSelector:instancesRespondToSelector:方法检查一个类或者实例的方法是否可用。否则,调用方法可能会抛出NSInvalidArgumentException类型的unrecognized selector sent to instance异常。例如,CLLocationManager实例的requestWhenInUseAuthorization方法从iOS 8.0macOS10.10开始才可用:

objective-c
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {
+    // 方法可用
+} else {
+    // 方法不可用
+}

在 Swift,试图调用项目所支持的最低平台版本不支持的方法将会引发编译时错误。

如上例子在 Swift 中如下所示:

swift
let locationManager = CLLocationManager()
+locationManager.requestWhenInUseAuthorization()
+// error: only available on iOS 8.0 or newer

如果应用程序在版本低于iOS 8.0或者macOS 10.10的平台上运行,那么requestWhenInUseAuthorization()方法将不可用,因此编译器会报告错误。

Swift 代码可以使用 API 可用性在运行时作为判断条件。可用性检查可以作为控制流语句的一个条件,例如ifguardwhile语句。

针对之前的例子,可以在if语句中检查可用性,当requestWhenInUseAuthorization()方法在运行时可用时才去调用:

swift
let locationManager = CLLocationManager()
+if #available(iOS 8.0, macOS 10.10, *) {
+    locationManager.requestWhenInUseAuthorization()
+}

或者,可以在guard语句中检查可用性,除非当前的平台版本符合指定要求,否则将退出作用域。这种方式简化了处理不同平台功能时的逻辑。

swift
let locationManager = CLLocationManager()
+guard #available(iOS 8.0, macOS 10.10, *) else { return }
+locationManager.requestWhenInUseAuthorization()

每个平台参数由下面列出的平台名称组成,后面跟着相应的版本号。最后一个参数是一个星号(*),用来处理未来可能的平台。

平台名称:

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension

所有的 Cocoa API 都提供了可用性信息,因此能确信代码可以在应用所支持的任何平台上如期工作。

可以用@available特性标注自己的 API 声明来指明其可用性。@available特性的语法和#available一样,以逗号分隔的参数提供平台版本要求。

例如:

swift
@available(iOS 8.0, macOS 10.10, *)
+func useShinyNewFeature() {
+    // ...
+}

注意
使用@available特性标记的方法可以安全地使用满足指定平台要求的 API 而不用再进行可用性检查。

处理命令行参数

macOS,通常通过点击 Dock 或者 Launchpad 上的应用程序图标启动应用程序,也可以双击 Finder 中的应用程序图标。然而,也可以使用终端通过编程的方式打开应用程序,并可以为其传递一些命令行参数。

可以访问类型属性CommandLine.arguments获取应用程序启动时指定的一系列命令行参数。

$ /path/to/app --argumentName value
swift
for argument in CommandLine.arguments {
+    print(argument)
+}
+// 打印 /path/to/app
+// 打印 --argumentName
+// 打印 value

CommandLine.arguments的第一个元素总是可执行文件的路径。从Process.arguments[1]开始才是启动时指定的命令行参数。

注意
这等同于访问ProcessInfo.processInfoarguments属性。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/02-Interoperability/05-Interacting with C APIs.html b/docs/.vitepress/dist/frontend/swift/02-Interoperability/05-Interacting with C APIs.html new file mode 100644 index 0000000..595b9ec --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/02-Interoperability/05-Interacting with C APIs.html @@ -0,0 +1,231 @@ + + + + + + 与 C 语言 API 交互 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

与 C 语言 API 交互

为了更好地支持与 Objective-C 语言的互用性,Swift 对一些 C 语言的类型和特性保持了兼容性,提供了一些方式来使用常见的 C 语言设计和模式。

基本类型

Swift 提供了一些与 C 语言基本数值类型(例如charintfloatdouble)对应的类型。然而,这些类型和 Swift 基本数值类型(例如Int)之间不能进行隐式转换。因此,只应在必要时才使用这些类型,尽可能地使用Int这种原生 Swift 类型。

C 类型Swift 类型
boolCBool
char, signed charCChar
unsigned charCUnsignedChar
shortCShort
unsigned shortCUnsignedShort
intCInt
unsigned intCUnsignedInt
longCLong
unsigned longCUnsignedLong
long longCLongLong
unsigned long longCUnsignedLongLong
wchar_tCWideChar
char16_tCChar16
char32_tCChar32
floatCFloat
doubleCDouble

全局常量

C 和 Objective-C 的源文件中定义的全局常量会自动被 Swift 编译器导入为 Swift 全局常量。

导入的常量枚举和结构体

在 Objective-C,常量通常用来为属性或者方法参数提供一系列合适的值。你可以用 NS_TYPED_ENUMNS_TYPED_EXTENSIBLE_ENUM 宏标注 Objective-C typedef 声明,这样 Swift 就会将该类型导入为枚举或结构体,而该类型的各种常量会变成相应的类型成员。使用 NS_TYPED_ENUM 宏标注一套不会再扩充新值的常量声明。使用 NS_TYPED_EXTENSIBLE_ENUM 宏标注一套可以通过 Swift 扩展来扩充新值的常量声明。

表示一组固定值的常量声明在标注 NS_TYPED_ENUM 宏之后会以结构体形式导入到 Swift。例如,请考虑如下整形常量类型 TrafficLightColor 的 Objective-C 声明:

objective-c
typedef long TrafficLightColor NS_TYPED_ENUM;
+
+TrafficLightColor const TrafficLightColorRed;
+TrafficLightColor const TrafficLightColorYellow;
+TrafficLightColor const TrafficLightColorGreen;

Swift 会以如下形式导入它们:

swift
struct TrafficLightColor: RawRepresentable, Equatable, Hashable {
+    typealias RawValue = Int
+
+    init(rawValue: RawValue)
+    var rawValue: RawValue { get }
+
+    static var red: TrafficLightColor { get }
+    static var yellow: TrafficLightColor { get }
+    static var green: TrafficLightColor { get }
+}

表示一套可扩充新值的常量的声明在标注 NS_TYPED_EXTENSIBLE_ENUM 宏之后也会作为结构体导入到 Swift。例如,考虑以下 Objective-C 声明,它们表示交通信号灯的颜色组合:

objective-c
typedef TrafficLightColor TrafficLightCombo [3] NS_TYPED_EXTENSIBLE_ENUM;
+
+TrafficLightCombo const TrafficLightComboJustRed;
+TrafficLightCombo const TrafficLightComboJustYellow;
+TrafficLightCombo const TrafficLightComboJustGreen;
+
+TrafficLightCombo const TrafficLightComboRedYellow;

Swift 会以如下形式导入它们:

swift
struct TrafficLightCombo: RawRepresentable, Equatable, Hashable {
+    typealias RawValue = (TrafficLightColor, TrafficLightColor, TrafficLightColor)
+
+    init(_ rawValue: RawValue)
+    init(rawValue: RawValue)
+    var rawValue: RawValue { get }
+
+    static var justRed: TrafficLightCombo { get }
+    static var justYellow: TrafficLightCombo { get }
+    static var justGreen: TrafficLightCombo { get }
+    static var redYellow: TrafficLightCombo { get }
+}

可以看到,使用可扩充形式的常量声明在导入后会额外获得一个构造器,这使得调用者可以在扩充新值时省略参数标签。

标注 NS_TYPED_EXTENSIBLE_ENUM 宏的常量声明可在 Swift 代码中进行扩充以添加新值:

swift
extension TrafficLightCombo {
+    static var all: TrafficLightCombo {
+        return TrafficLightCombo((.red, .yellow, .green))
+    }
+}

注意
你可能会遇到使用 NS_STRING_ENUMNS_EXTENSIBLE_STRING_ENUM 旧版宏的 Objective-C 代码,这些宏用于组织字符串常量。组织任意类型的相关常量(包括字符串常量)时,请使用 NS_TYPED_ENUMNS_TYPED_EXTENSIBLE_ENUM

函数

Swift 将 C 头文件中的所有函数声明导入为 Swift 全局函数。例如,思考如下 Objective-C 函数声明:

objective-c
int product(int multiplier, int multiplicand);
+int quotient(int dividend, int devisor, int *remainder);
+
+struct Point2D createPoint2D(float x, float y);
+float distance(struct Point2D from, struct Point2D to);

Swift 会以如下形式导入它们:

swift
func product(_ multiplier: Int32, _ multiplicand: Int32) -> Int32
+func quotient(_ dividend: Int32, _ devisor: Int32, _ remainder: UnsafeMutablePointer<Int32>) -> Int32
+
+func createPoint2D(_ x: Float, _ y: Float) -> Point2D
+func distance(_ from: Point2D, _ to: Point2D) -> Float

变参函数

在 Swift,可以调用 C 中的可变参数函数,例如vasprintf函数,调用这种函数需使用 getVaList(_:)withVaList(_:_:) 函数。getVaList(_:)函数接受一个CVarArgType类型的数组,返回一个CVaListPointer类型的值。withVaList(_:_:)函数则会在闭包体中通过闭包参数来提供该值,而不是直接返回它。最终,CVaListPointer类型的值会传递给接受可变参数的 C 函数的va_list参数。

例如,如下示例代码演示了如何在 Swift 中调用vasprintf函数:

swift
func swiftprintf(format: String, arguments: CVarArg...) -> String? {
+    return withVaList(arguments) { va_list in
+        var buffer: UnsafeMutablePointer<Int8>? = nil
+        return format.withCString { CString in
+            guard vasprintf(&buffer, CString, va_list) != 0 else {
+                return nil
+            }
+
+            return String(validatingUTF8: buffer!)
+        }
+    }
+}
+print(swiftprintf(format: "√2 ≅ %g", arguments: sqrt(2.0))!)
+// 打印 "√2 ≅ 1.41421"

注意
可选指针不能传递给withVaList(_:invoke:)函数。相反,使用Int.init(bitPattern:)构造器将可选指针转化为Int值,在所有支持的平台上,Int类型的 C 可变函数调用约定和指针类型一样。

结构体

Swift 将 C 头文件中的所有结构体声明导入为 Swift 结构体。导入后的结构体会用存储属性表示结构体中的字段,并且有一个参数对应各个存储属性的构造器。如果所有被导入的结构体成员都有默认值,Swift 还会提供一个无参数的默认构造器。例如,思考如下 C 结构体声明:

objective-c
struct Color {
+    float r, g, b;
+};
+typedef struct Color Color;

相对应的 Swift 结构体如下所示:

swift
public struct Color {
+    var r: Float
+    var g: Float
+    var b: Float
+
+    init()
+    init(r: Float, g: Float, b: Float)
+}

导入函数作为类型成员

C API,例如 Core Foundation 框架,通常会提供一些函数用于创建、访问、修改结构体。你可以在自己的代码中使用CF_SWIFT_NAME宏来让 Swift 将这些 C 函数导入为相应结构体的成员函数。例如,对于如下 C 函数声明:

objective-c
Color ColorCreateWithCMYK(float c, float m, float y, float k) CF_SWIFT_NAME(Color.init(c:m:y:k:));
+
+float ColorGetHue(Color color) CF_SWIFT_NAME(getter:Color.hue(self:));
+void ColorSetHue(Color color, float hue) CF_SWIFT_NAME(setter:Color.hue(self:newValue:));
+
+Color ColorDarkenColor(Color color, float amount) CF_SWIFT_NAME(Color.darken(self:amount:));
+
+extern const Color ColorBondiBlue CF_SWIFT_NAME(Color.bondiBlue);
+
+Color ColorGetCalibrationColor(void) CF_SWIFT_NAME(getter:Color.calibration());
+Color ColorSetCalibrationColor(Color color) CF_SWIFT_NAME(setter:Color.calibration(newValue:));

Swift 会将其导入为结构体的成员函数:

swift
extension Color {
+    init(c: Float, m: Float, y: Float, k: Float)
+
+    var hue: Float { get set }
+
+    func darken(amount: Float) -> Color
+
+    static var bondiBlue: Color
+
+    static var calibration: Color
+}

传入CF_SWIFT_NAME宏的参数使用和#selector表达式相同的语法。实例方法对应的CF_SWIFT_NAME宏中的参数self引用着方法的调用者。

注意
你无法使用CF_SWIFT_NAME宏改变方法的参数顺序或参数数量,要实现该需求,只能提供一个新的 Swift 函数,并在函数实现中调用相关函数。

枚举

Swift 会将用NS_ENUM宏标注的 C 语言枚举导入为原始值类型为Int的 Swift 枚举。无论是系统框架还是自己代码中的枚举,导入到 Swift 后,它们的前缀名均会被移除。

例如,一个 Objective-C 枚举的声明如下:

objective-c
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
+	UITableViewCellStyleDefault,
+    UITableViewCellStyleValue1,
+    UITableViewCellStyleValue2,
+    UITableViewCellStyleSubtitle
+};

在 Swift,它被导入为如下形式:

swift
enum UITableViewCellStyle: Int {
+    case `default`
+    case value1
+    case value2
+    case subtitle
+}

需要使用一个枚举值时,使用以点(.)开头的枚举变量名:

swift
let cellStyle: UITableViewCellStyle = .default

注意
对于导入到 Swift 的 C 枚举,使用原始值进行初始化时,即使原始值不匹配任何枚举值,初始化也不会失败。这是为了兼容 C 枚举的特性,即枚举可以存储任何值,包括一些只在内部使用而没有在头文件中暴露出来的值。

Swift 会将未使用NS_ENUMNS_OPTIONS宏标注的 C 语言枚举导入为结构体。每个枚举成员会被导入为属性类型是该结构体类型的全局只读计算型属性,而不是作为结构体本身的属性。

例如,下面是个未使用NS_ENUM宏声明的 C 语言枚举:

objective-c
typedef enum {
+    MessageDispositionUnread = 0,
+    MessageDispositionRead = 1,
+    MessageDispositionDeleted = -1,
+} MessageDisposition;

在 Swift,它被导入为如下形式:

swift
struct MessageDisposition: RawRepresentable, Equatable {}
+
+var MessageDispositionUnread: MessageDisposition { get }
+var MessageDispositionRead: MessageDisposition { get }
+var MessageDispositionDeleted: MessageDisposition { get }

被导入到 Swift 的 C 语言枚举会自动遵守Equatable协议。

选项集

Swfit 会将使用NS_OPTIONS宏标注的 C 语言枚举导入为 Swfit 选项集。选项集会像枚举一样把前缀移除,只剩下选项值名称。

例如,一个 Objective-C 选项集的声明如下:

objective-c
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
+    UIViewAutoresizingNone                 = 0,
+    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
+    UIViewAutoresizingFlexibleWidth        = 1 << 1,
+    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
+    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
+    UIViewAutoresizingFlexibleHeight       = 1 << 4,
+    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
+};

在 Swift,它被导入为如下形式:

swift
public struct UIViewAutoresizing : OptionSet {
+    public init(rawValue: UInt)
+
+    public static var flexibleLeftMargin: UIViewAutoresizing { get }
+    public static var flexibleWidth: UIViewAutoresizing { get }
+    public static var flexibleRightMargin: UIViewAutoresizing { get }
+    public static var flexibleTopMargin: UIViewAutoresizing { get }
+    public static var flexibleHeight: UIViewAutoresizing { get }
+    public static var flexibleBottomMargin: UIViewAutoresizing { get }
+}

在 Objective-C,一个选项集是一些整数值的位掩码。可以使用按位或操作符(|)组合选项值,使用按位与操作符(&)检查选项值。可以使用常量值或者表达式创建一个选项集。一个空的选项集使用常数0表示。

在 Swift,选项集用一个遵守OptionSet协议的结构体表示,每个选项值都是结构体的一个静态变量。可以使用一个数组字面量创建一个选项集,访问选项值像枚举一样也用点(.)开头。创建空选项集时,可以使用一个空数组字面量,也可以调用默认构造器。

注意
在导入标注NS_OPTIONS宏的 C 枚举时,Swift 会忽略值为0的枚举成员,因为 Swift 会使用空选项集表示这种选项。

选项集类似于 Swift 的集合类型Set,可以用insert(_:)或者formUnion(_:)方法添加选项值,用remove(_:)或者subtract(_:)方法移除选项值,用contains(_:)方法检查选项值。

swift
let options: Data.Base64EncodingOptions = [
+    .lineLength64Characters,
+    .endLineWithLineFeed
+]
+let string = data.base64EncodedString(options: options)

联合体

Swift 将 C 联合体导入为 Swift 结构体。尽管 Swift 不支持联合体,但 C 联合体导入为 Swift 结构体后仍将保持类似 C 联合体的行为。例如,思考如下名为SchroedingersCat的 C 联合体,它拥有isAliveisDead两个字段:

swift
union SchroedingersCat {
+    bool isAlive;
+    bool isDead;
+};
+
+它被导入到 Swift 后如下所示:
+
+struct SchroedingersCat {
+    var isAlive: Bool { get set }
+    var isDead: Bool { get set }
+
+    init(isAlive: Bool)
+    init(isDead: Bool)
+
+    init()
+}

由于 C 联合体所有字段共享同一块内存,因此联合体作为结构体导入到 Swift 后,所有计算属性也会共享同一块内存。这将导致修改任意计算属性的值都会改变其他计算属性的值。

在上述例子中,修改结构体SchroedingersCat的计算属性isAlive的值也会改变计算属性isDead的值:

swift
var mittens = SchroedingersCat(isAlive: false)
+
+print(mittens.isAlive, mittens.isDead)
+// 打印 "false false"
+
+mittens.isAlive = true
+print(mittens.isDead)
+// 打印 "true"

位字段

Swift 会将结构体中的位字段导入为结构体的计算型属性,例如 Foundation 中的NSDecimal类型。使用位字段相对应的计算属性时,Swift 会处理好这些值和其兼容的 Swift 类型之间的转换工作。

匿名结构体和联合体字段

C structunion类型既可以定义匿名字段,也可以定义具有匿名类型的字段。匿名字段由内部所嵌套的拥有命名字段的structunion类型构成。

例如,在如下这个 C 结构体Cake中,layersheight两个字段嵌套在匿名union类型中,toppings字段则是一个匿名struct类型:

objective-c
struct Cake {
+    union {
+        int layers;
+        double height;
+    };
+
+    struct {
+        bool icing;
+        bool sprinkles;
+    } toppings;
+};

导入到 Swift 后,可以像如下这样创建和使用它:

swift
var simpleCake = Cake()
+simpleCake.layers = 5
+print(simpleCake.toppings.icing)

Cake结构体被导入后会拥有一个逐一成员构造器,可以通过该构造器将结构体的字段初始化为自定义的值,就像下面这样:

swift
let cake = Cake(
+    .init(layers: 2),
+    toppings: .init(icing: true, sprinkles: false)
+)
+
+print("The cake has \(cake.layers) layers.")
+// 打印 "The cake has 2 layers."
+print("Does it have sprinkles?", cake.toppings.sprinkles ? "Yes." : "No.")
+// 打印 "Does it have sprinkles? No."

因为Cake结构体第一个字段是匿名的,因此构造器的第一个参数没有标签。由于Cake结构体的字段是匿名类型,因此使用.init构造器,这将借助类型推断来为结构体的每个匿名字段设置初始值。

指针

Swift 尽可能地避免直接使用指针。不过,Swift 也提供了多种指针类型以供直接操作内存。如下表格使用Type作为类型名称的占位符来表示相应的映射语法。

对于返回类型,变量和参数,遵循如下映射:

C 语法Swift 语法
const Type *UnsafePointer<Type>
Type *UnsafeMutablePointer<Type>

对于类类型,遵循如下映射:

C 语法Swift 语法
Type * const *UnsafePointer<Type>
Type * __strong *UnsafeMutablePointer<Type>
Type **AutoreleasingUnsafeMutablePointer<Type>

对于指向原始内存的无类型指针,遵循如下映射:

C 语法Swift 语法
const void *UnsafeRawPointer
void *UnsafeMutableRawPointer

如果指针的类型在 Swift 中无法表示,例如某个不完备的结构体类型,Swift 会将之导入为OpaquePointer

常量指针

如果函数接受UnsafePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • UnsafePointer<Type>UnsafeMutablePointer<Type>AutoreleasingUnsafeMutablePointer<Type>类型的值,后两种类型会转换成UnsafePointer<Type>
  • 一个String类型的值,如果TypeInt8或者UInt8String类型的值会被自动转换为 UTF8 形式到一个缓冲区内,该缓冲区的指针会被传递给函数。
  • 一个左操作数为Type类型的inout表达式,左操作数的内存地址作为函数参数传入。
  • 一个[Type]类型的值,将作为该数组的起始指针传递给函数。

传递给函数的指针仅保证在函数调用期间内有效,不要试图保留指针并在函数返回之后继续使用。

如果定义了一个类似下面这样的函数:

swift
func takesAPointer(_ p: UnsafePointer<Float>) {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0
+takesAPointer(&x)
+takesAPointer([1.0, 2.0, 3.0])

如果函数接受UnsafeRawPointer参数,那么该函数参数可以是任意类型的UnsafePointer<Type>

如果定义了一个类似下面这样的函数:

swift
func takesAVoidPointer(_ p: UnsafeRawPointer?)  {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0, y: Int = 0
+takesAVoidPointer(&x)
+takesAVoidPointer(&y)
+takesAVoidPointer([1.0, 2.0, 3.0] as [Float])
+let intArray = [1, 2, 3]
+takesAVoidPointer(intArray)

可变指针

如果函数接受UnsafeMutablePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • 一个UnsafeMutablePointer<Type>类型的值。
  • 一个左操作数为Type类型的inout表达式,左操作数的内存地址作为函数参数传入。
  • 一个inout [Type]类型的值,将作为该数组的起始指针传入,其生命周期会延续到本次调用结束。

如果定义了一个类似下面这样的函数:

swift
func takesAMutablePointer(_ p: UnsafeMutablePointer<Float>) {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0
+var a: [Float] = [1.0, 2.0, 3.0]
+takesAMutablePointer(&x)
+takesAMutablePointer(&a)

如果函数接受UnsafeMutableRawPointer参数,那么该函数参数可以是任意类型的UnsafeMutablePointer<Type>

如果定义了一个类似下面这样的函数:

swift
func takesAMutableVoidPointer(_ p: UnsafeMutableRawPointer?)  {
+    // ...
+}

那么可以通过以下任意一种方式来调用该函数:

swift
var x: Float = 0.0, y: Int = 0
+var a: [Float] = [1.0, 2.0, 3.0], b: [Int] = [1, 2, 3]
+takesAMutableVoidPointer(&x)
+takesAMutableVoidPointer(&y)
+takesAMutableVoidPointer(&a)
+takesAMutableVoidPointer(&b)

自动释放指针

如果函数接受AutoreleasingUnsafeMutablePointer<Type>参数,那么该函数参数可以是下列任意一种类型:

  • 一个AutoreleasingUnsafeMutablePointer<Type>类型的值。
  • 一个inout表达式,其操作数首先被拷贝到一个无主临时缓冲区,缓冲区的地址会作为函数参数传入。函数调用结束时,读取并保留缓冲区中的值,然后重新赋值给操作数。

注意,上述列表中没有包含数组。

如果定义了一个类似下面这样的函数:

swift
func takesAnAutoreleasingPointer(_ p: AutoreleasingUnsafeMutablePointer<NSDate?>) {
+    // ...
+}

那么可以通过以下方式来调用该函数:

swift
var x: NSDate? = nil
+takesAnAutoreleasingPointer(&x)

指针指向的类型不会被桥接。例如,NSString **转换到 Swift 后,会是AutoreleasingUnsafeMutablePointer<NSString?>,而不是AutoreleasingUnsafeMutablePointer<String?>

函数指针

Swift 将 C 函数指针导入为沿用其调用约定的闭包,使用@convention(c)特性来表示。例如,一个类型为int (*)(void)的 C 函数指针,会以@convention(c) () -> Int32的形式导入到 Swift。

调用一个以函数指针为参数的函数时,可以传递一个顶级的 Swift 函数作为其参数,也可以传递闭包字面量,或者nil。也可以传递一个泛型类型的闭包属性或者泛型方法,只要闭包的参数列表或闭包体内没有引用泛型类型的参数。例如,Core Foundation 的CFArrayCreateMutable(_:_:_:)函数接受一个CFArrayCallBacks结构体作为参数,这个CFArrayCallBacks结构体使用一些函数指针进行初始化:

swift
func customCopyDescription(_ p: UnsafeRawPointer?) -> Unmanaged<CFString>? {
+    // 返回一个 Unmanaged<CFString>? 值
+}
+
+var callbacks = CFArrayCallBacks(
+    version: 0,
+    retain: nil,
+    release: nil,
+    copyDescription: customCopyDescription,
+    equal: { (p1, p2) -> DarwinBoolean in
+        // 返回布尔值
+    }
+)
+
+var mutableArray = CFArrayCreateMutable(nil, 0, &callbacks)

上面的例子中,结构体CFArrayCallBacks的构造器使用nil作为参数retainrelease的值,使用函数customCopyDescription作为参数copyDescription的值,最后使用一个闭包字面量作为参数equal的值。

注意
只有使用 C 函数指针调用约定的 Swift 函数才可以作为函数指针参数。如同 C 函数指针,使用@convention(c)特性的 Swift 函数同样不具有捕获周围作用域上下文的能力。

更多信息请参阅 The Swift Programming Language 中文版类型特性小节。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html b/docs/.vitepress/dist/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html new file mode 100644 index 0000000..d087488 --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.html @@ -0,0 +1,103 @@ + + + + + + 在项目中同时使用 Swift 和 Objective-C | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

在项目中同时使用 Swift 和 Objective-C

由于 Swift 与 Objective-C 的兼容性,你可以在项目中同时使用两种语言,开发基于混合语言的应用程序。利用这种特性,你可以用 Swift 的最新语言特性实现应用程序的部分功能,并无缝并入现有的 Objective-C 代码中。

混搭概述

Objective-C 和 Swift 文件可以在项目中并存,无论这个项目原本是基于 Objective-C 还是 Swift。还可以直接往现有项目中添加另一种语言的源文件。这种自然的工作流程使得创建基于混合语言的应用程序或框架变得和单独使用一种语言一样简单。

基于混合语言编写应用程序或框架的过程还是有些区别的。下图展示了同时使用两种语言时,在同一 target 中导入代码的基本原理,后续小节会介绍更多细节。

在应用程序 target 中导入代码

在编写基于混合语言的应用程序时,可能需要在 Swift 代码中使用 Objective-C 代码,或者反过来。下面描述的流程适用于非框架类型的 target 。

将 Objective-C 代码导入到 Swift

在应用程序 target 中导入一系列 Objective-C 文件供 Swift 代码使用时,需要依靠 Objective-C 桥接头文件将这些文件暴露给 Swift。添加 Swift 文件到现有的 Objective-C 项目时(或者反过来),Xcode 会自动创建 Objective-C 桥接头文件。

如果选择创建,Xcode 会随着源文件的创建生成 Objective-C 桥接头文件,并用产品模块名拼接上"-Bridging-Header.h"作为 Objective-C 桥接头文件的文件名。关于产品模块名的具体介绍,请参阅为产品模块命名小节。

或者,可以选择File > New > File > (iOS,watchOS,tvOS,macOS) > Source > Header File来手动创建 Objective-C 桥接头文件。

你可以编辑这个 Objective-C 桥接头文件将 Objective-C API 暴露给 Swift。

在 target 中将 Objective-C 代码导入到 Swift
  1. 在 Objective-C 桥接头文件中,导入希望暴露给 Swift 的 Objective-C 头文件。例如:

    objective-c
    #import "XYZCustomCell.h"
    +#import "XYZCustomView.h"
    +#import "XYZCustomViewController.h"
  2. 确保在Build Settings > Swfit Compiler - Code Generation > Objective-C Bridging Header中设置了 Objective-C 桥接头文件的路径。该路径相对于项目,类似Info.plistBuild Settings中指定的路径。Xcode 自动生成 Objective-C 桥接头文件时会自动设置该路径,因此大多数情况下你不需要专门去设置它。

在 Objective-C 桥接头文件中导入的所有 Objective-C 头文件都会暴露给 Swift。target 中所有 Swift 文件都可以使用这些 Objective-C 头文件中的内容,不需要任何导入语句。不但如此,你还能用 Swift 语法使用这些自定义的 Objective-C 代码,就像使用系统的 Swift 类一样。

swift
let myCell = XYZCustomCell()
+myCell.subtitle = "A custom cell"

将 Swift 代码导入到 Objective-C

将 Swift 代码导入到 Objective-C 时,需要依靠 Xcode 自动生成的头文件将这些 Swift 文件暴露给 Objective-C(此头文件不是上小节描述的 Objective-C 桥接头文件,该头文件在项目目录下不可见,但是可以跳转进去查看)。这个自动生成的头文件是一个 Objective-C 头文件,声明了 target 中的一些 Swift 接口。可以将这个 Objective-C 头文件看作 Swift 代码的保护伞头文件。该头文件以产品模块名拼接上"-Swift.h"来命名。关于产品模块名的具体介绍,请参阅为产品模块命名小节。

默认情况下,这个头文件包含所有标记publicopen修饰符的 Swift 声明。如果 target 中有 Objective-C 桥接头文件的话,它还会包含标记internal修饰符的 Swift 声明。标记privatefileprivate修饰符的 Swift 声明不会出现在这个头文件中。私有声明不会暴露给 Objective-C,除非它们被标记@IBAction@IBOutlet@objc。如果应用程序的 target 启用了单元测试,在单元测试的 target 中导入应用程序的 target 时,在import语句前加上@testable特性,就可以在单元测试的 target 中访问应用程序的 target 中任何标记internal修饰符的声明,犹如它们标记了public修饰符一般。

关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

这个头文件会由 Xcode 自动生成,可直接导入到 Objective-C 代码中使用。注意,如果这个头文件中的 Swift 接口使用了自定义的 Objective-C 类型,在导入这个自动生成的头文件前,必须先将相关的自定义 Objective-C 类型对应的 Objective-C 头文件导入。

在 target 中将 Swift 代码导入到 Objective-C
  • 在 target 中的 Objective-C .m文件中,用如下语法导入 Swift 代码:
objective-c
#import "ProductModuleName-Swift.h" // 将 ProductModuleName 替换为产品模块名

target 中的一些 Swift 声明会暴露给包含这个导入语句的 Objective-C .m文件。关于如何在 Objective-C 中使用 Swift,请参阅在 Objective-C 中使用 Swift小节。

导入到 Swift导入到 Objective-C
Swift 代码不需要导入语句#import "ProductModuleName-Swift.h"
Objective-C 代码不需要导入语句;需要 Objective-C 桥接头文件#import "Header.h"

在框架 target 中导入代码

在编写基于混合语言的框架时,往往需要在 Swift 代码中访问 Objective-C 代码,或者反过来。

将 Objective-C 代码导入到 Swift

若要将 Objective-C 文件导入到 target 中的 Swift 代码中,需要将这些 Objective-C 文件导入到 Objective-C 的保护伞头文件中。

译者注
此处的“保护伞头文件”指的是带有框架版本号和版本字符串声明的那个头文件。

在 target 中将 Objective-C 代码导入到 Swift
  1. 确保将 target 的Build Settings > Packaging > Defines Module设置为Yes

  2. 在保护伞头文件中导入希望暴露给 Swift 的 Objective-C 头文件。例如:

objective-c
#import <XYZ/XYZCustomCell.h>
+#import <XYZ/XYZCustomView.h>
+#import <XYZ/XYZCustomViewController.h>

保护伞头文件中导入的 Objective-C 头文件都会暴露给 Swift。target 中所有 Swift 文件都可以使用这些 Objective-C 头文件中的内容,不需要任何导入语句。不但如此,你还能用 Swift 语法使用这些自定义的 Objective-C 代码,就像使用系统的 Swift 类一样。

swift
let myOtherCell = XYZCustomCell()
+myOtherCell.subtitle = "Another custom cell"

将 Swift 代码导入到 Objective-C

若要将 Swift 文件导入到 target 中的 Objective-C 代码中,不需要导入任何东西到保护伞头文件,只需将 Xcode 为 Swift 代码自动生成的头文件导入到要使用 Swift 代码的 Objective-C .m文件。

由于这个自动生成的头文件是框架公共接口的一部分,因此只有标记publicopen修饰符的 Swift 声明才会出现在这个自动生成的头文件中。

对于继承自 Objective-C 类的 Swift 子类中标记internal修饰符的方法和属性,它们只会暴露给 Objective-C 运行时系统,这意味着它们不会出现在 Swift 代码的头文件中,也无法在编译期访问它们。

译者注
使用这些标记internal的 Swift 声明时,编译器会报错提示符号未定义,研究了一下发现可以采取如下方式解决:

swift
// Swift 代码部分
+@objc(Foo) 
+class Foo: NSObject {
+    func hello() { print("Hello!") }
+}
objective-c
// Objective-C 代码部分
+// 为了解决符号未定义的错误,手动写个接口声明,注意 Swift 代码中的 @objc(Foo),否则会导致类名不匹配
+@interface Foo : NSObject
+- (void)hello;
+@end

关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

在 target 中将 Swift 代码导入到 Objective-C
  1. 确保将 target 的Build Settings > Packaging > Defines Module设置为Yes

  2. 使用如下语法将 Swift 代码导入到 target 中的 Objective-C .m文件:

objective-c
// 分别用产品名和产品模块名替换 ProductName 和 ProductModuleName
+#import <ProductName/ProductModuleName-Swift.h>

target 中的一些 Swift 声明会暴露给包含这个导入语句的 Objective-C .m文件。关于如何在 Objective-C 中使用 Swift,请参阅在 Objective-C 中使用 Swift小节。

导入到 Swift导入到 Objective-C
Swift 代码不需要导入语句#import <ProductName/ProductModuleName-Swift.h>
Objective-C 代码不需要导入语句;需要 Objective-C 保护伞头文件#import "Header.h"

导入外部框架

你可以导入位于其他 target 中的外部框架,无论它是基于 Objective-C,Swift,还是基于混合语言的。导入流程都是一样的,只需确保被导入框架的Build Setting > Pakaging > Defines Module设置为Yes

使用如下语法将外部框架导入到 Swift 文件:

swift
import FrameworkName

使用如下语法将外部框架导入到 Objective-C .m文件:

objective-c
@import FrameworkName;
导入到 Swift导入到 Objective-C
任意语言框架import FrameworkName@import FrameworkName;

在 Objective-C 中使用 Swift

将 Swift 代码导入到 Objective-C 后,就可用标准 Objective-C 语法使用 Swift 类。

objective-c
MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
+[swiftObject swiftMethod];

只有继承自 Objective-C 类的 Swift 类才能在 Objective-C 中使用。想要了解 Swift 如何将接口导入到 Objective-C 以及在 Objective-C 中能使用哪些 Swift 特性,请参阅Swift 类型兼容性小节。

在 Objective-C 头文件中引用 Swift 类或协议

为避免循环引用,不要将 Swift 代码导入到 Objective-C 头文件(.h文件),而应该使用前向声明来引用一个 Swift 类或者协议。

objective-c
// MyObjcClass.h
+@class MySwiftClass;
+@protocol MySwiftProtocol;
+
+@interface MyObjcClass : NSObject
+- (MySwiftClass *)returnSwiftClassInstance;
+- (id <MySwiftProtocol>)returnInstanceAdoptingSwiftProtocol;
+// ...
+@end

Swift 类和协议的前向声明只能用于声明方法和属性。

声明可被 Objective-C 类遵守的 Swift 协议

将 Swift 协议标记@objc特性,从而让 Objective-C 类可以遵守该协议。

swift
@objc public protocol MySwiftProtocol {
+    func requiredMethod()
+
+    @objc optional func optionalMethod()
+}

为了遵守协议,Objective-C 类必须实现协议中声明的所有构造器,属性,下标,方法。可选的协议要求必须标记@objc特性和optional修饰符。

在 Objective-C 的实现文件中采用 Swift 协议

Objective-C 类可以在实现文件(.m文件)中导入 Xcode 自动生成的 Swift 头文件,然后使用类扩展来采用 Swift 协议。

objective-c
// MyObjcClass.m
+#import "ProductModuleName-Swift.h"
+     
+@interface MyObjcClass () <MySwiftProtocol>
+// ...
+@end
+     
+@implementation MyObjcClass
+// ...
+@end

声明可在 Objective-C 中使用的 Swift 错误类型

遵守Error协议并标记@objc特性的 Swift 枚举会在 Swift 头文件中生成一个NS_ENUM枚举声明,并会为错误域生成相应的NSString字符串常量。例如,有如下 Swift 枚举声明:

swift
@objc public enum CustomError: Int, Error {
+    case a, b, c
+}

Swift 头文件中相应的 Objective-C 声明如下所示:

objective-c
// Project-Swift.h
+typedef SWIFT_ENUM(NSInteger, CustomError) {
+    CustomErrorA = 0,
+    CustomErrorB = 1,
+    CustomErrorC = 2,
+};
+static NSString * const CustomErrorDomain = @"Project.CustomError";

为 Objective-C 接口提供 Swift 命名

Swift 编译器自动将 Objective-C 代码作为常规 Swift 代码导入,它将 Objective-C 类工厂方法导入为 Swift 构造器,还会缩短 Objective-C 枚举值的命名。

代码中也许会存在无法自动处理的特殊情况。对于 Objective-C 方法,枚举值,或者选项集的值,可以使用NS_SWIFT_NAME宏来自定义它们导入到 Swift 后的命名。

类工厂方法

如果 Swift 编译器无法识别类工厂方法,可以使用NS_SWIFT_NAME宏来指定类工厂方法导入为 Swift 构造器后的方法名,从而能够将其正确导入。例如:

objective-c
+ (instancetype)recordWithRPM:(NSUInteger)RPM NS_SWIFT_NAME(init(RPM:));

如果 Swift 编译器错误地将一个普通的类方法识别为类工厂方法,可以使用NS_SWIFT_NAME宏来指定类方法导入为 Swift 类方法后的方法名,从而能够将其正确导入。例如:

objective-c
+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));

枚举

默认情况下,Swift 导入枚举时,会将枚举值的名称前缀截断。如果需要自定义枚举值的名称,可以使用NS_SWIFT_NAME宏来指定枚举值导入到 Swift 后的命名。例如:

objective-c
typedef NS_ENUM(NSInteger, ABCRecordSide) {
+    ABCRecordSideA,
+    ABCRecordSideB NS_SWIFT_NAME(FlipSide),
+};

让 Objective-C 接口在 Swift 中不可用

一些 Objective-C 接口可能不适合或者没必要暴露给 Swift,为了防止 Objective-C 接口导入到 Swift,可以使用NS_SWIFT_UNAVAILABLE宏来传达一个提示信息,从而指引 API 使用者使用其他替代方式。

例如,一个 Objective-C 类提供了一个接收一些键值对作为可变参数的便利构造器,可以建议 Swift 用户使用字典字面量作为替代:

objective-c
+ (instancetype)collectionWithValues:(NSArray *)values 
+                             forKeys:(NSArray<NSCopying> *)keys NS_SWIFT_UNAVAILABLE("使用字典字面量替代");

试图在 Swift 中调用+collectionWithValues:forKeys:方法将导致编译错误。

优化 Objective-C 声明

可以使用NS_REFINED_FOR_SWIFT宏标记 Objective-C 方法的声明,然后在 Swift 中通过扩展提供一个优雅的 Swift 接口,通过该接口去调用方法的原始实现。例如,接收一个或者多个指针参数的 Objective-C 方法可以优化为一个返回元组值的 Swift 方法。使用该宏标记的方法导入到 Swift 后会做如下处理:

  • 对于初始化方法,在第一个外部参数名前加双下划线(__)。
  • 对于对象下标方法,只要设值或取值方法被标记NS_REFINED_FOR_SWIFT宏,这对下标方法就会变为 Swift 中的普通方法。被标记宏的下标方法会在方法名前加双下划线(__)。
  • 对于其他方法,在方法名前加双下划线(__)。

思考如下 Objective-C 声明:

objective-c
@interface Color : NSObject
+
+- (void)getRed:(nullable CGFloat *)red
+         green:(nullable CGFloat *)green
+          blue:(nullable CGFloat *)blue
+         alpha:(nullable CGFloat *)alpha NS_REFINED_FOR_SWIFT;
+         
+@end

可以通过 Swift 扩展来提供一个优化后的接口:

swift
extension Color {
+    var RGBA: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
+        var r: CGFloat = 0.0
+        var g: CGFloat = 0.0
+        var b: CGFloat = 0.0
+        var a: CGFloat = 0.0
+        __getRed(&r, green: &g, blue: &b, alpha: &a)
+        return (red: r, green: g, blue: b, alpha: a)
+    }
+}

将可用性信息添加到 Objective-C API

在 Swift 中为特定平台编译应用时,你可以使用 @available 特性来控制一个声明是否可用。同样,你可以使用可用性条件 #available 根据所需平台和版本有条件地执行代码。

两种可用性说明符在 Objective-C 中都有提供,使用以下示例中展示的相应语法即可。

如下示例展示了如何为 Swift 声明添加可用性信息:

swift
@available(iOS 11, macOS 10.13, *)
+func newMethod() {
+    // 使用 iOS 11 API
+}

如下示例展示了如何在 Objective-C 中添加相同的可用性信息:

objective-c
@interface MyViewController : UIViewController
+- (void) newMethod API_AVAILABLE(ios(11), macosx(10.13));
+@end

如下示例展示了如何在 Swift 条件语句中使用可用性信息:

swift
if #available(iOS 11, *) {
+    // 使用 iOS 11 API
+} else {
+    // 早期版本的 iOS 的替代代码
+}

如下示例展示了如何在 Objective-C 中使用相同的可用性信息:

objective-c
if (@available(iOS 11, *)) {
+    // 使用 iOS 11 API
+} else {
+    // 早期版本的 iOS 的替代代码
+}

关于指定平台可用性的更多信息,请参阅 The Swift Programming Language 中文版 中的声明特性部分。

为产品模块命名

无论是 Xcode 为 Swift 代码自动生成的头文件,还是 Objective-C 桥接头文件,都会根据产品模块名来命名。默认情况下,产品模块名和产品名一样。然而,如果产品名包含特殊字符(只能是字母、数字、下划线),例如点号(.),作为产品模块名时,这些特殊字符会被下划线(_)替换。如果产品名以数字开头,作为产品模块名时,第一个数字也会被下划线替换。

也可以为产品模块名提供一个自定义的名称,Xcode 会根据这个名称来命名桥接头文件和自动生成的头文件,只需修改Build setting > Packaging > Product Module Name中的名称即可。

注意
无法改变框架的产品模块名。

故障排除贴士

  • 将 Swift 和 Objective-C 文件看作同一代码集,注意命名冲突。

  • 如果使用框架,确保框架的Build setting > Packaging > Defines ModuleDEFINES_MODULE)设置为Yes

  • 如果使用 Objective-C 桥接头文件,确保Build setting > Swift Compiler > Code GenerationSWIFT_OBJC_BRIDGING_HEADER)中的头文件路径是头文件自身相对于项目的路径,例如MyApp/MyApp-Bridging-Header.h

  • Xcode 会根据产品模块名(PRODUCT_MODULE_NAME),而不是 target 的名称(TARGET_NAME)来命名 Objective-C 桥接头文件以及为 Swift 代码自动生成的头文件。详情请参阅为产品模块命名小节。

  • 只有继承自 Objective-C 类的 Swift 类,以及标记了@objc(包括各种被隐式标记的情况)的 Swift 声明,才能在 Objective-C 中使用。

  • 将 Swift 代码导入到 Objective-C 时,注意 Objective-C 无法转化 Swift 的独有特性。详情请参阅在 Objective-C 中使用 Swift小节。

  • 如果在 Swift 代码中使用了自定义的 Objective-C 类型,在 Objective-C 中使用这部分 Swift 代码时,确保先导入相关的 Objective-C 类型的头文件,然后再将 Xcode 为 Swift 代码自动生成的头文件导入。

  • 标记privatefileprivate修饰符的 Swift 声明不会出现在自动生成的头文件中,因为私有声明不会暴露给 Objective-C,除非它们被标记@IBAction@IBOutlet或者@objc

  • 对于应用程序的 target,当存在 Objective-C 桥接头文件时,标记internal修饰符的 Swift 声明也会出现在自动生成的头文件中。

  • 对于框架的 target,只有标记publicopen修饰符的声明才会出现在自动生成的头文件中,不过依然可以在框架内部的 Objective-C 代码中使用标记internal修饰符的 Swift API,只要它们所属的类继承自 Objective-C 类。关于访问级别修饰符的更多信息,请参阅 The Swift Programming Language 中文版 中的访问控制章节。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html b/docs/.vitepress/dist/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html new file mode 100644 index 0000000..e7c2b4e --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.html @@ -0,0 +1,29 @@ + + + + + + 迁移 Objective-C 代码到 Swift | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

迁移 Objective-C 代码到 Swift

迁移工作提供了一个重新审视现有的 Objective-C 应用程序的机会,通过用 Swift 代码替换 Objective-C 代码来改善程序的架构,逻辑以及性能。简而言之,通过之前学习的工具,即混搭和互用来对应用程序进行增量迁移。在决定哪些特性和功能用 Swift 实现,哪些依然用 Objective-C 实现时,混搭和互用会让这一切变得简单可行。通过这些工具,可以一步步探索 Swift 广泛的功能并整合到现有的 Objective-C 应用程序中,而不必立刻使用 Swift 重写整个应用程序。

为 Objective-C 代码做好迁移准备

在开始迁移代码之前,请确保 Objective-C 和 Swift 代码间有着最佳兼容性。这意味着你可能需要整理现有项目,并将 Objective-C 现代化特性应用其中。为了更好地与 Swift 无缝交互,现有的 Objective-C 代码需要遵循现代编码实践。在开始前,这有个简短的实践列表,请参阅 Adopting Mordern Objective-C

迁移过程

迁移代码到 Swift 的最有效的方式是逐个文件迁移,即一次迁移一个类。由于无法在 Objective-C 中继承 Swift 类,因此最好选择一个没有子类的类开始。使用单个.swift文件替换对应的.m.h文件,实现和接口将直接放进这个 Swift 文件。你也不用创建头文件,Xcode 会在你需要引用头文件的时候自动生成头文件。

准备迁移

  • 在 Xcode 中,选择File > New > File > (iOS,watchOS,tvOS,macOS) > Source > Swift File为对应的 Objective-C .m.h文件创建一个 Swift 类。可以使用相同或者不同的类名。类前缀在 Swift 中不是必须的。

  • 导入相关的系统框架。

  • 如果需要在 Swift 文件中使用同一 target 中的 Objective-C 代码,可以填写一个 Objective-C 桥接头文件。具体的操作步骤,请参阅在应用程序的 target 中导入代码小节。

  • 为了让 Swift 类能在 Objective-C 中使用,Swift 类必须继承自 Objective-C 类。如果想为 Swift 类指定在 Objective-C 中的类名,可以使用@objc(name)特性,name就是 Swift 类在 Objective-C 中的类名。关于@objc的更多信息,请参阅Swift 类型兼容性小节。

开始迁移

  • 使用 Cocoa 设计模式的时候,请参阅采用 Cocoa 设计模式章节。

  • 对于如何将属性从 Objective-C 转换到 Swift,请参阅 The Swift Programming Language 中文版 中的属性章节。

  • 在需要的时候,使用@objc(name)特性为 Swift 中的属性或方法提供 Objective-C 命名。例如,可以像下面这样将enabled属性的取值方法在 Objective-C 中的命名更改为isEnabled

    swift
    var enabled: Bool {
    +	@objc(isEnabled) get {
    +		// ...
    +	}
    +}
  • 分别用funcclass func来声明实例方法(-)和类方法(+)。

  • 将简单宏声明为全局常量,将复杂宏声明为函数。

完成迁移

  • 将 Objective-C 代码中对应的导入语句更改为#import "ProductModuleName-Swift.h",更多信息请参阅在应用程序的 target 中导入代码小节。

  • 将原始的 Objective-C .m文件在Target Membership选择框中的勾选取消,从而将其从 target 中移除。不要立刻删除.m.h文件,以备解决问题时使用。

  • 如果为 Swift 类起了一个新的类名,在相关代码中请使用新的 Swift 类名代替原来的 Objective-C 类名。

故障排除贴士

尽管对于不同的项目,迁移过程是不尽相同的,但仍有一些通用的办法能解决代码迁移时遇到的问题:

  • 无法在 Objective-C 中继承 Swift 类。因此,被迁移的类不能有任何 Objective-C 子类。

  • 迁移一个类到 Swift 时,必须从 target 中移除相关的.m文件,避免编译时出现符号重复的错误。

  • 为了能在 Objective-C 中使用,Swift 类必须是一个 Objective-C 类的子类。

  • 在将 Swift 代码导入 Objective-C 代码时,切记 Objective-C 不能转化某些 Swift 的独有特性。详细列表请参阅在 Objective-C 中使用 Swift小节。

  • 可以在 Objective-C 代码中通过Commond + 单击一个 Swift 类名的方式来查看 Xcode 为它自动生成的头文件。

  • 可以Option + 单击一个符号来查看它的详细信息,比如它的类型,特性以及文档注释等。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/swift/index.html b/docs/.vitepress/dist/frontend/swift/index.html new file mode 100644 index 0000000..26bbff8 --- /dev/null +++ b/docs/.vitepress/dist/frontend/swift/index.html @@ -0,0 +1,25 @@ + + + + + + 目录 | 前端技术知识库 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/frontend/vue/index.html b/docs/.vitepress/dist/frontend/vue/index.html new file mode 100644 index 0000000..d62b4fb --- /dev/null +++ b/docs/.vitepress/dist/frontend/vue/index.html @@ -0,0 +1,25 @@ + + + + + + vue 前端 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

vue 前端

待更新

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/about.html b/docs/.vitepress/dist/guide/about.html new file mode 100644 index 0000000..93153fe --- /dev/null +++ b/docs/.vitepress/dist/guide/about.html @@ -0,0 +1,25 @@ + + + + + + 关于本知识库 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

关于本知识库

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/api-examples.html b/docs/.vitepress/dist/guide/api-examples.html new file mode 100644 index 0000000..d9f3d5a --- /dev/null +++ b/docs/.vitepress/dist/guide/api-examples.html @@ -0,0 +1,431 @@ + + + + + + Runtime API Examples | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Runtime API Examples

This page demonstrates usage of some of the runtime APIs provided by VitePress.

The main useData() API can be used to access site, theme, and page data for the current page. It works in both .md and .vue files:

md
<script setup>
+import { useData } from 'vitepress'
+
+const { theme, page, frontmatter } = useData()
+</script>
+
+## Results
+
+### Theme Data
+<pre>{{ theme }}</pre>
+
+### Page Data
+<pre>{{ page }}</pre>
+
+### Page Frontmatter
+<pre>{{ frontmatter }}</pre>

Results

Theme Data

{
+  "outlineTitle": "目录",
+  "outline": [
+    2,
+    6
+  ],
+  "nav": [
+    {
+      "text": "首页",
+      "link": "/"
+    },
+    {
+      "text": "前端",
+      "items": [
+        {
+          "text": "Vue",
+          "link": "/frontend/vue/index"
+        },
+        {
+          "text": "iOS",
+          "link": "/frontend/ios/index"
+        }
+      ]
+    },
+    {
+      "text": "语言",
+      "items": [
+        {
+          "text": "js",
+          "link": "/frontend/js/index"
+        },
+        {
+          "text": "swift",
+          "link": "/frontend/swift/index"
+        }
+      ]
+    },
+    {
+      "text": "工程化",
+      "link": "/engineering"
+    },
+    {
+      "text": "后端",
+      "link": "/backend/container/tomcat"
+    },
+    {
+      "text": "网络",
+      "link": "/network"
+    },
+    {
+      "text": "Examples",
+      "link": "/guide/markdown-examples"
+    }
+  ],
+  "sidebar": {
+    "/frontend/vue": [
+      {
+        "text": "Vue",
+        "items": []
+      }
+    ],
+    "/frontend/js": [
+      {
+        "text": "JS",
+        "items": []
+      }
+    ],
+    "/frontend/base": [
+      {
+        "text": "基础",
+        "items": [
+          {
+            "text": "xml-tips",
+            "link": "frontend/base/xml-tips.md"
+          }
+        ]
+      },
+      {
+        "text": "其他",
+        "items": [
+          {
+            "text": "2020-03-12-ionic",
+            "link": "frontend/other/2020-03-12-ionic.md"
+          },
+          {
+            "text": "2020-03-22-angular",
+            "link": "frontend/other/2020-03-22-angular.md"
+          }
+        ]
+      }
+    ],
+    "/frontend/ios": [
+      {
+        "text": "iOS",
+        "items": [
+          {
+            "text": "apple-update-cert",
+            "link": "frontend/ios/apple-update-cert.md"
+          },
+          {
+            "text": "appstore-share",
+            "link": "frontend/ios/appstore-share.md"
+          },
+          {
+            "text": "autoPackage-tips",
+            "link": "frontend/ios/autoPackage-tips.md"
+          },
+          {
+            "text": "cocoapods",
+            "link": "frontend/ios/cocoapods.md"
+          },
+          {
+            "text": "download-share",
+            "link": "frontend/ios/download-share.md"
+          },
+          {
+            "text": "flutter",
+            "link": "frontend/ios/flutter.md"
+          },
+          {
+            "text": "framework-share",
+            "link": "frontend/ios/framework-share.md"
+          },
+          {
+            "text": "get-ipa",
+            "link": "frontend/ios/get-ipa.md"
+          },
+          {
+            "text": "im-first",
+            "link": "frontend/ios/im-first.md"
+          },
+          {
+            "text": "image-on-iphone",
+            "link": "frontend/ios/image-on-iphone.md"
+          },
+          {
+            "text": "jailbreak",
+            "link": "frontend/ios/jailbreak.md"
+          },
+          {
+            "text": "lock-share",
+            "link": "frontend/ios/lock-share.md"
+          },
+          {
+            "text": "macro-define",
+            "link": "frontend/ios/macro-define.md"
+          },
+          {
+            "text": "network-share",
+            "link": "frontend/ios/network-share.md"
+          },
+          {
+            "text": "note-share",
+            "link": "frontend/ios/note-share.md"
+          },
+          {
+            "text": "post-current-controller",
+            "link": "frontend/ios/post-current-controller.md"
+          },
+          {
+            "text": "post-dispatch-group",
+            "link": "frontend/ios/post-dispatch-group.md"
+          },
+          {
+            "text": "post-facebook-share",
+            "link": "frontend/ios/post-facebook-share.md"
+          },
+          {
+            "text": "post-instagram-share",
+            "link": "frontend/ios/post-instagram-share.md"
+          },
+          {
+            "text": "post-twitter-share",
+            "link": "frontend/ios/post-twitter-share.md"
+          },
+          {
+            "text": "post-view-tips",
+            "link": "frontend/ios/post-view-tips.md"
+          },
+          {
+            "text": "post-whatsapp-share",
+            "link": "frontend/ios/post-whatsapp-share.md"
+          },
+          {
+            "text": "reactnative",
+            "link": "frontend/ios/reactnative.md"
+          },
+          {
+            "text": "url-codeing",
+            "link": "frontend/ios/url-codeing.md"
+          },
+          {
+            "text": "version-share",
+            "link": "frontend/ios/version-share.md"
+          },
+          {
+            "text": "webScoket",
+            "link": "frontend/ios/webScoket.md"
+          },
+          {
+            "text": "webview-share",
+            "link": "frontend/ios/webview-share.md"
+          },
+          {
+            "text": "xcode build",
+            "link": "frontend/ios/xcode build.md"
+          }
+        ]
+      }
+    ],
+    "/frontend/swift": [
+      {
+        "text": "swift",
+        "items": [
+          {
+            "text": "01-Getting Started",
+            "collapsible": true,
+            "items": [
+              {
+                "text": "Basic Setup",
+                "link": "frontend/swift/01-Getting Started/Basic Setup.md"
+              }
+            ]
+          },
+          {
+            "text": "02-Interoperability",
+            "collapsible": true,
+            "items": [
+              {
+                "text": "01-Interacting with Objective-C APIs",
+                "link": "frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md"
+              },
+              {
+                "text": "02-Writing Swift Classes and Protocols with Objective-C Behavior",
+                "link": "frontend/swift/02-Interoperability/02-Writing Swift Classes and Protocols with Objective-C Behavior.md"
+              },
+              {
+                "text": "03-Working with Cocoa Frameworks",
+                "link": "frontend/swift/02-Interoperability/03-Working with Cocoa Frameworks.md"
+              },
+              {
+                "text": "04-Adopting Cocoa Design Patterns",
+                "link": "frontend/swift/02-Interoperability/04-Adopting Cocoa Design Patterns.md"
+              },
+              {
+                "text": "05-Interacting with C APIs",
+                "link": "frontend/swift/02-Interoperability/05-Interacting with C APIs.md"
+              }
+            ]
+          },
+          {
+            "text": "03-Mix and Match",
+            "collapsible": true,
+            "items": [
+              {
+                "text": "Swift and Objective-C in the Same Project",
+                "link": "frontend/swift/03-Mix and Match/Swift and Objective-C in the Same Project.md"
+              }
+            ]
+          },
+          {
+            "text": "04-Migration",
+            "collapsible": true,
+            "items": [
+              {
+                "text": "Migrating Your Objective-C Code to Swift",
+                "link": "frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md"
+              }
+            ]
+          }
+        ]
+      }
+    ],
+    "/utils": [
+      {
+        "text": "工具",
+        "items": [
+          {
+            "text": "Xcode 使用小技巧",
+            "link": "/utils/2016-03-28-post-xcode-tips.md"
+          },
+          {
+            "text": "Xcode 使用小技巧",
+            "link": "/utils/2017-03-28-post-xcode-tips.md"
+          },
+          {
+            "text": "Git 技巧",
+            "link": "/utils/2019-04-15-git-comment.md"
+          }
+        ]
+      }
+    ],
+    "/guide": [
+      {
+        "text": "Markdown 介绍",
+        "items": [
+          {
+            "text": "Markdown 基础语法",
+            "link": "/guide/markdown"
+          },
+          {
+            "text": "Markdown 扩展语法",
+            "link": "/guide/markdown-extension"
+          },
+          {
+            "text": "Markdown 样例",
+            "link": "/guide/markdown-examples"
+          },
+          {
+            "text": "api 样例",
+            "link": "/guide/api-examples"
+          }
+        ]
+      }
+    ],
+    "/network": [
+      {
+        "text": "网络",
+        "items": [
+          {
+            "text": "http网络请求",
+            "link": "/network/https-tips"
+          }
+        ]
+      }
+    ],
+    "/engineering": [
+      {
+        "text": "Examples",
+        "items": [
+          {
+            "text": "Markdown Examples",
+            "link": "/markdown-examples"
+          },
+          {
+            "text": "Runtime API Examples",
+            "link": "/api-examples"
+          }
+        ]
+      }
+    ]
+  },
+  "socialLinks": [
+    {
+      "icon": "github",
+      "link": "https://github.com/feipages"
+    },
+    {
+      "icon": "github",
+      "link": "/guide/profile"
+    }
+  ],
+  "footer": {
+    "copyright": "Copyright © 2017-present Gao Fei",
+    "message": "Released under the MIT License."
+  },
+  "search": {
+    "provider": "local",
+    "options": {
+      "locales": {
+        "root": {
+          "translations": {
+            "button": {
+              "buttonText": "搜索文档",
+              "buttonAriaLabel": "搜索文档"
+            },
+            "modal": {
+              "noResultsText": "无法找到相关结果",
+              "resetButtonTitle": "清除查询条件",
+              "footer": {
+                "selectText": "选择",
+                "navigateText": "切换",
+                "closeText": "关闭"
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}

Page Data

{
+  "title": "Runtime API Examples",
+  "description": "",
+  "frontmatter": {
+    "outline": "deep"
+  },
+  "headers": [],
+  "relativePath": "guide/api-examples.md",
+  "filePath": "guide/api-examples.md"
+}

Page Frontmatter

{
+  "outline": "deep"
+}

More

Check out the documentation for the full list of runtime APIs.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/index.html b/docs/.vitepress/dist/guide/index.html new file mode 100644 index 0000000..2e8c325 --- /dev/null +++ b/docs/.vitepress/dist/guide/index.html @@ -0,0 +1,25 @@ + + + + + + markdown 语法 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/markdown-examples.html b/docs/.vitepress/dist/guide/markdown-examples.html new file mode 100644 index 0000000..fc2225f --- /dev/null +++ b/docs/.vitepress/dist/guide/markdown-examples.html @@ -0,0 +1,57 @@ + + + + + + Markdown Extension Examples | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Markdown Extension Examples

This page demonstrates some of the built-in markdown extensions provided by VitePress.

Syntax Highlighting

VitePress provides Syntax Highlighting powered by Shiki, with additional features like line-highlighting:

Input

md
```js{4}
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}
+```

Output

js
export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}

Custom Containers

Input

md
::: info
+This is an info box.
+:::
+
+::: tip
+This is a tip.
+:::
+
+::: warning
+This is a warning.
+:::
+
+::: danger
+This is a dangerous warning.
+:::
+
+::: details
+This is a details block.
+:::

Output

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

More

Check out the documentation for the full list of markdown extensions.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/markdown-extension.html b/docs/.vitepress/dist/guide/markdown-extension.html new file mode 100644 index 0000000..7c02235 --- /dev/null +++ b/docs/.vitepress/dist/guide/markdown-extension.html @@ -0,0 +1,385 @@ + + + + + + Markdown 扩展 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Markdown 扩展

VitePress 带有内置的 Markdown 扩展。

标题锚点

标题会自动应用锚点。可以使用 markdown.anchor 选项配置锚点的渲染。

自定义锚点

要为标题指定自定义锚点而不是使用自动生成的锚点,请向标题添加后缀:

# 使用自定义锚点 {#my-anchor}

这允许将标题链接为 #my-anchor,而不是默认的 #使用自定义锚点

内部和外部链接都会被特殊处理。

内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 index.md 都会自动转换为 index.html,并带有相应的 URL /

例如,给定以下目录结构:

.
+├─ index.md
+├─ foo
+│  ├─ index.md
+│  ├─ one.md
+│  └─ two.md
+└─ bar
+   ├─ index.md
+   ├─ three.md
+   └─ four.md

假设现在处于 foo/one.md 文件中:

md
[Home](/) <!-- 将用户导航至根目录下的 index.html -->
+[foo](/foo/) <!-- 将用户导航至目录 foo 下的 index.html -->
+[foo heading](./#heading) <!-- 将用户锚定到目录 foo 下的index文件中的一个标题上 -->
+[bar - three](../bar/three) <!-- 可以省略扩展名 -->
+[bar - three](../bar/three.md) <!-- 可以添加 .md -->
+[bar - four](../bar/four.html) <!-- 或者可以添加 .html -->

页面后缀

默认情况下,生成的页面和内部链接带有 .html 后缀。

外部链接带有 target="_blank" rel="noreferrer"

frontmatter

YAML 格式的 frontmatter 开箱即用:

yaml
---
+title: Blogging Like a Hacker
+lang: en-US
+---

此数据将可用于页面的其余部分,以及所有自定义和主题组件。

GitHub 风格的表格

输入

| Tables        |      Are      |  Cool |
+| ------------- | :-----------: | ----: |
+| col 3 is      | right-aligned | $1600 |
+| col 2 is      |   centered    |   $12 |
+| zebra stripes |   are neat    |    $1 |

输出

TablesAreCool
col 3 isright-aligned$1600
col 2 iscentered$12
zebra stripesare neat$1

Emoji 🎉

输入

:tada: :100:

输出

🎉 💯

这里可以找到所有支持的 emoji 列表

目录表 (TOC)

输入

[[toc]]

输出

可以使用 markdown.toc 选项配置 TOC 的呈现效果。

自定义容器

自定义容器可以通过它们的类型、标题和内容来定义。

默认标题

输入

md
::: info
+This is an info box.
+:::
+
+::: tip
+This is a tip.
+:::
+
+::: warning
+This is a warning.
+:::
+
+::: danger
+This is a dangerous warning.
+:::
+
+::: details
+This is a details block.
+:::

输出

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

自定义标题

可以通过在容器的 "type" 之后附加文本来设置自定义标题。

输入

md
::: danger STOP
+危险区域,请勿继续
+:::
+
+::: details 点我查看代码
+```js
+console.log('Hello, VitePress!')
+```
+:::

输出

STOP

危险区域,请勿继续

点我查看代码
js
console.log('Hello, VitePress!')

此外,可以通过在站点配置中添加以下内容来全局设置自定义标题,如果不是用英语书写,这会很有帮助:

ts
// config.ts
+export default defineConfig({
+  // ...
+  markdown: {
+    container: {
+      tipLabel: '提示',
+      warningLabel: '警告',
+      dangerLabel: '危险',
+      infoLabel: '信息',
+      detailsLabel: '详细信息'
+    }
+  }
+  // ...
+})

raw

这是一个特殊的容器,可以用来防止与 VitePress 的样式和路由冲突。这在记录组件库时特别有用。可能还想查看 whyframe 以获得更好的隔离。

语法

md
::: raw
+Wraps in a `<div class="vp-raw">`
+:::

vp-raw class 也可以直接用于元素。样式隔离目前是可选的:

  • 使用喜欢的包管理器来安装需要的依赖项:

    sh
    $ npm add -D postcss
  • 创建 docs/postcss.config.mjs 文件并将以下内容添加到其中:

    js
    import { postcssIsolateStyles } from 'vitepress'
    +
    +export default {
    +  plugins: [postcssIsolateStyles()]
    +}

    它在底层使用 postcss-prefix-selector。你可以像这样传递它的选项:

    js
    postcssIsolateStyles({
    +  includeFiles: [/vp-doc\.css/] // 默认为 /base\.css/
    +})

GitHub 风格的警报

VitePress 同样支持以标注的方式渲染 GitHub 风格的警报。它们和自定义容器的渲染方式相同。

md
> [!NOTE]
+> 强调用户在快速浏览文档时也不应忽略的重要信息。
+
+> [!TIP]
+> 有助于用户更顺利达成目标的建议性信息。
+
+> [!IMPORTANT]
+> 对用户达成目标至关重要的信息。
+
+> [!WARNING]
+> 因为可能存在风险,所以需要用户立即关注的关键内容。
+
+> [!CAUTION]
+> 行为可能带来的负面影响。

NOTE

强调用户在快速浏览文档时也不应忽略的重要信息。

TIP

有助于用户更顺利达成目标的建议性信息。

IMPORTANT

对用户达成目标至关重要的信息。

WARNING

因为可能存在风险,所以需要用户立即关注的关键内容。

CAUTION

行为可能带来的负面影响。

代码块中的语法高亮

VitePress 使用 Shiki 在 Markdown 代码块中使用彩色文本实现语法高亮。Shiki 支持多种编程语言。需要做的就是将有效的语言别名附加到代码块的开头:

输入

```js
+export default {
+  name: 'MyComponent',
+  // ...
+}
+```
```html
+<ul>
+  <li v-for="todo in todos" :key="todo.id">
+    {{ todo.text }}
+  </li>
+</ul>
+```

输出

js
export default {
+  name: 'MyComponent'
+  // ...
+}
html
<ul>
+  <li v-for="todo in todos" :key="todo.id">
+    {{ todo.text }}
+  </li>
+</ul>

在 Shiki 的代码仓库中,可以找到合法的编程语言列表

在代码块中实现行高亮

输入

```js{4}
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}
+```

输出

js
export default {
+  data () {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}

除了单行之外,还可以指定多个单行、多行,或两者均指定:

  • 多行:例如 {5-8}{3-10}{10-17}
  • 多个单行:例如 {4,7,9}
  • 多行与单行:例如 {4,7-13,16,23-27,40}

输入

```js{1,4,6-8}
+export default { // Highlighted
+  data () {
+    return {
+      msg: `Highlighted!
+      This line isn't highlighted,
+      but this and the next 2 are.`,
+      motd: 'VitePress is awesome',
+      lorem: 'ipsum'
+    }
+  }
+}
+```

输出

js
export default { // Highlighted
+  data () {
+    return {
+      msg: `Highlighted!
+      This line isn't highlighted,
+      but this and the next 2 are.`,
+      motd: 'VitePress is awesome',
+      lorem: 'ipsum',
+    }
+  }
+}

也可以使用 // [!code highlight] 注释实现行高亮。

输入

```js
+export default {
+  data () {
+    return {
+      msg: 'Highlighted!' // [!!code highlight]
+    }
+  }
+}
+```

输出

js
export default {
+  data() {
+    return {
+      msg: 'Highlighted!'
+    }
+  }
+}

代码块中聚焦

在某一行上添加 // [!code focus] 注释将聚焦它并模糊代码的其他部分。

此外,可以使用 // [!code focus:<lines>] 定义要聚焦的行数。

输入

```js
+export default {
+  data () {
+    return {
+      msg: 'Focused!' // [!!code focus]
+    }
+  }
+}
+```

输出

js
export default {
+  data() {
+    return {
+      msg: 'Focused!'
+    }
+  }
+}

代码块中的颜色差异

在某一行添加 // [!code --]// [!code ++] 注释将会为该行创建 diff,同时保留代码块的颜色。

输入

```js
+export default {
+  data () {
+    return {
+      msg: 'Removed' // [!!code --]
+      msg: 'Added' // [!!code ++]
+    }
+  }
+}
+```

输出

js
export default {
+  data () {
+    return {
+      msg: 'Removed'
+      msg: 'Added'
+    }
+  }
+}

高亮“错误”和“警告”

在某一行添加 // [!code warning]// [!code error] 注释将会为该行相应的着色。

输入

```js
+export default {
+  data () {
+    return {
+      msg: 'Error', // [!!code error]
+      msg: 'Warning' // [!!code warning]
+    }
+  }
+}
+```

输出

js
export default {
+  data() {
+    return {
+      msg: 'Error', 
+      msg: 'Warning'
+    }
+  }
+}

行号

可以通过以下配置为每个代码块启用行号:

js
export default {
+  markdown: {
+    lineNumbers: true
+  }
+}

可以在代码块中添加 :line-numbers / :no-line-numbers 标记来覆盖在配置中的设置。

还可以通过在 :line-numbers 之后添加 = 来自定义起始行号,例如 :line-numbers=2 表示代码块中的行号从 2 开始。

输入

md
```ts {1}
+// 默认禁用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
+```
+
+```ts:line-numbers {1}
+// 启用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
+```
+
+```ts:line-numbers=2 {1}
+// 行号已启用,并从 2 开始
+const line3 = 'This is line 3'
+const line4 = 'This is line 4'
+```

输出

ts
// 默认禁用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
ts
// 启用行号
+const line2 = 'This is line 2'
+const line3 = 'This is line 3'
ts
// 行号已启用,并从 2 开始
+const line3 = 'This is line 3'
+const line4 = 'This is line 4'

导入代码片段

可以通过下面的语法来从现有文件中导入代码片段:

md
<<< @/filepath

此语法同时支持行高亮

md
<<< @/filepath{highlightLines}

输入

md
<<< @/snippets/snippet.js{2}

Code file

js
export default function () {
+  // ..
+}

输出

js
export default function () {
+  // ..
+}

TIP

@ 的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 srcDir。或者也可以从相对路径导入:

md
<<< ../snippets/snippet.js

也可以使用 VS Code region 来只包含代码文件的相应部分。可以在文件目录后面的 # 符号后提供一个自定义的区域名:

输入

md
<<< @/snippets/snippet-with-region.js#snippet{1}

Code file

js
// #region snippet
+function foo() {
+  // ..
+}
+// #endregion snippet
+
+export default foo

输出

js
function foo() {
+  // ..
+}

也可以像这样在大括号内({})指定语言:

md
<<< @/snippets/snippet.cs{c#}
+
+<!-- 带行高亮: -->
+
+<<< @/snippets/snippet.cs{1,2,4-6 c#}
+
+<!-- 带行号: -->
+
+<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers}

如果无法从文件扩展名推测出源语言,这将会很有帮助

代码组

可以像这样对多个代码块进行分组:

输入

md
::: code-group
+
+```js [config.js]
+/**
+ * @type {import('vitepress').UserConfig}
+ */
+const config = {
+  // ...
+}
+
+export default config
+```
+
+```ts [config.ts]
+import type { UserConfig } from 'vitepress'
+
+const config: UserConfig = {
+  // ...
+}
+
+export default config
+```
+
+:::

输出

js
/**
+ * @type {import('vitepress').UserConfig}
+ */
+const config = {
+  // ...
+}
+
+export default config
ts
import type { UserConfig } from 'vitepress'
+
+const config: UserConfig = {
+  // ...
+}
+
+export default config

也可以在代码组中导入代码片段

输入

md
::: code-group
+
+<!-- 文件名默认用作标题 -->
+
+<<< @/snippets/snippet.js
+
+<!-- 也可以提供定制的代码组 -->
+
+<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region]
+
+:::

输出

js
export default function () {
+  // ..
+}
ts
function foo() {
+  // ..
+}

包含 markdown 文件

可以像这样在一个 markdown 文件中包含另一个 markdown 文件,甚至是内嵌的。

TIP

也可以使用 @,它的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 srcDir

例如,可以这样用相对路径包含 Markdown 文件:

输入

md
# Docs
+
+## Basics
+
+<!--@include: ./parts/basics.md-->

Part file (parts/basics.md)

md
Some getting started stuff.
+
+### Configuration
+
+Can be created using `.foorc.json`.

等价代码

md
# Docs
+
+## Basics
+
+Some getting started stuff.
+
+### Configuration
+
+Can be created using `.foorc.json`.

它还支持选择行范围:

输入

md
# Docs
+
+## Basics
+
+<!--@include: ./parts/basics.md{3,}-->

Part file (parts/basics.md)

md
Some getting started stuff.
+
+### Configuration
+
+Can be created using `.foorc.json`.

等价代码

md
# Docs
+
+## Basics
+
+### Configuration
+
+Can be created using `.foorc.json`.

所选行范围的格式可以是: {3,}{,10}{1,10}

WARNING

如果指定的文件不存在,这将不会产生错误。因此,在使用这个功能的时候请保证内容按预期呈现。

数学方程

现在这是可选的。要启用它,需要安装 markdown-it-mathjax3,在配置文件中设置markdown.mathtrue

sh
npm add -D markdown-it-mathjax3
ts
export default {
+  markdown: {
+    math: true
+  }
+}

输入

md
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
+$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
+
+**Maxwell's equations:**
+
+| equation                                                                                                                                                                  | description                                                                            |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
+| $\nabla \cdot \vec{\mathbf{B}}  = 0$                                                                                                                                      | divergence of $\vec{\mathbf{B}}$ is zero                                               |
+| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t}  = \vec{\mathbf{0}}$                                                          | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
+| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}}    \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_                                                                                 |

输出

When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are $$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$

Maxwell's equations:

equationdescription
$\nabla \cdot \vec{\mathbf{B}} = 0$divergence of $\vec{\mathbf{B}}$ is zero
$\nabla \times \vec{\mathbf{E}}, +, \frac1c, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$
$\nabla \times \vec{\mathbf{B}} -, \frac1c, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$wha?

图片懒加载

通过在配置文件中将 lazyLoading 设置为 true,可以为通过 markdown 添加的每张图片启用懒加载。

js
export default {
+  markdown: {
+    image: {
+      // 默认禁用;设置为 true 可为所有图片启用懒加载。
+      lazyLoading: true
+    }
+  }
+}

高级配置

VitePress 使用 markdown-it 作为 Markdown 渲染器。上面提到的很多扩展功能都是通过自定义插件实现的。可以使用 .vitepress/config.js 中的 markdown 选项来进一步自定义 markdown-it 实例。

js
import { defineConfig } from 'vitepress'
+import markdownItAnchor from 'markdown-it-anchor'
+import markdownItFoo from 'markdown-it-foo'
+
+export default defineConfig({
+  markdown: {
+    // markdown-it-anchor 的选项
+    // https://github.com/valeriangalliat/markdown-it-anchor#usage
+    anchor: {
+      permalink: markdownItAnchor.permalink.headerLink()
+    },
+    // @mdit-vue/plugin-toc 的选项
+    // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
+    toc: { level: [1, 2] },
+    config: (md) => {
+      // 使用更多的 Markdown-it 插件!
+      md.use(markdownItFoo)
+    }
+  }
+})

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/markdown.html b/docs/.vitepress/dist/guide/markdown.html new file mode 100644 index 0000000..95001f6 --- /dev/null +++ b/docs/.vitepress/dist/guide/markdown.html @@ -0,0 +1,84 @@ + + + + + + Markdown基础语法 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Markdown基础语法

本文介绍markdown语法。部分语法为非标准语法,为GitHub对markdown的扩充语法,称之为GitHub Flavored Markdown。简称GFM,大家在使用过程中注意验证。

目录

横线


***、---、___可以显示横线效果




标题

# 一级标题
+## 二级标题
+### 三级标题
+#### 四级标题
+##### 五级标题
+###### 六级标题

效果如下:

一级标题

二级标题

三级标题

四级标题

五级标题
六级标题

文本

普通文本

这是一段普通的文本

单行文本

Hello,大家好,我是果冻虾仁。
+

在一行开头加入1个Tab或者4个空格。

文本块

语法1

在连续几行的文本开头加入1个Tab或者4个空格。

欢迎到访
+很高兴见到您
+祝您,早上好,中午好,下午好,晚安
+

语法2

使用一对各三个的反引号:

欢迎到访
+我是前端码农
+你可以在github上搜索【feipages】找到我

该语法也可以实现代码高亮,见代码高亮

文字高亮

文字高亮功能能使行内部分文字高亮,使用一对反引号。 语法:

`linux` `网络编程` `socket` `epoll`

效果:linux 网络编程 socket epoll

也适合做一篇文章的tag

换行

直接回车不能换行, 可以在上一行文本后面补两个空格, 这样下一行的文本就换行了。

或者就是在两行文本直接加一个空行。

也能实现换行效果,不过这个行间距有点大。

斜体、粗体、删除线

语法效果
*斜体1*斜体1
_斜体2_斜体2
**粗体1**粗体1
__粗体2__粗体2
这是一个 ~~删除线~~这是一个 删除线
***斜粗体1***斜粗体1
___斜粗体2___斜粗体2
***~~斜粗体删除线1~~***斜粗体删除线1
~~***斜粗体删除线2***~~斜粗体删除线2
斜体、粗体、删除线可混合使用
+

图片

基本格式:

![alt](URL title)

alt和title即对应HTML中的alt和title属性(都可省略):

  • alt表示图片显示失败时的替换文本
  • title表示鼠标悬停在图片时的显示文本(注意这里要加引号)

URL即图片的url地址,如果引用本仓库中的图片,直接使用相对路径就可了,如果引用其他github仓库中的图片要注意格式,即:仓库地址/raw/分支名/图片路径,如:

https://github.com/guodongxiaren/ImageCache/raw/master/Logo/foryou.gif
#语法效果
1![baidu](http://www.baidu.com/img/bdlogo.gif "百度logo")baidu

注意例2的写法使用了URL标识符的形式,在链接一节有介绍。

在文末有code-past的定义:

[code-past]:/img/favicon.ico "收藏"

链接

链接外部URL

#语法效果
1[必应](https://www.bing.com "悬停显示")必应

语法2由两部分组成:

  • 第一部分使用两个中括号,[ ]里的标识符(本例中zhihu),可以是数字,字母等的组合,标识符上下对应就行了(姑且称之为URL标识符
  • 第二部分标记实际URL。

使用URL标识符能达到复用的目的,一般把全文所有的URL标识符统一放在文章末尾,这样看起来比较干净。除了干净之外,它还能达到复用的目的,比如你在多个地方想使用同一个链接,那么文内使用标识符,只在最底部给标识符定义出实际的URL链接即可,类似编程语言中的变量。

URL标识符是我起的名字,不知道是否准确。囧。。

链接本仓库里的URL

语法效果
[我的简介](/example/profile.md)我的简介

图片链接

给图片加链接的本质是混合图片显示语法和普通的链接语法。普通的链接中[ ]内部是链接要显示的文本,而图片链接[ ]里面则是要显示的图片。 直接混合两种语法当然可以,但是十分啰嗦,为此我们可以使用URL标识符的形式。

#语法效果
1[![](/img/zhihu.png "我的知乎,欢迎关注")][zhihu][][zhihu]

因为图片本身和链接本身都支持URL标识符的形式,所以图片链接也可以很简洁(见例3)。 注意,此时鼠标悬停时显示的文字是图片的title,而非链接本身的title了。

本文URL标识符都放置于文末

锚点

其实呢,每一个标题都是一个锚点,和HTML的锚点(#)类似,比如我们

语法效果
[回到顶部](#readme)回到顶部

不过要注意,标题中的英文字母都被转化为小写字母了。

以前GitHub对中文支持的不好,所以中文标题不能正确识别为锚点,但是现在已经没问题啦!

列表

无序列表

语法

* 昵称:果冻虾仁
+- 别名:隔壁老王
+* 英文名:Jelly

效果

  • 昵称:果冻虾仁
  • 别名:隔壁老王
  • 英文名:Jelly

多级无序列表

语法

* 编程语言
+    * 脚本语言
+        * Python

效果

  • 编程语言
    • 脚本语言
      • Python

一级有序列表

语法

就是在数字后面加一个点,再加一个空格。不过看起来起来可能不够明显。

面向对象的三个基本特征:
+
+1. 封装
+2. 继承
+3. 多态

效果

面向对象的三个基本特征:

  1. 封装
  2. 继承
  3. 多态

多级有序列表

和无序列表一样,有序列表也有多级结构。

语法

1. 这是一级的有序列表,数字1还是1
+   1. 这是二级的有序列表,阿拉伯数字在显示的时候变成了罗马数字
+      1. 这是三级的有序列表,数字在显示的时候变成了英文字母

效果

  1. 这是一级的有序列表,数字1还是1
    1. 这是二级的有序列表,阿拉伯数字在显示的时候变成了罗马数字
      1. 这是三级的有序列表,数字在显示的时候变成了英文字母

复选框列表

语法

- [x] 需求分析
+- [x] 系统设计
+- [x] 详细设计
+- [ ] 编码
+- [ ] 测试
+- [ ] 交付

效果

  • [x] 需求分析
  • [x] 系统设计
  • [x] 详细设计
  • [ ] 编码
  • [ ] 测试
  • [ ] 交付

您可以使用这个功能来标注某个项目各项任务的完成情况。

Tip:

在GitHub的issue中使用该语法是可以实时点击复选框来勾选或解除勾选的,而无需修改issue原文。

块引用

常用于引用文本

文本摘自《深入理解计算机系统》P27

令人吃惊的是,在哪种字节顺序是合适的这个问题上,人们表现得非常情绪化。实际上术语“little endian”(小端)和“big endian”(大端)出自Jonathan Swift的《格利佛游记》一书,其中交战的两个派别无法就应该从哪一端打开一个半熟的鸡蛋达成一致。因此,争论沦为关于社会政治的争论。只要选择了一种规则并且始终如一的坚持,其实对于哪种字节排序的选择都是任意的。

“端”(endian)的起源 以下是Jonathan Swift在1726年关于大小端之争历史的描述: “……下面我要告诉你的是,Lilliput和Blefuscu这两大强国在过去36个月里一直在苦战。战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今的皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了,因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破较小的一端,违令者重罚。”

块引用有多级结构

语法

> 数据结构
+>> 树
+>>> 二叉树
+>>>> 平衡二叉树
+>>>>> 满二叉树

效果

数据结构

二叉树

平衡二叉树

满二叉树

代码高亮

语法

在三个反引号```后面加上编程语言的名字(比如javascipt),另起一行开始写代码,最后一行再加上三个反引号```。

效果

Java
public static void main(String[]args){} //Java
c
int main(int argc, char *argv[]) //C
Bash
echo "hello GitHub" #Bash
javascript
document.getElementById("myH1").innerHTML="Welcome to my Homepage"; //javascipt
cpp
string &operator+(const string& A,const string& B) //cpp

表格

基本语法:

| 表头1  | 表头2|
+| ---------- | -----------|
+| 表格单元   | 表格单元   |
+| 表格单元   | 表格单元   |
表头1表头2
表格单元表格单元
表格单元表格单元

简洁语法:

表头1  | 表头2|
+--------- | --------|
+表格单元  | 表格单元 |
+表格单元  | 表格单元 |
表头1表头2
表格单元表格单元
表格单元表格单元

对齐

表格可以指定对齐方式

| 左对齐 | 居中  | 右对齐 |
+| :------------ |:---------------:| -----:|
+| col 3 is      | some wordy text | $1600 |
+| col 2 is      | centered        |   $12 |
+| zebra stripes | are neat        |    $1 |
左对齐居中右对齐
col 3 issome wordy text$1600
col 2 iscentered$12
zebra stripesare neat$1

混合其他语法

表格单元中的内容可以和其他大多数GFM语法配合使用,如:

使用普通文本的删除线,斜体等效果

名字描述
HelpDisplay the help window.
CloseCloses a window

表格中嵌入图片(链接)

其实前面介绍图片显示、图片链接的时候为了清晰就是放在在表格中显示的。

图片描述
![baidu][baidu-logo]百度

diff语法

版本控制的系统中都少不了diff的功能,即展示一个文件内容的增加与删除。 GFM中可以显示的展示diff效果。使用绿色表示新增,红色表示删除。

语法

其语法与代码高亮类似,只是在三个反引号后面写diff, 并且其内容中,可以用 + 开头表示新增,- 开头表示删除。 另外还有有 !#的语法。

效果

diff
+ 人闲桂花落,
+- 夜静春山空。
+! 月出惊山鸟,
+# 时鸣春涧中。

常用HTML语法

markdown是支持HTML语法的,虽然不鼓励大量使用HTML语法,毕竟那样就丧失了markdown的意义,但是有一些HTML语法在写README的时候是很少的补充。

折叠

<details>
+<summary>Linux环境</summary>
+
+##### 编译
+xxxx
+
+##### 安装
+xxxx
+</details>
Linux环境
编译

xxxx

安装

xxxx

居中

很多地方都会用到居中的效果,比如如下内容将会把一个表格在页面中居中展示:

<div align="center">
+
+| 表头1  | 表头2|
+| ---------- | -----------|
+| 表格单元   | 表格单元   |
+| 表格单元   | 表格单元   |
+
+</div>
表头1表头2
表格单元表格单元
表格单元表格单元

其他任意需要居中展示的语法,都可以放在其中。

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/guide/profile.html b/docs/.vitepress/dist/guide/profile.html new file mode 100644 index 0000000..fb8921b --- /dev/null +++ b/docs/.vitepress/dist/guide/profile.html @@ -0,0 +1,25 @@ + + + + + + 简介 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/hashmap.json b/docs/.vitepress/dist/hashmap.json index c9255be..4cabca0 100644 --- a/docs/.vitepress/dist/hashmap.json +++ b/docs/.vitepress/dist/hashmap.json @@ -1 +1 @@ -{"api-examples.md":"B__5zNjv","index.md":"6FSCG9lU","markdown-examples.md":"DX_lK_aG"} +{"backend_container_tomcat.md":"Dg9oMqSB","backend_release_maven-first.md":"fbrMtubv","engineering_index.md":"B2wQBafC","frontend_base_xml-tips.md":"CjgTKY38","frontend_ios_apple-update-cert.md":"4HxgwTte","frontend_ios_appstore-share.md":"B_qI_911","frontend_ios_autopackage-tips.md":"COCidwNT","frontend_ios_cocoapods.md":"Bbev3CRS","frontend_ios_download-share.md":"r3iHDhjb","frontend_ios_flutter.md":"DFpOWWZg","frontend_ios_framework-share.md":"K-VOmPO9","frontend_ios_get-ipa.md":"Cj8aHUTQ","frontend_ios_im-first.md":"C0UI8p3Z","frontend_ios_image-on-iphone.md":"BLfaLcNU","frontend_ios_index.md":"CTrSx6HD","frontend_ios_jailbreak.md":"CZwC3MmJ","frontend_ios_lock-share.md":"CQLBBqsy","frontend_ios_macro-define.md":"DnhUoQxo","frontend_ios_network-share.md":"BvSwKl10","frontend_ios_note-share.md":"pMsyM96B","frontend_ios_post-current-controller.md":"B-9NYLT_","frontend_ios_post-dispatch-group.md":"BPC5tDy_","frontend_ios_post-facebook-share.md":"o1afdPes","frontend_ios_post-instagram-share.md":"CmIhBWP1","frontend_ios_post-twitter-share.md":"D8KqUT6F","frontend_ios_post-view-tips.md":"CEBmkpZm","frontend_ios_post-whatsapp-share.md":"DXPe5cbb","frontend_ios_reactnative.md":"MxIQB3HJ","frontend_ios_url-codeing.md":"BiysPrsl","frontend_ios_version-share.md":"CPKtn0IM","frontend_ios_webscoket.md":"D5yGxqO5","frontend_ios_webview-share.md":"BNnvsgQ0","frontend_ios_xcode build.md":"D8nyWHzf","frontend_js_index.md":"DIBkZ4Z0","frontend_other_2020-03-12-ionic.md":"5dqZ3YTS","frontend_other_2020-03-22-angular.md":"BZyIkX6a","frontend_other_index.md":"C6cSlaNs","frontend_swift_01-getting started_basic setup.md":"BLffIB_N","frontend_swift_02-interoperability_01-interacting with objective-c apis.md":"CgyRJN7j","frontend_swift_02-interoperability_02-writing swift classes and protocols with objective-c behavior.md":"DiA-b_2v","frontend_swift_02-interoperability_03-working with cocoa frameworks.md":"BVm4Kcn8","frontend_swift_02-interoperability_04-adopting cocoa design patterns.md":"B1zZGYT6","frontend_swift_02-interoperability_05-interacting with c apis.md":"B7qyAuun","frontend_swift_03-mix and match_swift and objective-c in the same project.md":"B8DxxDli","frontend_swift_04-migration_migrating your objective-c code to swift.md":"3nq7zSnw","frontend_swift_index.md":"DLsK_7-d","frontend_vue_index.md":"CSegZYxX","guide_about.md":"C8JydTFK","guide_api-examples.md":"DrTxPAI1","guide_index.md":"jxbnF1tf","guide_markdown-examples.md":"DaMNxmUN","guide_markdown-extension.md":"CbXUJjX7","guide_markdown.md":"B6cbd7BH","guide_profile.md":"D2-043_-","index.md":"bEuRoy2r","network_https-tips.md":"DbPLWUZ9","network_index.md":"yKg90t4v","readme.zh.md":"CUr6FBXy","utils_git-tips.md":"Cst2ESAN","utils_mac-tips.md":"BSmTDcFx","utils_xcode-tips.md":"D-lHTeox"} diff --git a/docs/.vitepress/dist/img/404-bg.jpg b/docs/.vitepress/dist/img/404-bg.jpg new file mode 100755 index 0000000..c2ee242 Binary files /dev/null and b/docs/.vitepress/dist/img/404-bg.jpg differ diff --git a/docs/.vitepress/dist/img/about-bg-o.jpg b/docs/.vitepress/dist/img/about-bg-o.jpg new file mode 100755 index 0000000..89b476b Binary files /dev/null and b/docs/.vitepress/dist/img/about-bg-o.jpg differ diff --git a/docs/.vitepress/dist/img/about-bg.jpg b/docs/.vitepress/dist/img/about-bg.jpg new file mode 100755 index 0000000..d8a6a14 Binary files /dev/null and b/docs/.vitepress/dist/img/about-bg.jpg differ diff --git a/docs/.vitepress/dist/img/apple/1-1.png b/docs/.vitepress/dist/img/apple/1-1.png new file mode 100644 index 0000000..a0eb3e2 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/1-1.png differ diff --git a/docs/.vitepress/dist/img/apple/2-1-0.png b/docs/.vitepress/dist/img/apple/2-1-0.png new file mode 100644 index 0000000..01d09f1 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-1-0.png differ diff --git a/docs/.vitepress/dist/img/apple/2-1-1.png b/docs/.vitepress/dist/img/apple/2-1-1.png new file mode 100644 index 0000000..f31a1c2 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-1-1.png differ diff --git a/docs/.vitepress/dist/img/apple/2-1-2.png b/docs/.vitepress/dist/img/apple/2-1-2.png new file mode 100644 index 0000000..a6e7973 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-1-2.png differ diff --git a/docs/.vitepress/dist/img/apple/2-1-3.png b/docs/.vitepress/dist/img/apple/2-1-3.png new file mode 100644 index 0000000..c9c4439 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-1-3.png differ diff --git a/docs/.vitepress/dist/img/apple/2-1-4.png b/docs/.vitepress/dist/img/apple/2-1-4.png new file mode 100644 index 0000000..69898d5 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-1-4.png differ diff --git a/docs/.vitepress/dist/img/apple/2-2-1.png b/docs/.vitepress/dist/img/apple/2-2-1.png new file mode 100644 index 0000000..b2a4a8b Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-2-1.png differ diff --git a/docs/.vitepress/dist/img/apple/2-2-2.png b/docs/.vitepress/dist/img/apple/2-2-2.png new file mode 100644 index 0000000..5803756 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-2-2.png differ diff --git a/docs/.vitepress/dist/img/apple/2-2-3.png b/docs/.vitepress/dist/img/apple/2-2-3.png new file mode 100644 index 0000000..df10428 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-2-3.png differ diff --git a/docs/.vitepress/dist/img/apple/2-2-4.png b/docs/.vitepress/dist/img/apple/2-2-4.png new file mode 100644 index 0000000..edcc1e3 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-2-4.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-0.png b/docs/.vitepress/dist/img/apple/2-3-0.png new file mode 100644 index 0000000..a0685ea Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-0.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-1.png b/docs/.vitepress/dist/img/apple/2-3-1.png new file mode 100644 index 0000000..ade0ca4 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-1.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-2.png b/docs/.vitepress/dist/img/apple/2-3-2.png new file mode 100644 index 0000000..6703599 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-2.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-3.png b/docs/.vitepress/dist/img/apple/2-3-3.png new file mode 100644 index 0000000..25b8d71 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-3.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-4.png b/docs/.vitepress/dist/img/apple/2-3-4.png new file mode 100644 index 0000000..736c742 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-4.png differ diff --git a/docs/.vitepress/dist/img/apple/2-3-5.png b/docs/.vitepress/dist/img/apple/2-3-5.png new file mode 100644 index 0000000..c8bf9a1 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-3-5.png differ diff --git a/docs/.vitepress/dist/img/apple/2-4-1.png b/docs/.vitepress/dist/img/apple/2-4-1.png new file mode 100644 index 0000000..4fe4d92 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-4-1.png differ diff --git a/docs/.vitepress/dist/img/apple/2-4-2.png b/docs/.vitepress/dist/img/apple/2-4-2.png new file mode 100644 index 0000000..b1fd878 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-4-2.png differ diff --git a/docs/.vitepress/dist/img/apple/2-4-3.png b/docs/.vitepress/dist/img/apple/2-4-3.png new file mode 100644 index 0000000..b8fbad0 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-4-3.png differ diff --git a/docs/.vitepress/dist/img/apple/2-4-4.png b/docs/.vitepress/dist/img/apple/2-4-4.png new file mode 100644 index 0000000..d478ea1 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-4-4.png differ diff --git a/docs/.vitepress/dist/img/apple/2-4-5.png b/docs/.vitepress/dist/img/apple/2-4-5.png new file mode 100644 index 0000000..8f4dd0d Binary files /dev/null and b/docs/.vitepress/dist/img/apple/2-4-5.png differ diff --git a/docs/.vitepress/dist/img/apple/3-1-1.png b/docs/.vitepress/dist/img/apple/3-1-1.png new file mode 100644 index 0000000..b780a74 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/3-1-1.png differ diff --git a/docs/.vitepress/dist/img/apple/3-1-2.png b/docs/.vitepress/dist/img/apple/3-1-2.png new file mode 100644 index 0000000..e71a7be Binary files /dev/null and b/docs/.vitepress/dist/img/apple/3-1-2.png differ diff --git a/docs/.vitepress/dist/img/apple/3-1-3.png b/docs/.vitepress/dist/img/apple/3-1-3.png new file mode 100644 index 0000000..507456f Binary files /dev/null and b/docs/.vitepress/dist/img/apple/3-1-3.png differ diff --git a/docs/.vitepress/dist/img/apple/3-1-4.png b/docs/.vitepress/dist/img/apple/3-1-4.png new file mode 100644 index 0000000..57222ec Binary files /dev/null and b/docs/.vitepress/dist/img/apple/3-1-4.png differ diff --git a/docs/.vitepress/dist/img/apple/3-2.png b/docs/.vitepress/dist/img/apple/3-2.png new file mode 100644 index 0000000..3f73bf3 Binary files /dev/null and b/docs/.vitepress/dist/img/apple/3-2.png differ diff --git a/docs/.vitepress/dist/img/avatar-fei.jpg b/docs/.vitepress/dist/img/avatar-fei.jpg new file mode 100644 index 0000000..e1d1706 Binary files /dev/null and b/docs/.vitepress/dist/img/avatar-fei.jpg differ diff --git a/docs/.vitepress/dist/img/avatar-hux-home.jpg b/docs/.vitepress/dist/img/avatar-hux-home.jpg new file mode 100644 index 0000000..e1d1706 Binary files /dev/null and b/docs/.vitepress/dist/img/avatar-hux-home.jpg differ diff --git a/docs/.vitepress/dist/img/blog-desktop.jpg b/docs/.vitepress/dist/img/blog-desktop.jpg new file mode 100644 index 0000000..9a26c88 Binary files /dev/null and b/docs/.vitepress/dist/img/blog-desktop.jpg differ diff --git a/docs/.vitepress/dist/img/blog-keynote.jpg b/docs/.vitepress/dist/img/blog-keynote.jpg new file mode 100755 index 0000000..8f6eb84 Binary files /dev/null and b/docs/.vitepress/dist/img/blog-keynote.jpg differ diff --git a/docs/.vitepress/dist/img/blog-md-navbar.gif b/docs/.vitepress/dist/img/blog-md-navbar.gif new file mode 100755 index 0000000..e4e5b0c Binary files /dev/null and b/docs/.vitepress/dist/img/blog-md-navbar.gif differ diff --git a/docs/.vitepress/dist/img/blog-sidebar.jpg b/docs/.vitepress/dist/img/blog-sidebar.jpg new file mode 100755 index 0000000..2f996c0 Binary files /dev/null and b/docs/.vitepress/dist/img/blog-sidebar.jpg differ diff --git a/docs/.vitepress/dist/img/contact-bg.jpg b/docs/.vitepress/dist/img/contact-bg.jpg new file mode 100755 index 0000000..fb7fad1 Binary files /dev/null and b/docs/.vitepress/dist/img/contact-bg.jpg differ diff --git a/docs/.vitepress/dist/img/csdn.png b/docs/.vitepress/dist/img/csdn.png new file mode 100644 index 0000000..03c3ca3 Binary files /dev/null and b/docs/.vitepress/dist/img/csdn.png differ diff --git a/docs/.vitepress/dist/img/favicon.ico b/docs/.vitepress/dist/img/favicon.ico new file mode 100755 index 0000000..f7baa5f Binary files /dev/null and b/docs/.vitepress/dist/img/favicon.ico differ diff --git a/docs/.vitepress/dist/img/home-bg-art.jpg b/docs/.vitepress/dist/img/home-bg-art.jpg new file mode 100755 index 0000000..89e422a Binary files /dev/null and b/docs/.vitepress/dist/img/home-bg-art.jpg differ diff --git a/docs/.vitepress/dist/img/home-bg-geek.jpg b/docs/.vitepress/dist/img/home-bg-geek.jpg new file mode 100755 index 0000000..b2f8e41 Binary files /dev/null and b/docs/.vitepress/dist/img/home-bg-geek.jpg differ diff --git a/docs/.vitepress/dist/img/home-bg-o.jpg b/docs/.vitepress/dist/img/home-bg-o.jpg new file mode 100755 index 0000000..56d3dd4 Binary files /dev/null and b/docs/.vitepress/dist/img/home-bg-o.jpg differ diff --git a/docs/.vitepress/dist/img/home-bg.jpg b/docs/.vitepress/dist/img/home-bg.jpg new file mode 100755 index 0000000..36b17af Binary files /dev/null and b/docs/.vitepress/dist/img/home-bg.jpg differ diff --git a/docs/.vitepress/dist/img/icon_wechat.png b/docs/.vitepress/dist/img/icon_wechat.png new file mode 100755 index 0000000..f353149 Binary files /dev/null and b/docs/.vitepress/dist/img/icon_wechat.png differ diff --git a/docs/.vitepress/dist/img/in-post/forcify.jpg b/docs/.vitepress/dist/img/in-post/forcify.jpg new file mode 100755 index 0000000..67b4130 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/forcify.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926786938908.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926786938908.jpg new file mode 100644 index 0000000..0018233 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926786938908.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787070447.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787070447.jpg new file mode 100644 index 0000000..f6f582e Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787070447.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787316762.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787316762.jpg new file mode 100644 index 0000000..6c6d964 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787316762.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787446970.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787446970.jpg new file mode 100644 index 0000000..48b5b10 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926787446970.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788159747.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788159747.jpg new file mode 100644 index 0000000..8cbc2bd Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788159747.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788345812.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788345812.jpg new file mode 100644 index 0000000..946bc3a Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788345812.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788445548.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788445548.jpg new file mode 100644 index 0000000..84cb8c5 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788445548.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788538614.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788538614.jpg new file mode 100644 index 0000000..ec76211 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788538614.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788643833.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788643833.jpg new file mode 100644 index 0000000..c75a207 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926788643833.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926791330965.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926791330965.jpg new file mode 100644 index 0000000..652944e Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926791330965.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926792525999.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926792525999.jpg new file mode 100644 index 0000000..6eb438f Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926792525999.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/media/14926785184639/14926813444655.jpg b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926813444655.jpg new file mode 100644 index 0000000..a776bba Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/media/14926785184639/14926813444655.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/open-source-license.png b/docs/.vitepress/dist/img/in-post/open-source-license.png new file mode 100755 index 0000000..fb54c0c Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/open-source-license.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.013.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.013.jpg new file mode 100755 index 0000000..00b12d7 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.013.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.014.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.014.jpg new file mode 100755 index 0000000..d0cd39c Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.014.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.016.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.016.jpg new file mode 100755 index 0000000..174fc40 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.016.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.018.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.018.jpg new file mode 100755 index 0000000..b16f0fd Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.018.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.019.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.019.jpg new file mode 100755 index 0000000..d584d29 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.019.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.020.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.020.jpg new file mode 100755 index 0000000..bf01973 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.020.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.021.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.021.jpg new file mode 100755 index 0000000..f67f02b Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.021.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.023.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.023.jpg new file mode 100755 index 0000000..5cdae7c Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.023.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.026.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.026.jpg new file mode 100755 index 0000000..c4fa75a Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.026.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.028.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.028.jpg new file mode 100755 index 0000000..703d51e Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.028.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.029.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.029.jpg new file mode 100755 index 0000000..fbcbe8a Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.029.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.030.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.030.jpg new file mode 100755 index 0000000..e2a76af Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.030.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.031.jpg b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.031.jpg new file mode 100755 index 0000000..a21ed8f Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-alitrip-pd/post-alitrip-pd.031.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-c-u-ali-079717.png b/docs/.vitepress/dist/img/in-post/post-c-u-ali-079717.png new file mode 100755 index 0000000..2fd624e Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-c-u-ali-079717.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-c-u-ali-memo.jpg b/docs/.vitepress/dist/img/in-post/post-c-u-ali-memo.jpg new file mode 100755 index 0000000..b1d7f25 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-c-u-ali-memo.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-c-u-ali-team.png b/docs/.vitepress/dist/img/in-post/post-c-u-ali-team.png new file mode 100755 index 0000000..83a78d4 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-c-u-ali-team.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Architecture.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Architecture.png new file mode 100755 index 0000000..72f0fa7 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Architecture.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-after.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-after.png new file mode 100755 index 0000000..2c4f242 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-after.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-before.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-before.png new file mode 100755 index 0000000..39ebc15 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/Lighthouse-before.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PRECACHE-future-routes.jpg b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PRECACHE-future-routes.jpg new file mode 100755 index 0000000..29909b2 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PRECACHE-future-routes.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PUSH-link-rel-preload.jpg b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PUSH-link-rel-preload.jpg new file mode 100755 index 0000000..2fd4c7f Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/PUSH-link-rel-preload.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/after-skeleton.jpg b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/after-skeleton.jpg new file mode 100755 index 0000000..d6c1da0 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/after-skeleton.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/before-skeleton.jpg b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/before-skeleton.jpg new file mode 100755 index 0000000..7fb7cb4 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/before-skeleton.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/eleme-at-io.jpg b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/eleme-at-io.jpg new file mode 100755 index 0000000..6190a41 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/eleme-at-io.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-After-Optim.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-After-Optim.png new file mode 100755 index 0000000..8606e73 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-After-Optim.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-Before-Optim.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-Before-Optim.png new file mode 100755 index 0000000..0e275dc Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/msite-Before-Optim.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/nextTick-&-Load.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/nextTick-&-Load.png new file mode 100755 index 0000000..ba1dcaf Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/nextTick-&-Load.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-eleme-pwa/thisTick-&-Load.png b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/thisTick-&-Load.png new file mode 100755 index 0000000..0ae2244 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-eleme-pwa/thisTick-&-Load.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-js-version/javascript-java.jpg b/docs/.vitepress/dist/img/in-post/post-js-version/javascript-java.jpg new file mode 100755 index 0000000..e3b94c8 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-js-version/javascript-java.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-js-version/keep-calm-and-learn-javascript.png b/docs/.vitepress/dist/img/in-post/post-js-version/keep-calm-and-learn-javascript.png new file mode 100755 index 0000000..45b3892 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-js-version/keep-calm-and-learn-javascript.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-kuaidi-1.jpg b/docs/.vitepress/dist/img/in-post/post-kuaidi-1.jpg new file mode 100755 index 0000000..23d2f40 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-kuaidi-1.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-kuaidi-2.jpg b/docs/.vitepress/dist/img/in-post/post-kuaidi-2.jpg new file mode 100755 index 0000000..df26178 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-kuaidi-2.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-metro-panorama.jpg b/docs/.vitepress/dist/img/in-post/post-metro-panorama.jpg new file mode 100755 index 0000000..7e485e5 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-metro-panorama.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-metro-real.jpg b/docs/.vitepress/dist/img/in-post/post-metro-real.jpg new file mode 100755 index 0000000..528cefb Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-metro-real.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-metro-ui.jpg b/docs/.vitepress/dist/img/in-post/post-metro-ui.jpg new file mode 100755 index 0000000..2f8005d Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-metro-ui.jpg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-007.jpeg b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-007.jpeg new file mode 100755 index 0000000..1238ae9 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-007.jpeg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-014+PWA.jpeg b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-014+PWA.jpeg new file mode 100755 index 0000000..37bb1f5 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/PWAR-014+PWA.jpeg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-1.jpeg b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-1.jpeg new file mode 100755 index 0000000..69428a7 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-1.jpeg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-2.jpeg b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-2.jpeg new file mode 100755 index 0000000..e273c93 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-2.jpeg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-3.jpeg b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-3.jpeg new file mode 100755 index 0000000..6c0b02a Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/flipkart-3.jpeg differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/ios2-a2hs.gif b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/ios2-a2hs.gif new file mode 100755 index 0000000..b15be2d Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/ios2-a2hs.gif differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-hybridzation.png b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-hybridzation.png new file mode 100755 index 0000000..0775615 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-hybridzation.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-trend.png b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-trend.png new file mode 100755 index 0000000..b60ffeb Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/qcon-trend.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-lifecycle.png b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-lifecycle.png new file mode 100755 index 0000000..8c97795 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-lifecycle.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-race.png b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-race.png new file mode 100755 index 0000000..2252fe0 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-race.png differ diff --git a/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-sw.png b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-sw.png new file mode 100755 index 0000000..fcf5977 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/post-nextgen-web-pwa/sw-sw.png differ diff --git a/docs/.vitepress/dist/img/in-post/zip/AutoPackageShell_2017.zip b/docs/.vitepress/dist/img/in-post/zip/AutoPackageShell_2017.zip new file mode 100644 index 0000000..594d456 Binary files /dev/null and b/docs/.vitepress/dist/img/in-post/zip/AutoPackageShell_2017.zip differ diff --git a/docs/.vitepress/dist/img/post-bg-2015.jpg b/docs/.vitepress/dist/img/post-bg-2015.jpg new file mode 100755 index 0000000..aa39f69 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-2015.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-alibaba.jpg b/docs/.vitepress/dist/img/post-bg-alibaba.jpg new file mode 100755 index 0000000..1005409 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-alibaba.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-alitrip.jpg b/docs/.vitepress/dist/img/post-bg-alitrip.jpg new file mode 100755 index 0000000..c6ed9a1 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-alitrip.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-android.jpg b/docs/.vitepress/dist/img/post-bg-android.jpg new file mode 100755 index 0000000..73eb313 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-android.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-apple-event-2015.jpg b/docs/.vitepress/dist/img/post-bg-apple-event-2015.jpg new file mode 100755 index 0000000..57370ea Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-apple-event-2015.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-digital-native.jpg b/docs/.vitepress/dist/img/post-bg-digital-native.jpg new file mode 100755 index 0000000..6a3d3b8 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-digital-native.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-e2e-ux.jpg b/docs/.vitepress/dist/img/post-bg-e2e-ux.jpg new file mode 100755 index 0000000..963f085 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-e2e-ux.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-ios9-web.jpg b/docs/.vitepress/dist/img/post-bg-ios9-web.jpg new file mode 100755 index 0000000..a1f20e7 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-ios9-web.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-js-module.jpg b/docs/.vitepress/dist/img/post-bg-js-module.jpg new file mode 100755 index 0000000..029670e Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-js-module.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-js-version.jpg b/docs/.vitepress/dist/img/post-bg-js-version.jpg new file mode 100755 index 0000000..5afdc56 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-js-version.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-kuaidi.jpg b/docs/.vitepress/dist/img/post-bg-kuaidi.jpg new file mode 100755 index 0000000..8416b93 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-kuaidi.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-miui-ux.jpg b/docs/.vitepress/dist/img/post-bg-miui-ux.jpg new file mode 100755 index 0000000..5ee984b Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-miui-ux.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-miui6.jpg b/docs/.vitepress/dist/img/post-bg-miui6.jpg new file mode 100755 index 0000000..d2fb693 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-miui6.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-nextgen-web-pwa.jpg b/docs/.vitepress/dist/img/post-bg-nextgen-web-pwa.jpg new file mode 100755 index 0000000..f422ee8 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-nextgen-web-pwa.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-os-metro.jpg b/docs/.vitepress/dist/img/post-bg-os-metro.jpg new file mode 100755 index 0000000..0524e12 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-os-metro.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-re-vs-ng2.jpg b/docs/.vitepress/dist/img/post-bg-re-vs-ng2.jpg new file mode 100755 index 0000000..8ba7688 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-re-vs-ng2.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-rwd.jpg b/docs/.vitepress/dist/img/post-bg-rwd.jpg new file mode 100755 index 0000000..f204790 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-rwd.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-see-u-ali.jpg b/docs/.vitepress/dist/img/post-bg-see-u-ali.jpg new file mode 100755 index 0000000..8ec0e5d Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-see-u-ali.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-universe.jpg b/docs/.vitepress/dist/img/post-bg-universe.jpg new file mode 100755 index 0000000..de5a63b Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-universe.jpg differ diff --git a/docs/.vitepress/dist/img/post-bg-unix-linux.jpg b/docs/.vitepress/dist/img/post-bg-unix-linux.jpg new file mode 100755 index 0000000..7edec50 Binary files /dev/null and b/docs/.vitepress/dist/img/post-bg-unix-linux.jpg differ diff --git a/docs/.vitepress/dist/img/post-sample-image.jpg b/docs/.vitepress/dist/img/post-sample-image.jpg new file mode 100755 index 0000000..51fe509 Binary files /dev/null and b/docs/.vitepress/dist/img/post-sample-image.jpg differ diff --git a/docs/.vitepress/dist/img/tag-bg.jpg b/docs/.vitepress/dist/img/tag-bg.jpg new file mode 100755 index 0000000..2295638 Binary files /dev/null and b/docs/.vitepress/dist/img/tag-bg.jpg differ diff --git a/docs/.vitepress/dist/img/weibo.png b/docs/.vitepress/dist/img/weibo.png new file mode 100644 index 0000000..48c84b3 Binary files /dev/null and b/docs/.vitepress/dist/img/weibo.png differ diff --git a/docs/.vitepress/dist/img/zhihu.png b/docs/.vitepress/dist/img/zhihu.png new file mode 100644 index 0000000..f180a81 Binary files /dev/null and b/docs/.vitepress/dist/img/zhihu.png differ diff --git a/docs/.vitepress/dist/index.html b/docs/.vitepress/dist/index.html index 9ceea02..43106fd 100644 --- a/docs/.vitepress/dist/index.html +++ b/docs/.vitepress/dist/index.html @@ -3,23 +3,23 @@ - my blog project - + 前端技术知识库 + - + - + - - - + + + -
Skip to content

my blog projecta blog site

My great project tagline

- +
Skip to content

让技术赋能业务开发高效稳定赋能业务运行

Keep Reading, Keep Thinking, Keep Doing

背景图

Released under the MIT License.

+ \ No newline at end of file diff --git a/docs/.vitepress/dist/markdown-examples.html b/docs/.vitepress/dist/markdown-examples.html deleted file mode 100644 index 08847bb..0000000 --- a/docs/.vitepress/dist/markdown-examples.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - Markdown Extension Examples | my blog project - - - - - - - - - - - - - - -
Skip to content

Markdown Extension Examples

This page demonstrates some of the built-in markdown extensions provided by VitePress.

Syntax Highlighting

VitePress provides Syntax Highlighting powered by Shiki, with additional features like line-highlighting:

Input

md
```js{4}
-export default {
-  data () {
-    return {
-      msg: 'Highlighted!'
-    }
-  }
-}
-```

Output

js
export default {
-  data () {
-    return {
-      msg: 'Highlighted!'
-    }
-  }
-}

Custom Containers

Input

md
::: info
-This is an info box.
-:::
-
-::: tip
-This is a tip.
-:::
-
-::: warning
-This is a warning.
-:::
-
-::: danger
-This is a dangerous warning.
-:::
-
-::: details
-This is a details block.
-:::

Output

INFO

This is an info box.

TIP

This is a tip.

WARNING

This is a warning.

DANGER

This is a dangerous warning.

Details

This is a details block.

More

Check out the documentation for the full list of markdown extensions.

- - - - \ No newline at end of file diff --git a/docs/.vitepress/dist/network/https-tips.html b/docs/.vitepress/dist/network/https-tips.html new file mode 100644 index 0000000..6b5ae7d --- /dev/null +++ b/docs/.vitepress/dist/network/https-tips.html @@ -0,0 +1,34 @@ + + + + + + HTTPS网站访问过程 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

HTTPS网站访问过程

相对于普通HTTP网络请求,访问HTTPS时,浏览器会帮我们做很多影藏的工作。

  1. 发起请求 首先当输入完https网址 点击enter之后,浏览器首先向服务器发送一个访问的请求,这个请求中包含浏览器SSL协议的版本号,加密算法的种类,产生的随机数,以及其他 服务器与客户端之间通讯所需要的各种信息;
  2. 服务器端返回证书 服务器向客户端传送SSL协议的版本号,加密算法的种类,随机数以及其他信息,同时服务器还将向客服端传送自己的证书,这些信息被保存在客户端称作‘保护空间’的地方,这里最关键的就是证书信息;
  3. 浏览器验证证书信息 浏览器利用服务器传递过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器的证书的CA是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。 如果合法验证没有通过,通讯将断开,如果合法验证通过,将继续进行第四步。
  4. 客服端向服务器发送“预主密码” 浏览器随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤2中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器; 4.1 如果服务器要求客户的身份认证(在握手过程中可选),用户不光要给服务器“预主密码”,还需要建立一个随机数然后对其进行数据签名,将设个含有签名的随机数和客户自己的证书也传给服务器。 4.2 如果不需要,则只将“预主密码”传递给服务器,直接进行第6步。
  5. 服务器身份验证(需要才进行);
  6. 浏览器、服务器各自生成通话密码 服务器将自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主通讯密码(客服端也将通过同样的方法产生相同的主通讯密码);
  7. 约定通话密码 服务器和客服端用相同的主通讯密码即“通话密码”,一个对称密钥用于SSL协议的安全数据通讯的加解密通讯,同时在SSL通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。
  8. 浏览器通知服务器已经准备就绪
  9. 服务器通知浏览器已经准备就绪
  10. 开始数据通信 SSL的握手部分结束,SSL安全通道建立,开始进行数据通讯

NSURLSession 模拟HTTPS证书认证

当我们进行访问一个HTTPS网站时,当走到步骤2时(服务器返回证书时),需要我们在本地完成证书信任的过程,如果使用session创建的task进行网络访问,会进入到代理方法- URLSession:didReceiveChallenge:completionHandler:完成步骤3。 其中 challenge 是一个包含授权请求的对象(NSURLAuthenticationChalleng),代表进行HTTPS请求时,服务器发过来的质询,当收到质询之后就要开始进行客服端验证了, challenge 有几个重要的属性: protectionSpace它代表着对需要验证的受保护空间的验证,是一个NSURLProtectionSpace类型的对象,NSURLProtectionSpace对象包含请求的主机host、端口号port、代理类型proxyType、使用的协议protocol、服务端要求客户端对其验证的方法authenticationMethod等重要的信息,还有代表着服务器SSL传输状态的SecTrustRef类型的属性serverTrust,不过当且仅当authenticationMethod为NSURLAuthenticationMethodServerTrust这个属性值才不为Nil.

常见服务端指定的验证方法的类型

NSURLAuthenticationMethodHTTPBasic 
+NSURLAuthenticationMethodHTTPDigest
+NSURLAuthenticationMethodNTLM
+NSURLAuthenticationMethodClientCertificate
+NSURLAuthenticationMethodServerTrust

其中HTTP Basic、HTTP Digest与NTLM认证都是基于用户名/密码的认证,ClientCertificate(客户端证书)认证要求从客户端上传证书。客户端需要按照服务端指定的认证方法进行认证,否则可能会按照错误处理。例如使用HTTP Basic方式,客户端需要将用户名和密码信息放到凭据中,然后传递给服务端;如果使用的是ServerTrust方式,那么客户端就要将信任的凭据发给服务端。 一般在HTTPS访问的第3步过程中,服务端要求的认证方法几乎总是ServerTrust方式。有遇到过一些网络代理工具使用HTTP Digest的验证方式,在浏览器端进行访问的时候就弹出一个要求输入账号和密码的弹窗.

对于completionHandler参数是一个最终处理凭据的回调,要求在创建好包含验证信息的凭据之后必须调用,这样才会将验证的信息发送给服务端,也就意味着第3步的完成,开始进行第4步

typedef NS_ENUM(NSInteger, NSURLSessionAuthChallengeDisposition) {
+    NSURLSessionAuthChallengeUseCredential = 0,   // 使用服务器发回的凭据,不过可能为空     
+    NSURLSessionAuthChallengePerformDefaultHandling = 1,  // 默认的处理方法,凭据参数会被忽略
+    NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2,  //取消整个请求,忽略凭据参数 
+    NSURLSessionAuthChallengeRejectProtectionSpace = 3, // 这次质询被拒绝,下次再试 ,凭据参数被忽略
+} NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);

参考:HTTPS访问控制

date: 2017-04-22 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/network/index.html b/docs/.vitepress/dist/network/index.html new file mode 100644 index 0000000..5d54456 --- /dev/null +++ b/docs/.vitepress/dist/network/index.html @@ -0,0 +1,25 @@ + + + + + + 网络 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

网络

网络协议

应用

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/utils/git-tips.html b/docs/.vitepress/dist/utils/git-tips.html new file mode 100644 index 0000000..67f3712 --- /dev/null +++ b/docs/.vitepress/dist/utils/git-tips.html @@ -0,0 +1,316 @@ + + + + + + git 使用汇总 | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

git 使用汇总

Git配置多个SSH-Key

当有多个git账号时,比如:

a. 一个gitlab,用于公司内部的工作开发;

b. 一个github,用于自己进行一些开发活动;

解决方法

(1) 生成一个公司用的SSH-Key

# 在~/.ssh/目录会生成gitlab_id-rsa和gitlab_id-rsa.pub私钥和公钥。我们将gitlab_id-rsa.pub中的内容粘帖到公司GitLab服务器的SSH-key的配置中
+$ ssh-keygen -t rsa -C 'xxxxx@company.com' -f ~/.ssh/gitlab_id_rsa

(2) 生成一个github用的SSH-Key

ssh-keygen -t rsa -C 'xxxxx@qq.com' -f ~/.ssh/github_id_rsa

(3) 在 ~/.ssh 目录下新建一个config文件,添加如下内容(其中Host和HostName填写git服务器的域名,IdentityFile指定私钥的路径)

# 添加config配置文件
+# vi ~/.ssh/config
+# 或者
+# touch ~/.ssh/config
+
+# 文件内容如下
+# gitlab
+Host gitlab.com
+HostName gitlab.com
+PreferredAuthentications publickey
+IdentityFile ~/.ssh/gitlab_id_rsa
+# github
+Host github.com
+HostName github.com
+PreferredAuthentications publickey
+IdentityFile ~/.ssh/github_id_rsa

(4) 用ssh命令分别测试

$ ssh -T git@gitlab.com
+$ ssh -T git@github.com

常见的git命令

新建代码库

# 在当前目录新建一个Git代码库
+$ git init
+
+# 新建一个目录,将其初始化为Git代码库
+$ git init [project-name]
+
+# 下载一个项目和它的整个代码历史
+$ git clone [url]

配置

# 显示当前的Git配置
+$ git config --list
+
+# 编辑Git配置文件
+$ git config -e [--global]
+
+# 设置提交代码时的用户信息
+$ git config [--global] user.name "[name]"
+$ git config [--global] user.email "[email address]"

增加/删除文件

# 添加指定文件到暂存区
+$ git add [file1] [file2] ...
+
+# 添加指定目录到暂存区,包括子目录
+$ git add [dir]
+
+# 添加当前目录的所有文件到暂存区
+$ git add .
+
+# 添加每个变化前,都会要求确认
+# 对于同一个文件的多处变化,可以实现分次提交
+$ git add -p
+
+# 删除工作区文件,并且将这次删除放入暂存区
+$ git rm [file1] [file2] ...
+
+# 停止追踪指定文件,但该文件会保留在工作区
+$ git rm --cached [file]
+
+# 改名文件,并且将这个改名放入暂存区
+$ git mv [file-original] [file-renamed]

代码提交

# 提交暂存区到仓库区
+$ git commit -m [message]
+
+# 提交暂存区的指定文件到仓库区
+$ git commit [file1] [file2] ... -m [message]
+
+# 提交工作区自上次commit之后的变化,直接到仓库区
+$ git commit -a
+
+# 提交时显示所有diff信息
+$ git commit -v
+
+# 使用一次新的commit,替代上一次提交
+# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
+$ git commit --amend -m [message]
+
+# 重做上一次commit,并包括指定文件的新变化
+$ git commit --amend [file1] [file2] ...

分支

# 列出所有本地分支
+$ git branch
+
+# 列出所有远程分支
+$ git branch -r
+
+# 列出所有本地分支和远程分支
+$ git branch -a
+
+# 新建一个分支,但依然停留在当前分支
+$ git branch [branch-name]
+
+# 新建一个分支,并切换到该分支
+$ git checkout -b [branch]
+
+# 新建一个分支,指向指定commit
+$ git branch [branch] [commit]
+
+# 新建一个分支,与指定的远程分支建立追踪关系
+$ git branch --track [branch] [remote-branch]
+
+# 切换到指定分支,并更新工作区
+$ git checkout [branch-name]
+
+# 切换到上一个分支
+$ git checkout -
+
+# 建立追踪关系,在现有分支与指定的远程分支之间
+$ git branch --set-upstream [branch] [remote-branch]
+
+# 合并指定分支到当前分支
+$ git merge [branch]
+
+# 选择一个commit,合并进当前分支
+$ git cherry-pick [commit]
+
+# 删除分支
+$ git branch -d [branch-name]
+
+# 删除远程分支
+$ git push origin --delete [branch-name]
+$ git branch -dr [remote/branch]

标签

# 列出所有tag
+$ git tag
+
+# 新建一个tag在当前commit
+$ git tag [tag]
+
+# 新建一个tag在指定commit
+$ git tag [tag] [commit]
+
+# 删除本地tag
+$ git tag -d [tag]
+
+# 删除远程tag
+$ git push origin :refs/tags/[tagName]
+
+# 查看tag信息
+$ git show [tag]
+
+# 提交指定tag
+$ git push [remote] [tag]
+
+# 提交所有tag
+$ git push [remote] --tags
+
+# 新建一个分支,指向某个tag
+$ git checkout -b [branch] [tag]
+
+# 切换为由远程创建的分支
+$ git checkout -b [branch] [remote/branch]

查看信息

# 显示有变更的文件
+$ git status
+
+# 显示当前分支的版本历史
+$ git log

远程同步

# 下载远程仓库的所有变动
+$ git fetch [remote]
+
+# 显示所有远程仓库
+$ git remote -v
+
+# 显示某个远程仓库的信息
+$ git remote show [remote]
+
+# 增加一个新的远程仓库,并命名
+$ git remote add [shortname] [url]
+
+# 更新远程仓库地址
+$ git remote set-url [shortname] [url]
+$ git remote set-url origin http://originproject.git
+
+# 修改远程仓库名
+$ git remote rename [current-shortname] [new-shortname]
+
+# 取回远程仓库的变化,并与本地分支合并,
+$ git pull [remote] [branch]
+
+# 上传本地指定分支到远程仓库,默认提交到与本地分支对应的远程分支上
+$ git push [remote] [branch]
+
+上传本地指定分支到远程仓库,创建与到与本地分支对应的远程分支上
+$  git push --set-upstream [remote] [branch]
+
+# 强行推送当前分支到远程仓库,即使有冲突
+$ git push [remote] --force
+
+# 推送所有分支到远程仓库
+$ git push [remote] --all
+
+# 推送某一个commit 到远程仓库
+$ git push [remote name] [commit hash]:[remote branch name]
+
+# 推送所有tag到远程仓库
+$ git push [remote] --tags

回滚

# 回退到上个版本
+$ git reset --hard HEAD^
+# 回退到前3次提交之前,以此类推,回退到n次提交之前  
+$ git reset --hard HEAD~3
+# 退到/进到 指定commit的sha码        
+$ git reset --hard [commit_id] 
+# 强制推到远程
+$ git push origin HEAD --force

date: 2019-04-15 14:00:00 author: "Gao Fei"

pull request 基本操作流程

<!--远程代码-->
+$ git remote -v
+
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (fetch)
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (push)
$ git remote add http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git
+
+usage: git remote add [<options>] <name> <url>
+
+   
+`-f, --fetch           fetch the remote branches
+    --tags                import all tags and associated objects when fetching
+                          or do not fetch any tag at all (--no-tags)
+    -t, --track <branch>  branch(es) to track
+    -m, --master <branch>
+                          master branch
+    --mirror[=<push|fetch>]
+                          set up remote as a mirror to push to or fetch from`
+                          
+$ git remote add upstream http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git
+
+$ git remote -v
+
+origin	http://58`.250.71.52:8081/gaofei/FSMobileAssistant.git (fetch)
+origin	http://58.250.71.52:8081/gaofei/FSMobileAssistant.git (push)
+upstream	http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git (fetch)
+upstream	http://58.250.71.52:8081/iOS_Group/FSMobileAssistant.git (push)`
+bogon:FSMobileAssistant awei$ git fetch --all
+
+`Fetching origin
+Fetching upstream
+remote: Counting objects: 166, done.
+remote: Compressing objects: 100% (98/98), done.
+remote: Total 166 (delta 124), reused 99 (delta 66)
+Receiving objects: 100% (166/166), 69.78 KiB | 0 bytes/s, done.
+Resolving deltas: 100% (124/124), completed with 48 local objects.
+From http://58.250.71.52:8081/iOS_Group/FSMobileAssistant
+ * [new branch]      master     -> upstream/master
+ * [new branch]      mvvm       -> upstream/mvvm`
+$ git merge upstream/master origin/master
+`Auto-merging MobileAssistant/Vendors/XHDatePicker/XHDatePickerView.m
+Auto-merging MobileAssistant/Vendors/FSAlertTools/FSAlertTools.m
+Auto-merging MobileAssistant/Vendors/FSAlertTools/FSAlertTools.h
+CONFLICT (modify/delete): MobileAssistant/Util/AlertUtil.m deleted in upstream/master and modified in HEAD. Version HEAD of MobileAssistant/Util/AlertUtil.m left in tree.
+CONFLICT (modify/delete): MobileAssistant/Util/AlertUtil.h deleted in upstream/master and modified in HEAD. Version HEAD of MobileAssistant/Util/AlertUtil.h left in tree.
+Auto-merging MobileAssistant/Sections/Personal Center/ViewController/AboutVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/TouchIDUtil/TouchIDUtil.m
+Auto-merging MobileAssistant/Sections/Personal Center/TouchIDUtil/KeyChainManager.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/SetNewPwdVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/RegisterVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/PwdInputVC.m
+Auto-merging MobileAssistant/Sections/Personal Center/LoginAndRegister/ViewController/ForgetPwdVC.m
+Auto-merging MobileAssistant/Sections/Main/CompanyInfo/Controller/FSCompanyInfoController.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailReasonCell.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailNameCell.m
+Auto-merging MobileAssistant/Sections/Approval/CustomerUI/DetailView/ADetailDescriptionCell.m
+Automatic merge failed; fix conflicts and then commit the result.`
整体流程如下:
+第一步:
+bogon:FSMobileAssistant awei$ git add .
+第二步:
+bogon:FSMobileAssistant awei$ git commit -m "sure delete AlertUtil"
+[master b989627] sure delete AlertUtil
+第三步:
+bogon:FSMobileAssistant awei$ git fetch --all
+Fetching origin
+Fetching upstream
+第四步:
+bogon:FSMobileAssistant awei$ git merge upstream/master origin/master
+Already up-to-date.
+第五步:
+bogon:FSMobileAssistant awei$ git push`
+`Counting objects: 209, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (84/84), done.
+Writing objects: 100% (209/209), 171.21 KiB | 0 bytes/s, done.
+Total 209 (delta 153), reused 162 (delta 123)
+To http://58.250.71.52:8081/gaofei/FSMobileAssistant.git
+   1e7ae50..b989627  master -> master
+bogon:FSMobileAssistant awei$

一. 在合并远程代码的时候,或许会出现以下问题:

I'm in the process of learning github on mac (command-line) and whenever I do git pull origin master i get this

# Please enter a commit message to explain why this merge is necessary,
+# especially if it merges an updated upstream into a topic branch.
+#
+# Lines starting with '#' will be ignored, and an empty message aborts
+# the commit.
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+~                                                                               
+".git/MERGE_MSG" 7L, 293C

两种解决方式: 方式一:

You're in the text editor, vim! It's a modal text editor, so you would need to:

	1.	Press ==i== to enter insert mode.
+	2.	Now you can type your message, as if you were in a normal (non-modal) text editor.
+	3.	Press ==esc== to go back to command mode.
+	4.	Then type *:w* followed by ==enter== to save.
+	5.	Finally *:q* followed by ==enter== to quit.

方式二:

Make it simple.
+
+Type *:wq* and ==enter==

2017-04-20 高飞

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/utils/mac-tips.html b/docs/.vitepress/dist/utils/mac-tips.html new file mode 100644 index 0000000..b5224a3 --- /dev/null +++ b/docs/.vitepress/dist/utils/mac-tips.html @@ -0,0 +1,25 @@ + + + + + + Mac Tips | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Mac Tips

显示任何来源

macos 安全性与隐私中设置 显示 任何来源 使用如下命令: sudo spctl --master-disable

date: 2016-04-28 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/.vitepress/dist/utils/xcode-tips.html b/docs/.vitepress/dist/utils/xcode-tips.html new file mode 100644 index 0000000..1e74734 --- /dev/null +++ b/docs/.vitepress/dist/utils/xcode-tips.html @@ -0,0 +1,29 @@ + + + + + + Xcode Tips | 前端技术知识库 + + + + + + + + + + + + + + +
Skip to content

Xcode Tips

Xcode IDE

Xcode: symbol(s) not found for architecture armv7

log : Undefined symbols for architecture armv7:"OBJC_CLASS$_ViewController", referenced from:objc-class-ref in AppDelegate.o

ld: symbol(s) not found for architecture armv7

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Check if your Compile Sources section within the Build Phases of your project shows ViewController.m

参考: http://stackoverflow.com/questions/12522571/xcode-symbols-not-found-for-architecture-armv7

How to trap on UIViewAlertForUnsatisfiableConstraints?

I added UIViewAlertForUnsatisfiableConstraints symbolic breakpoint with suggested action: Obj-C project

po [[UIWindow keyWindow] _autolayoutTrace]

Swift project

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

参考:http://stackoverflow.com/questions/26389273/how-to-trap-on-uiviewalertforunsatisfiableconstraints

How to define Preprocessor Macros in Xcode

  1. Find TARGETS -> Build Settings , search Preprocessor Macros , By default we have tow:Debug and Release, Notice that the Dubug configuration already has a Macro defined - it's called DEBUG=1. therefore out of the box you can already check in your code if it has been complied with the Debug or Release configuration.
  2. To define your own Macro, click the little plus sign next Debug (and Release) and add something specific. I’m using IS_PRO=1, but you can choose anything you like really. I don’t know if you can set values other than boolean. Make sure you set your Macro in BOTH configurations, otherwise you’ll find different results when you submit your app
  3. Now that our Macro is defined, you can check if it’s present in your code like so:
#ifdef IS_PRO
+    NSLog(@&quot;It&#039;s the PRO version&quot;);
+#else
+    NSLog(@&quot;Must be the LITE version&quot;);
+#endif

date: 2017-03-28 16:00:00 author: "Gao Fei"

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..b86a6f3 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +docs.ipages.top \ No newline at end of file diff --git a/docs/frontend/ios/apple-update-cert.md b/docs/frontend/ios/apple-update-cert.md index a9dd032..e086a92 100644 --- a/docs/frontend/ios/apple-update-cert.md +++ b/docs/frontend/ios/apple-update-cert.md @@ -7,66 +7,66 @@ ## 示例 ### 1.确定已过期的 APP ID 1.1 找到已过期或者即将过期的 APP ID(Xcode 中为bundle id),位于图图1-1中3所在位置。将该 APP ID (以下简称id)记录下来。 -![图1-1](../../../public/img/apple/1-1.png) +![图1-1](/img/apple/1-1.png) ### 2.根据APP ID重新生成Certifictes 2.1 点击 Certificates 中的 Production可以看到所有的生产环境的证书,同时也可以看到是否过期。选择右上角的新建+,如下图所示。 -![](../../../public/img/apple/2-1-0.png) +![](/img/apple/2-1-0.png) 选择证书的适用的场景, (1)Development 对应 xcode 中的debug环境,开发调试的使用,包含了推送与非推送版本。 (2)Production 对应 xcode 中的 release 环境,也即是上线 app store 的环境, 常用的是有不带推送的、带推送的、带apple pay的证书。 示例就以生产中带推送的做参考,选择 Apple Push Notification, 点击Continue。 -![](../../../public/img/apple/2-1-1.png) -![](../../../public/img/apple/2-1-2.png) +![](/img/apple/2-1-1.png) +![](/img/apple/2-1-2.png) 选择需要更新的APP ID, 点击Continue -![](../../../public/img/apple/2-1-3.png) +![](/img/apple/2-1-3.png) 出现创建CSR文件的界面,里面说明了创建的步骤。下面我们按照步骤创建CSR。 -![](../../../public/img/apple/2-1-4.png) +![](/img/apple/2-1-4.png) 在mac应用程序中找到 “钥匙串访问”,打开“钥匙串访问”app, -![](../../../public/img/apple/2-2-1.png) +![](/img/apple/2-2-1.png) 在导航栏中点击“钥匙串访问”-> "证书助理" -> "从证书颁发机构请求证书", -![](../../../public/img/apple/2-2-2.png) +![](/img/apple/2-2-2.png) 输入邮箱地址,常用名称,选择存储到磁盘,点击“继续”.其中常用名称可以采用公司名称+app名称+环境名 -![](../../../public/img/apple/2-2-3.png) +![](/img/apple/2-2-3.png) 输入名称名称, 选择存储位置, 点击"存储". 将请求下来的的CSR证书保存在桌面上。 -![](../../../public/img/apple/2-2-4.png) +![](/img/apple/2-2-4.png) 回到创建证书的页面,点击"Continu" -![](../../../public/img/apple/2-1-4.png) +![](/img/apple/2-1-4.png) 出现选择证书的页面,点击"Choose File..." -![](../../../public/img/apple/2-3-0.png) +![](/img/apple/2-3-0.png) 找到之前创建的CSR文件,点击"选取" -![](../../../public/img/apple/2-3-1.png) +![](/img/apple/2-3-1.png) 上传CSR文件, 点击“Continue” -![](../../../public/img/apple/2-3-2.png) +![](/img/apple/2-3-2.png) 上传完成之后,证书就生成完毕, 点击"Download",下载到本地磁盘。 -![](../../../public/img/apple/2-3-3.png) +![](/img/apple/2-3-3.png) 下载完毕后会得到一个aps.cer证书, 但是不能直接发给别人使用, 需要双击cer文件,安装到钥匙串中,然后导出为.p12文件. -![](../../../public/img/apple/2-3-4.png) +![](/img/apple/2-3-4.png) - + 接下来说明一下导出P12文件给服务器使用。 在钥匙串中找到对应id的证书(可以通过id+证书名称确定) -![](../../../public/img/apple/2-4-1.png) +![](/img/apple/2-4-1.png) 选择导出“Apple Push Service: xxxxx” -![](../../../public/img/apple/2-4-2.png) +![](/img/apple/2-4-2.png) 弹出保存框, 输入存储名称,选择存储位置,点击"存储"。存储名称建议使用公司名称+app名称+环境+apns的形式,方便以管理。 -![](../../../public/img/apple/2-4-3.png) +![](/img/apple/2-4-3.png) 输入导出的密码, 此密码用于其他人员读取P12文件时使用。 -![](../../../public/img/apple/2-4-4.png) +![](/img/apple/2-4-4.png) 输入电脑登录用户的密码,点击“允许”。此处成功导出P12推送证书。备注:有的服务器只识别pem格式的文件,需要将P12格式转换为pem格式的。 -![](../../../public/img/apple/2-4-5.png) +![](/img/apple/2-4-5.png) 再次回到apple deleloper 页面,找到已过期的的描述文件(Provisioning Profiles),点击“Edit”, -![](../../../public/img/apple/3-1-1.png) +![](/img/apple/3-1-1.png) 选择对应的App ID 以及 Certificates, 点击 “Generate” -![](../../../public/img/apple/3-1-2.png) +![](/img/apple/3-1-2.png) 到此新的Provisioning Profiles 已生成,点击"Download" -![](../../../public/img/apple/3-1-3.png) +![](/img/apple/3-1-3.png) 刚才已过期的 Provisioning Profiles 的 Status has changed to Active -![](../../../public/img/apple/3-1-4.png) +![](/img/apple/3-1-4.png) 按照同样的方式,更新development 下的Certificates & Provisioning Profiles 一共产生了5个文件,如下图所示 -![](../../../public/img/apple/3-2.png) +![](/img/apple/3-2.png) |序列|示例|名称|说明| |----|----|----|----| diff --git a/docs/frontend/ios/autoPackage-tips.md b/docs/frontend/ios/autoPackage-tips.md index a9122ff..50987e4 100644 --- a/docs/frontend/ios/autoPackage-tips.md +++ b/docs/frontend/ios/autoPackage-tips.md @@ -21,7 +21,7 @@ build_configuration="Release" 备注:Xcode 安装了多个版本之后,可以将目标打包的Xcode名称(eg:Xcode8.2.app)改为Xcode.app teamID可以在xxx.xcodeproj包文件中==project.pbxproj==,找到==DEVELOPMENT_TEAM==的值 -![AutoPackageShell.zip](../../../public/img/in-post/zip/AutoPackageShell_2017.zip) + date: 2017-06-01 16:00:00 diff --git a/docs/frontend/ios/framework-share.md b/docs/frontend/ios/framework-share.md index ce0c7db..2136dda 100644 --- a/docs/frontend/ios/framework-share.md +++ b/docs/frontend/ios/framework-share.md @@ -6,27 +6,27 @@ xcode打包需要配置 1.检查基本的配置 -![WechatIMG54](../../../public/img/in-post/media/15111440909345/WechatIMG54.jpeg) +![WechatIMG54](/img/in-post/media/15111440909345/WechatIMG54.jpeg) -![WechatIMG53](.../../../public/img/in-post/media/15111440909345/WechatIMG53.jpeg) +![WechatIMG53](/img/in-post/media/15111440909345/WechatIMG53.jpeg) 2.选择支持的最低版本 -![WechatIMG4161](../../../public/img/in-post/media/15111440909345/WechatIMG4161.jpeg) +![WechatIMG4161](/img/in-post/media/15111440909345/WechatIMG4161.jpeg) 3. 改为静态打包(对于ios8以上的系统,可以使用动态库(Dynamic Library)) -![WechatIMG4162](../../../public/img/in-post/media/15111440909345/WechatIMG4162.jpeg) +![WechatIMG4162](/img/in-post/media/15111440909345/WechatIMG4162.jpeg) 4. 导入工程中.m与 .h文件 -![WechatIMG4163](../../../public/img/in-post/media/15111440909345/WechatIMG4163.jpeg) +![WechatIMG4163](/img/in-post/media/15111440909345/WechatIMG4163.jpeg) 合并模拟器与真机版本 -![WechatIMG55](../../../public/img/in-post/media/15111440909345/WechatIMG55.jpeg) +![WechatIMG55](/img/in-post/media/15111440909345/WechatIMG55.jpeg) -![WechatIMG56](../../../public/img/in-post/media/15111440909345/WechatIMG56.jpeg) +![WechatIMG56](/img/in-post/media/15111440909345/WechatIMG56.jpeg) -![WechatIMG57](../../../public/img/in-post/media/15111440909345/WechatIMG57.jpeg) +![WechatIMG57](/img/in-post/media/15111440909345/WechatIMG57.jpeg) 在终端输入 diff --git a/docs/frontend/ios/post-facebook-share.md b/docs/frontend/ios/post-facebook-share.md index c0380de..bfd470b 100644 --- a/docs/frontend/ios/post-facebook-share.md +++ b/docs/frontend/ios/post-facebook-share.md @@ -125,7 +125,7 @@ content.contentURL = [NSURL URLWithString:@"https://developers.facebook.com"]; ``` SDK中定义的分享按钮如下图: -![](../../../public/img/in-post/media/14925152141994/14925202210363.jpg) +![](/img/in-post/media/14925152141994/14925202210363.jpg) @@ -138,11 +138,11 @@ SDK中定义的分享按钮如下图: * 请求 ==publish_actions== 权限,需要申请 对自定义的分享按钮的样式的说明: -![](../../../public/img/in-post/media/14925152141994/14925198369392.jpg) +![](/img/in-post/media/14925152141994/14925198369392.jpg) 申请权限需要注意的事项: 上传视频的注意事项如图所示: -![](../../../public/img/in-post/media/14925152141994/14925722696364.jpg) +![](/img/in-post/media/14925152141994/14925722696364.jpg) 3.4 自定义分享内容 diff --git a/docs/frontend/ios/post-instagram-share.md b/docs/frontend/ios/post-instagram-share.md index a9f28bc..9fd3bb7 100644 --- a/docs/frontend/ios/post-instagram-share.md +++ b/docs/frontend/ios/post-instagram-share.md @@ -2,7 +2,7 @@ # Instagram 分享 大概流程如下: -![](../../../public/img/in-post/media/14926785184639/14926786938908.jpg) +![](/img/in-post/media/14926785184639/14926786938908.jpg) 分享:无需获取权限,通过Custom URL Scheme或者Document Interaction 分享出去后停留在Instagram,无回调(返回值)。 @@ -10,23 +10,23 @@ 另外:通过授权(账号和密码)的方式,可以获取用户的公开内容。 登陆权限有如下几种: - ![](../../../public/img/in-post/media/14926785184639/14926788159747.jpg) + ![](/img/in-post/media/14926785184639/14926788159747.jpg) 获取较高权限,比如:public_content可以拿到用户发布的图片和视频内容。 备注: 客服端申请权限,目前只申请下来basic权限,public_content权限没申请下来,没能继续测试是否能拿到用户发布的内容,但是理论上是可以的,且看下面的介绍) - ![](../../../public/img/in-post/media/14926785184639/14926813444655.jpg) + ![](/img/in-post/media/14926785184639/14926813444655.jpg) 根据官方文档的介绍: 第一步:授权,获取access_token; -![](../../../public/img/in-post/media/14926785184639/14926788445548.jpg) +![](/img/in-post/media/14926785184639/14926788445548.jpg) 第二步:get用户最新发布的media。 - ![](../../../public/img/in-post/media/14926785184639/14926788538614.jpg) + ![](/img/in-post/media/14926785184639/14926788538614.jpg) 请求的url及参数如上图所示,返回的结果如下图所示。 - ![](../../../public/img/in-post/media/14926785184639/14926788643833.jpg) + ![](/img/in-post/media/14926785184639/14926788643833.jpg) 结论:可以先请求用户授权,然后分享照片,最后获取最新发布的信息。 @@ -34,7 +34,7 @@ 分享文档:https://www.instagram.com/developer/mobile-sharing/iphone-hooks/ 通过 URL Scheme 分享,截图如下: -![](../../../public/img/in-post/media/14926785184639/14926792525999.jpg) +![](/img/in-post/media/14926785184639/14926792525999.jpg) ``` -(void)loadInstagram{ @@ -51,7 +51,7 @@ ``` 通过UIDocumentInteractionController,原文档说明如下: -![](../../../public/img/in-post/media/14926785184639/14926791330965.jpg) +![](/img/in-post/media/14926785184639/14926791330965.jpg) 示例代码: ``` diff --git a/docs/frontend/ios/post-twitter-share.md b/docs/frontend/ios/post-twitter-share.md index 5255710..8c150c4 100644 --- a/docs/frontend/ios/post-twitter-share.md +++ b/docs/frontend/ios/post-twitter-share.md @@ -5,7 +5,7 @@ https://fabric.io/kits/ios/twitterkit/manual-install ## 1 开发者账号申请注意事项: -![]../../../public/img/in-post/media/14925836417059/14925860141113.jpg) +![]/img/in-post/media/14925836417059/14925860141113.jpg) ## 2 安装步骤: @@ -13,25 +13,25 @@ https://fabric.io/kits/ios/twitterkit/manual-install 2.1 Download, unzip, and drag 下载,解压,拖拽到工程文件 2.2 Add a Run Script Build Phase -![](../../../public/img/in-post/media/14925836417059/14925879419077.jpg) -![](../../../public/img/in-post/media/14925836417059/14925882391902.jpg) -![](../../../public/img/in-post/media/14925836417059/14925945787875.jpg) +![](/img/in-post/media/14925836417059/14925879419077.jpg) +![](/img/in-post/media/14925836417059/14925882391902.jpg) +![](/img/in-post/media/14925836417059/14925945787875.jpg) -![](../../../public/img/in-post/media/14925836417059/14925891251063.jpg) +![](/img/in-post/media/14925836417059/14925891251063.jpg) 2.3 Add API Key to Info.plist - ![](../../../public/img/in-post/media/14925836417059/14925893095808.jpg) + ![](/img/in-post/media/14925836417059/14925893095808.jpg) -![](../../../public/img/in-post/media/14925836417059/14925894119822.jpg) +![](/img/in-post/media/14925836417059/14925894119822.jpg) 2.4 Initialize Twitter and Run -![](../../../public/img/in-post/media/14925836417059/14925896301467.jpg) +![](/img/in-post/media/14925836417059/14925896301467.jpg) ## 3 重要注解: -![](../../../public/img/in-post/media/14925836417059/14926599993618.jpg) +![](/img/in-post/media/14925836417059/14926599993618.jpg) ## 4 twitter 分享文档: diff --git a/docs/frontend/other/2020-03-22-angular.md b/docs/frontend/other/2020-03-22-angular.md index c8109a4..046e1e1 100644 --- a/docs/frontend/other/2020-03-22-angular.md +++ b/docs/frontend/other/2020-03-22-angular.md @@ -4,7 +4,7 @@ title: "angular 入门" subtitle: "基础" date: 2020-03-12 14:00:00 author: "Gao Fei" -header-img: "../../../public/img/post-bg-ios9-web.jpg" +header-img: "/img/post-bg-ios9-web.jpg" tags: - git diff --git a/docs/frontend/other/index.md b/docs/frontend/other/index.md index b0880e3..2e147ac 100644 --- a/docs/frontend/other/index.md +++ b/docs/frontend/other/index.md @@ -4,7 +4,7 @@ title: "react 入门" subtitle: "基础" date: 2020-03-8 14:00:00 author: "Gao Fei" -header-img: "../../../public/img/post-bg-ios9-web.jpg" +header-img: "/img/post-bg-ios9-web.jpg" tags: - git diff --git a/docs/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md b/docs/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md index f07f94e..bb048dd 100644 --- a/docs/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md +++ b/docs/frontend/swift/02-Interoperability/01-Interacting with Objective-C APIs.md @@ -685,7 +685,7 @@ class MyViewController: UIViewController { 可以使用`perform(_:)`方法以及它的变体在兼容 Objective-C 的对象上调用方法。使用选择器调用方法并非内在安全的,因为编译器无法保证结果,甚至无法保证对象能否响应选择器。因此,坚决不提倡使用这些 API,除非代码确实依赖于 Objective-C 运行时提供的动态方法决议。例如,实现一个类似`NSResponder`这种在接口中使用了目标-行为设计模式的类。绝大多数情况下,将对象转换为`AnyObject`类型,再使用可选链语法调用方法会更为安全和方便,请参阅 [id 兼容性](#id_compatibility) 小节获取更多信息。 -`perform(_:)`方法同步执行,并返回隐式解包可选类型的非托管对象(`Unmanaged!`),这是因为通过执行选择器返回的值的类型和所有权无法在编译期决定。请参阅 [非托管对象](03-Working%20with%20Cocoa%20Data%20Types.md#%E9%9D%9E%E6%89%98%E7%AE%A1%E5%AF%B9%E8%B1%A1) 小节获取更多信息。与此相反,该方法的一些变体在指定线程执行选择器,或者延迟执行,例如`perform(_:on:with:waitUntilDone:modes:)`和`perform(_:with:afterDelay:)`,它们没有返回值。 + ```swift let string: NSString = "Hello, Cocoa!" diff --git a/docs/frontend/swift/02-Interoperability/05-Interacting with C APIs.md b/docs/frontend/swift/02-Interoperability/05-Interacting with C APIs.md index 46a43f0..957850b 100644 --- a/docs/frontend/swift/02-Interoperability/05-Interacting with C APIs.md +++ b/docs/frontend/swift/02-Interoperability/05-Interacting with C APIs.md @@ -17,7 +17,7 @@ - [可变指针](#mutable_pointers) - [自动释放指针](#autoreleasing_pointers) - [函数指针](#function_pointers) - - [缓冲区指针](#buffer_pointers) + - [空指针](#null_pointers) - [指针运算](#pointer_arithmetic) - [数据类型大小计算](#data_type_size_calculation) @@ -474,7 +474,7 @@ Swift 尽可能地避免直接使用指针。不过,Swift 也提供了多种 | const void * | UnsafeRawPointer | | void * | UnsafeMutableRawPointer | -Swift 还提供了用于操作缓冲区的指针类型,如[缓冲区指针](buffer_pointers)所述。 + 如果指针的类型在 Swift 中无法表示,例如某个不完备的结构体类型,Swift 会将之导入为`OpaquePointer`。 @@ -626,143 +626,12 @@ var callbacks = CFArrayCallBacks( var mutableArray = CFArrayCreateMutable(nil, 0, &callbacks) ``` -上面的例子中,结构体`CFArrayCallBacks`的构造器使用`nil`作为参数`retain`和`release`的值,使用函数`customCopyDescription`作为参数`copyDescription`的值,最后使用一个闭包字面量作为参数`equal`的值。 +上面的例子中,结构体`CFArrayCallBacks`的构造器使用`nil`作为参数`retain`和`release`的值,使用函数`customCopyDescription`作为参数`copyDescription`的值,最后使用一个闭包字面量作为参数`equal`的值。 > 注意 > 只有使用 C 函数指针调用约定的 Swift 函数才可以作为函数指针参数。如同 C 函数指针,使用`@convention(c)`特性的 Swift 函数同样不具有捕获周围作用域上下文的能力。 更多信息请参阅 [*The Swift Programming Language 中文版*](http://wiki.jikexueyuan.com/project/swift/) 的[类型特性](http://wiki.jikexueyuan.com/project/swift/chapter3/06_Attributes.html#type_attributes)小节。 - -### 缓冲区指针 -可以利用缓冲区指针以底层方式访问内存区域。例如,你可以使用缓冲区指针来高效地在应用程序与服务器之间通讯和处理数据。 -Swift 有如下缓冲区指针类型: - -- `UnsafeBufferPointer` -- `UnsafeMutableBufferPointer` -- `UnsafeRawBufferPointer` -- `UnsafeMutableRawBufferPointer` - -`UnsafeBufferPointer`和`UnsafeMutableBufferPointer`是类型化的缓冲区指针类型,能让你将一块连续的内存作为集合来访问或修改,每一个元素都是缓冲区类型的`Element`泛型类型参数所表示的类型的实例。 - -`UnsafeRawBufferPointer`和`UnsafeMutableRawBufferPointer`是原始缓冲区指针类型,能让你将一块连续的内存作为`UInt8`值的集合来访问或修改,每个元素都对应着一字节的内存。这些类型让你能使用底层编程模式,例如抛弃编译器类型检查带来的安全性,直接操作原始内存,或者将同一块内存转换为各种不同的类型。 - - -### 空指针 - -在 Objective-C,指针类型声明可以使用`_Nullable`或`_Nonnull`来标注其值是否可以为`nil`或`NULL`。在 Swift,空指针通过值为`nil`的可选指针类型表示。通过整数表示的内存地址创建指针类型的构造器是可失败构造器。此外,不能将`nil`赋值给非可选指针类型。 - -如下表格阐明了映射关系: - -| Objective-C 语法 | Swift 语法 | -| ------ | ------ | -| const Type * _Nonnull | UnsafePointer\ | -| const Type * _Nullable | UnsafeMutablePointer\? | -| const Type * \_Null_unspecified | UnsafeMutablePointer\! | - -> 注意 -> 在 Swift 3 之前,可空指针和不可空指针都表示为非可选不安全指针类型。在将代码迁移到最新版本 Swift 的过程中,你需要将通过`nil`字面量初始化的指针标记为可选类型。 - - -### 指针运算 - -使用不透明的数据类型时,你可能需要执行不安全的指针操作。你可以对 Swift 指针值使用算术运算符来创建位于指定偏移位置的新指针。 - -```swift -let pointer: UnsafePointer -let offsetPointer = pointer + 24 -// offsetPointer 是个前进了 24 的新指针 -``` - - -## 数据类型大小计算 - -在 C 语言,`sizeof`和`alignof`运算符会返回任意变量或数据类型的大小和对齐。在 Swift,可以使用`MemoryLayout`通过其`size`,`stride`,`alignment`属性来获取`T`类型的内存布局信息。例如,获取 Darwin 中的`timeval`结构体的内存布局信息: - -```swift -print(MemoryLayout.size) -// 打印 "16" -print(MemoryLayout.stride) -// 打印 "16" -print(MemoryLayout.alignment) -// 打印 "8" -``` - -在 Swift 中使用接受某个类型或值的大小作为参数的 C 函数时就会用到这些信息。例如,`setsockopt(_:_:_:_:_:)`函数可以为套接字指定一个`timeval`值作为接收超时选项(`SO_RCVTIMEO`),需要传入`timeval`值的指针及其长度: - -```swift -let sockfd = socket(AF_INET, SOCK_STREAM, 0) -var optval = timeval(tv_sec: 30, tv_usec: 0) -let optlen = socklen_t(MemoryLayout.size) -if setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &optval, optlen) == 0 { - // ... -} -``` - -更多信息请参阅 [MemoryLayout API reference](https://developer.apple.com/reference/swift/memorylayout)。 - - -## 一次性初始化 - -在 C 语言中,POSIX 的`pthread_once()`函数,以及 GCD 的`dispatch_once()`和`dispatch_once_f()`函数,都能提供一种机制来保证初始化代码只会执行一次。在 Swift,全局常量和存储型类型属性可以确保相应的初始化过程只执行一次,即使从多个线程同时进行访问。Swift 从语言特性层面提供了这一功能,因此并未暴露相应的 POSIX 以及 GCD 函数的调用过程。 - - -## 预处理指令 - -Swift 编译器不包含预处理器,它能利用编译期特性,条件编译块,以及语言特性来实现相同的功能。因此,预处理指令不会导入到 Swift。 - - -### 简单宏 - -在 C 和 Objective-C,通常使用`#define`指令来定义一个简单的常量。在 Swift,可以使用全局常量来代替。例如,对于常量定义`#define FADE_ANIMATION_DURATION 0.35`,在 Swift 可以表示为`let FADE_ANIMATION_DURATION = 0.35`。由于定义常量的简单宏会被直接映射成 Swift 全局常量,因此 Swift 编译器会自动导入 C 或 Objective-C 源文件中定义的简单宏。 - - -### 复杂宏 - -C 和 Objective-C 的复杂宏在 Swift 中没有相对应的东西。复杂宏是那些不是用来定义常量的宏,包括带括号的函数式宏。在 C 和 Objective-C 可以使用复杂宏来避开类型检查限制或避免重复键入大量样板代码。然而,宏也会让调试和重构变得更加困难。在 Swift,可以使用函数和泛型达到同样效果。因此,C 和 Objective-C 源文件中定义的复杂宏无法在 Swift 使用。 - - -### 条件编译块 - -区别于 C 以及 Objective-C,Swift 代码以不同的方式进行条件编译。Swift 可以使用条件编译块来进行条件编译。例如,如果你使用 `swift -D DEBUG_LOGGING` 设置了条件编译标志 `DEBUG_LOGGING`,那么编译器就会编译条件编译块中的代码,如下所示: - -```swift -#if DEBUG_LOGGING -print("Flag enabled.") -#endif -``` - -编译条件可以包含 `true` 和 `false` 字面值,自定义的条件编译标志(使用 `-D <#flag#>` 来指定),以及下表中列出的平台条件。 - -| 平台条件 | 有效参数 | -| --- | --- | -| `os()` | `macOS`, `iOS`, `watchOS`, `tvOS`, `Linux` | -| `arch()` | `i386`, `x86_64`, `arm`, `arm64` | -| `swift()` | `>=`紧接版本号 | -| `canImport()` | 模块名 | -| `targetEnvironment()` | `simulator` | - -关于平台条件的更多信息,请参阅 [*The Swift Programming Language 中文版*](http://wiki.jikexueyuan.com/project/swift) 中的[条件编译块](http://wiki.jikexueyuan.com/project/swift/chapter3/10_Statements.html#build_config_statements)部分。 - -> 注意 -> 平台条件 `arch(arm)` 在 ARM 64 位的设备上不会返回 `true`。`arch(i386)` 在32位的 iOS 模拟器上会返回 `true`。 - -你可以使用 `&&` 和 `||` 运算符来组合编译条件,使用 `!` 运算符来对编译条件取反,使用 `#elseif` 和 `#else` 条件编译指令添加新的条件编译分支。你还可以在条件编译块中嵌套其他条件编译块。 - -```swift -#if arch(arm) || arch(arm64) -#if swift(>=3.0) -print("Using Swift 3 ARM code") - #else - print("Using Swift 2.2 ARM code") -#endif -#elseif arch(x86_64) -print("Using 64-bit x86 code.) - #else - print("Using general code.") -#endif -``` - -与 C 语言预处理器的条件编译不同的是,Swift 的条件编译块中的语句必须是独立且语法有效的代码,因为所有的 Swift 代码都会进行语法检查,即使某些代码不会被编译。不过也有例外情况,就是当编译条件中包含 `swift()` 平台条件时:只有编译器的 Swift 版本与平台条件中指定的 Swift 版本一致时,条件编译块中的代码才会被解析。这个例外能确保旧版本编译器不会去试图解析新版本的 Swift 语法。 diff --git a/docs/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md b/docs/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md index 1da7afd..e463cb4 100644 --- a/docs/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md +++ b/docs/frontend/swift/04-Migration/Migrating Your Objective-C Code to Swift.md @@ -37,7 +37,7 @@ * 使用 Objective-C API 的时候,你需要知道 Swift 是怎样转化某些 Objective-C 语言特性的。更多信息请参阅[与 Objective-C API 交互](../02-Interoperability/01-Interacting%20with%20Objective-C%20APIs.md)章节。 -* 使用 Cocoa 框架的代码时,记住某些类型已经被桥接,这意味着可以使用 Swift 类型去替代 Objective-C 类型。更多信息请参阅[使用 Cocoa 框架](../02-Interoperability/03-Working%20with%20Cocoa%20Frameworks.md)章节。 + * 使用 Cocoa 设计模式的时候,请参阅[采用 Cocoa 设计模式](../02-Interoperability/04-Adopting%20Cocoa%20Design%20Patterns.md)章节。 diff --git a/docs/frontend/swift/index.md b/docs/frontend/swift/index.md index 320bdaf..d9aa7d9 100644 --- a/docs/frontend/swift/index.md +++ b/docs/frontend/swift/index.md @@ -6,7 +6,7 @@ #### 交互 - [与 Objective-C API 交互](02-Interoperability/01-Interacting%20with%20Objective-C%20APIs.md) - [使用 Objective-C 特性编写 Swift 类和协议](02-Interoperability/02-Writing%20Swift%20Classes%20and%20Protocols%20with%20Objective-C%20Behavior.md) -- [使用 Cocoa 框架](02-Interoperability/03-Working%20with%20Cocoa%20Frameworks.md) + - [采用 Cocoa 设计模式](02-Interoperability/04-Adopting%20Cocoa%20Design%20Patterns.md) - [与 C 语言 API 交互](02-Interoperability/05-Interacting%20with%20C%20APIs.md) diff --git a/docs/guide/markdown-extension.md b/docs/guide/markdown-extension.md index 308c49d..016bc6f 100644 --- a/docs/guide/markdown-extension.md +++ b/docs/guide/markdown-extension.md @@ -74,7 +74,7 @@ lang: en-US 此数据将可用于页面的其余部分,以及所有自定义和主题组件。 -更多信息,参见 [frontmatter](../reference/frontmatter-config)。 + ## GitHub 风格的表格 {#github-style-tables} @@ -343,7 +343,7 @@ export default { 在 Shiki 的代码仓库中,可以找到[合法的编程语言列表](https://shiki.style/languages)。 -还可以全局配置中自定义语法高亮主题。有关详细信息,参见 [`markdown` 选项](../reference/site-config#markdown)得到更多信息。 + ## 在代码块中实现行高亮 {#line-highlighting-in-code-blocks} @@ -549,7 +549,7 @@ export default { } ``` -查看 [`markdown` 选项](../reference/site-config#markdown) 获取更多信息。 + 可以在代码块中添加 `:line-numbers` / `:no-line-numbers` 标记来覆盖在配置中的设置。 @@ -924,4 +924,4 @@ export default defineConfig({ }) ``` -请查看[配置参考:站点配置](../reference/site-config#markdown)来获取完整的可配置属性列表。 + diff --git a/docs/guide/markdown.md b/docs/guide/markdown.md index 09b25a7..53948a0 100644 --- a/docs/guide/markdown.md +++ b/docs/guide/markdown.md @@ -167,7 +167,7 @@ https://github.com/guodongxiaren/ImageCache/raw/master/Logo/foryou.gif |语法|效果| |----|-----| |`[我的简介](/example/profile.md)`|[我的简介](./profile.md)| -|`[example](./example)`|[example](./example)| + ### 图片链接 给图片加链接的本质是混合图片显示语法和普通的链接语法。普通的链接中[ ]内部是链接要显示的文本,而图片链接[ ]里面则是要显示的图片。 diff --git a/docs/network/https-tips.md b/docs/network/https-tips.md index 4e6fab8..62a1410 100644 --- a/docs/network/https-tips.md +++ b/docs/network/https-tips.md @@ -55,7 +55,7 @@ typedef NS_ENUM(NSInteger, NSURLSessionAuthChallengeDisposition) { ``` -参考:[http://www.cnblogs.com/Mike-zh/p/5174238.html](HTTPS访问控制) +参考:![HTTPS访问控制](http://www.cnblogs.com/Mike-zh/p/5174238.html) diff --git a/docs/public/img/in-post/media/14925147353647/14925147448923.jpg b/docs/public/img/in-post/media/14925147353647/14925147448923.jpg new file mode 100644 index 0000000..4c528d7 Binary files /dev/null and b/docs/public/img/in-post/media/14925147353647/14925147448923.jpg differ diff --git a/docs/public/img/in-post/media/14925152141994/14925198369392.jpg b/docs/public/img/in-post/media/14925152141994/14925198369392.jpg new file mode 100644 index 0000000..23594ae Binary files /dev/null and b/docs/public/img/in-post/media/14925152141994/14925198369392.jpg differ diff --git a/docs/public/img/in-post/media/14925152141994/14925202210363.jpg b/docs/public/img/in-post/media/14925152141994/14925202210363.jpg new file mode 100644 index 0000000..a96bd3c Binary files /dev/null and b/docs/public/img/in-post/media/14925152141994/14925202210363.jpg differ diff --git a/docs/public/img/in-post/media/14925152141994/14925722696364.jpg b/docs/public/img/in-post/media/14925152141994/14925722696364.jpg new file mode 100644 index 0000000..dffe290 Binary files /dev/null and b/docs/public/img/in-post/media/14925152141994/14925722696364.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925860141113.jpg b/docs/public/img/in-post/media/14925836417059/14925860141113.jpg new file mode 100644 index 0000000..6ac7ee1 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925860141113.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925879419077.jpg b/docs/public/img/in-post/media/14925836417059/14925879419077.jpg new file mode 100644 index 0000000..df1c7f4 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925879419077.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925882391902.jpg b/docs/public/img/in-post/media/14925836417059/14925882391902.jpg new file mode 100644 index 0000000..19933f0 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925882391902.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925884065523.jpg b/docs/public/img/in-post/media/14925836417059/14925884065523.jpg new file mode 100644 index 0000000..e5fc376 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925884065523.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925884615265.jpg b/docs/public/img/in-post/media/14925836417059/14925884615265.jpg new file mode 100644 index 0000000..06f5cfe Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925884615265.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925891251063.jpg b/docs/public/img/in-post/media/14925836417059/14925891251063.jpg new file mode 100644 index 0000000..4dce54f Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925891251063.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925893095808.jpg b/docs/public/img/in-post/media/14925836417059/14925893095808.jpg new file mode 100644 index 0000000..8675b7b Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925893095808.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925894119822.jpg b/docs/public/img/in-post/media/14925836417059/14925894119822.jpg new file mode 100644 index 0000000..c7b8f90 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925894119822.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925896301467.jpg b/docs/public/img/in-post/media/14925836417059/14925896301467.jpg new file mode 100644 index 0000000..fc65df4 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925896301467.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14925945787875.jpg b/docs/public/img/in-post/media/14925836417059/14925945787875.jpg new file mode 100644 index 0000000..feeff87 Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14925945787875.jpg differ diff --git a/docs/public/img/in-post/media/14925836417059/14926599993618.jpg b/docs/public/img/in-post/media/14925836417059/14926599993618.jpg new file mode 100644 index 0000000..67532af Binary files /dev/null and b/docs/public/img/in-post/media/14925836417059/14926599993618.jpg differ diff --git a/docs/public/img/in-post/media/15111440909345/15111445428655.jpg b/docs/public/img/in-post/media/15111440909345/15111445428655.jpg new file mode 100644 index 0000000..97f73c2 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/15111445428655.jpg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG4161.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG4161.jpeg new file mode 100644 index 0000000..e5d7f0a Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG4161.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG4162.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG4162.jpeg new file mode 100644 index 0000000..247d343 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG4162.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG4163.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG4163.jpeg new file mode 100644 index 0000000..c68bfa7 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG4163.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG53.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG53.jpeg new file mode 100644 index 0000000..ec2865e Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG53.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG54.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG54.jpeg new file mode 100644 index 0000000..488da28 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG54.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG55.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG55.jpeg new file mode 100644 index 0000000..741ef29 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG55.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG56.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG56.jpeg new file mode 100644 index 0000000..4007dfa Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG56.jpeg differ diff --git a/docs/public/img/in-post/media/15111440909345/WechatIMG57.jpeg b/docs/public/img/in-post/media/15111440909345/WechatIMG57.jpeg new file mode 100644 index 0000000..0a7cfd9 Binary files /dev/null and b/docs/public/img/in-post/media/15111440909345/WechatIMG57.jpeg differ