From b6e2fda7ebf76790de791814cd1ef6eedeb67c7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 15 Nov 2025 17:19:55 +0000 Subject: [PATCH] Deploy to GitHub pages --- .nojekyll | 0 404.html | 34 ++ assets/404.html-6Yl8cQE3.js | 1 + assets/404.html-UdYhvg0G.js | 1 + assets/about.html-6Xw5XEhi.js | 1 + assets/about.html-AyhWm9Wa.js | 16 + assets/about.html-h4rdh_fS.js | 1 + assets/about.html-jqvjl3Ob.js | 16 + assets/app-aH6YcK-Q.js | 16 + assets/changelog.html-HK_jZl0_.js | 1 + assets/changelog.html-OIxI57Wq.js | 1 + assets/changelog.html-dsukWq08.js | 1 + assets/changelog.html-xI7_Sq17.js | 1 + assets/contacts.html-fepWrcVL.js | 1 + assets/contacts.html-mhfINZEn.js | 1 + assets/contacts.html-oiF8uxsH.js | 1 + assets/contacts.html-umJCUAv2.js | 1 + assets/future.html-LX8OEuCN.js | 1 + assets/future.html-T9ih0RxQ.js | 1 + assets/future.html-UrATvnbP.js | 1 + assets/future.html-mEvcxp6P.js | 1 + assets/home.html-2op2IBCZ.js | 11 + assets/home.html-9eiAlurd.js | 1 + assets/home.html-TFY4cEol.js | 1 + assets/home.html-no62ZQLF.js | 11 + assets/index.html-7DNoxpGZ.js | 1 + assets/index.html-7LpniZrm.js | 1 + assets/index.html-H28pjygm.js | 1 + assets/index.html-J5Mpt7Vl.js | 1 + assets/index.html-WpXt5Cz7.js | 1 + assets/index.html-zPqCtEf7.js | 1 + assets/quick-start.html-7AxcUCW_.js | 1 + assets/quick-start.html-f_E-gIx7.js | 493 ++++++++++++++++++++++++++ assets/quick-start.html-umL0lxu-.js | 461 ++++++++++++++++++++++++ assets/quick-start.html-wQnE0x98.js | 1 + assets/style-ZvMm2Cad.css | 1 + en/about/about.html | 49 +++ en/about/changelog.html | 34 ++ en/about/contacts.html | 34 ++ en/about/future.html | 34 ++ en/guide/home.html | 44 +++ en/guide/quick-start.html | 526 ++++++++++++++++++++++++++++ en/index.html | 34 ++ images/logo.svg | 16 + index.html | 34 ++ zh-cn/about/about.html | 49 +++ zh-cn/about/changelog.html | 34 ++ zh-cn/about/contacts.html | 34 ++ zh-cn/about/future.html | 34 ++ zh-cn/guide/home.html | 44 +++ zh-cn/guide/quick-start.html | 494 ++++++++++++++++++++++++++ zh-cn/index.html | 34 ++ 52 files changed, 2613 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 assets/404.html-6Yl8cQE3.js create mode 100644 assets/404.html-UdYhvg0G.js create mode 100644 assets/about.html-6Xw5XEhi.js create mode 100644 assets/about.html-AyhWm9Wa.js create mode 100644 assets/about.html-h4rdh_fS.js create mode 100644 assets/about.html-jqvjl3Ob.js create mode 100644 assets/app-aH6YcK-Q.js create mode 100644 assets/changelog.html-HK_jZl0_.js create mode 100644 assets/changelog.html-OIxI57Wq.js create mode 100644 assets/changelog.html-dsukWq08.js create mode 100644 assets/changelog.html-xI7_Sq17.js create mode 100644 assets/contacts.html-fepWrcVL.js create mode 100644 assets/contacts.html-mhfINZEn.js create mode 100644 assets/contacts.html-oiF8uxsH.js create mode 100644 assets/contacts.html-umJCUAv2.js create mode 100644 assets/future.html-LX8OEuCN.js create mode 100644 assets/future.html-T9ih0RxQ.js create mode 100644 assets/future.html-UrATvnbP.js create mode 100644 assets/future.html-mEvcxp6P.js create mode 100644 assets/home.html-2op2IBCZ.js create mode 100644 assets/home.html-9eiAlurd.js create mode 100644 assets/home.html-TFY4cEol.js create mode 100644 assets/home.html-no62ZQLF.js create mode 100644 assets/index.html-7DNoxpGZ.js create mode 100644 assets/index.html-7LpniZrm.js create mode 100644 assets/index.html-H28pjygm.js create mode 100644 assets/index.html-J5Mpt7Vl.js create mode 100644 assets/index.html-WpXt5Cz7.js create mode 100644 assets/index.html-zPqCtEf7.js create mode 100644 assets/quick-start.html-7AxcUCW_.js create mode 100644 assets/quick-start.html-f_E-gIx7.js create mode 100644 assets/quick-start.html-umL0lxu-.js create mode 100644 assets/quick-start.html-wQnE0x98.js create mode 100644 assets/style-ZvMm2Cad.css create mode 100644 en/about/about.html create mode 100644 en/about/changelog.html create mode 100644 en/about/contacts.html create mode 100644 en/about/future.html create mode 100644 en/guide/home.html create mode 100644 en/guide/quick-start.html create mode 100644 en/index.html create mode 100644 images/logo.svg create mode 100644 index.html create mode 100644 zh-cn/about/about.html create mode 100644 zh-cn/about/changelog.html create mode 100644 zh-cn/about/contacts.html create mode 100644 zh-cn/about/future.html create mode 100644 zh-cn/guide/home.html create mode 100644 zh-cn/guide/quick-start.html create mode 100644 zh-cn/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..7d49d0a --- /dev/null +++ b/404.html @@ -0,0 +1,34 @@ + + +
+ + + + + +Apache License Version 2.0
+
+Copyright (C) 2019 HighCapable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+版权所有 © 2019 HighCapable
`,2);function _(y,f){const s=c("ExternalLinkIcon");return l(),t("div",null,[i,a("blockquote",null,[a("p",null,[e("此文档由 "),a("a",d,[e("VuePress"),n(s)]),e(" 强力驱动。")])]),h,a("p",null,[a("a",b,[e("Apache-2.0"),n(s)])]),u])}const m=o(r,[["render",_],["__file","about.html.vue"]]);export{m as default}; diff --git a/assets/about.html-h4rdh_fS.js b/assets/about.html-h4rdh_fS.js new file mode 100644 index 0000000..0d14831 --- /dev/null +++ b/assets/about.html-h4rdh_fS.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-7a15fe3b","path":"/en/about/about.html","title":"About This Document","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"License","slug":"license","link":"#license","children":[]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"en/about/about.md"}');export{e as data}; diff --git a/assets/about.html-jqvjl3Ob.js b/assets/about.html-jqvjl3Ob.js new file mode 100644 index 0000000..2e052d8 --- /dev/null +++ b/assets/about.html-jqvjl3Ob.js @@ -0,0 +1,16 @@ +import{_ as o,r as t,o as c,c as l,a as e,b as a,d as n,e as p}from"./app-aH6YcK-Q.js";const i={},r=e("h1",{id:"about-this-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#about-this-document","aria-hidden":"true"},"#"),a(" About This Document")],-1),d={href:"https://v2.vuepress.vuejs.org/en",target:"_blank",rel:"noopener noreferrer"},h=e("h2",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license","aria-hidden":"true"},"#"),a(" License")],-1),b={href:"https://github.com/HighCapable/Gropify/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},u=p(`Apache License Version 2.0
+
+Copyright (C) 2019 HighCapable
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Copyright © 2019 HighCapable
`,2);function y(_,m){const s=t("ExternalLinkIcon");return c(),l("div",null,[r,e("blockquote",null,[e("p",null,[a("This document is powered by "),e("a",d,[a("VuePress"),n(s)]),a(".")])]),h,e("p",null,[e("a",b,[a("Apache-2.0"),n(s)])]),u])}const f=o(i,[["render",y],["__file","about.html.vue"]]);export{f as default}; diff --git a/assets/app-aH6YcK-Q.js b/assets/app-aH6YcK-Q.js new file mode 100644 index 0000000..3f17d88 --- /dev/null +++ b/assets/app-aH6YcK-Q.js @@ -0,0 +1,16 @@ +function _o(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;oJ?Ie(h,S,A,!0,!1,q):_(p,g,E,S,A,z,$,D,q)},$e=(h,p,g,E,S,A,z,$,D)=>{let R=0;const J=p.length;let q=h.length-1,Q=J-1;for(;R<=q&&R<=Q;){const re=h[R],ie=p[R]=D?kt(p[R]):nt(p[R]);if(jt(re,ie))w(re,ie,g,null,S,A,z,$,D);else break;R++}for(;R<=q&&R<=Q;){const re=h[q],ie=p[Q]=D?kt(p[Q]):nt(p[Q]);if(jt(re,ie))w(re,ie,g,null,S,A,z,$,D);else break;q--,Q--}if(R>q){if(R<=Q){const re=Q+1,ie=reQ)for(;R<=q;)He(h[R],S,A,!0),R++;else{const re=R,ie=R,be=new Map;for(R=ie;R<=Q;R++){const Ge=p[R]=D?kt(p[R]):nt(p[R]);Ge.key!=null&&be.set(Ge.key,R)}let _e,Te=0;const tt=Q-ie+1;let Zt=!1,Qo=0;const yn=new Array(tt);for(R=0;R=tt){He(Ge,S,A,!0);continue}let lt;if(Ge.key!=null)lt=be.get(Ge.key);else for(_e=ie;_e<=Q;_e++)if(yn[_e-ie]===0&&jt(Ge,p[_e])){lt=_e;break}lt===void 0?He(Ge,S,A,!0):(yn[lt-ie]=R+1,lt>=Qo?Qo=lt:Zt=!0,w(Ge,p[lt],g,null,S,A,z,$,D),Te++)}const Xo=Zt?Pc(yn):on;for(_e=Xo.length-1,R=tt-1;R>=0;R--){const Ge=ie+R,lt=p[Ge],Zo=Ge+1 {const{el:A,type:z,transition:$,children:D,shapeFlag:R}=h;if(R&6){Ve(h.component.subTree,p,g,E);return}if(R&128){h.suspense.move(p,g,E);return}if(R&64){z.move(h,p,g,H);return}if(z===Ee){r(A,p,g);for(let q=0;q $.enter(A),S);else{const{leave:q,delayLeave:Q,afterLeave:re}=$,ie=()=>r(A,p,g),be=()=>{q(A,()=>{ie(),re&&re()})};Q?Q(A,ie,be):be()}else r(A,p,g)},He=(h,p,g,E=!1,S=!1)=>{const{type:A,props:z,ref:$,children:D,dynamicChildren:R,shapeFlag:J,patchFlag:q,dirs:Q}=h;if($!=null&&Er($,null,g,h,!0),J&256){p.ctx.deactivate(h);return}const re=J&1&&Q,ie=!cn(h);let be;if(ie&&(be=z&&z.onVnodeBeforeUnmount)&&Ze(be,p,h),J&6)it(h.component,g,E);else{if(J&128){h.suspense.unmount(g,E);return}re&&at(h,null,p,"beforeUnmount"),J&64?h.type.remove(h,p,g,S,H,E):R&&(A!==Ee||q>0&&q&64)?Ie(R,p,g,!1,!0):(A===Ee&&q&384||!S&&J&16)&&Ie(D,p,g),E&&Et(h)}(ie&&(be=z&&z.onVnodeUnmounted)||re)&&Ke(()=>{be&&Ze(be,p,h),re&&at(h,null,p,"unmounted")},g)},Et=h=>{const{type:p,el:g,anchor:E,transition:S}=h;if(p===Ee){wt(g,E);return}if(p===An){b(h);return}const A=()=>{o(g),S&&!S.persisted&&S.afterLeave&&S.afterLeave()};if(h.shapeFlag&1&&S&&!S.persisted){const{leave:z,delayLeave:$}=S,D=()=>z(g,A);$?$(h.el,A,D):D()}else A()},wt=(h,p)=>{let g;for(;h!==p;)g=d(h),o(h),h=g;o(p)},it=(h,p,g)=>{const{bum:E,scope:S,update:A,subTree:z,um:$}=h;E&&zr(E),S.stop(),A&&(A.active=!1,He(z,h,p,g)),$&&Ke($,p),Ke(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},Ie=(h,p,g,E=!1,S=!1,A=0)=>{for(let z=A;z h.shapeFlag&6?x(h.component.subTree):h.shapeFlag&128?h.suspense.next():d(h.anchor||h.el),U=(h,p,g)=>{h==null?p._vnode&&He(p._vnode,null,null,!0):w(p._vnode||null,h,p,null,null,null,g),as(),gr(),p._vnode=h},H={p:w,um:He,m:Ve,r:Et,mt:te,mc:_,pc:V,pbc:P,n:x,o:e};let G,ae;return t&&([G,ae]=t(H)),{render:U,hydrate:G,createApp:Ec(U,G)}}function Ht({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function ol(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function sl(e,t,n=!1){const r=e.children,o=t.children;if(X(r)&&X(o))for(let s=0;s >1,e[n[a]] 0&&(t[r]=n[s-1]),n[s]=r)}}for(s=n.length,i=n[s-1];s-- >0;)n[s]=i,i=t[i];return n}const Rc=e=>e.__isTeleport,Ee=Symbol.for("v-fgt"),fn=Symbol.for("v-txt"),Qe=Symbol.for("v-cmt"),An=Symbol.for("v-stc"),Pn=[];let ot=null;function j(e=!1){Pn.push(ot=e?null:[])}function Oc(){Pn.pop(),ot=Pn[Pn.length-1]||null}let Mn=1;function ys(e){Mn+=e}function il(e){return e.dynamicChildren=Mn>0?ot||on:null,Oc(),Mn>0&&ot&&ot.push(e),e}function Z(e,t,n,r,o,s){return il(de(e,t,n,r,o,s,!0))}function ke(e,t,n,r,o){return il(ne(e,t,n,r,o,!0))}function wr(e){return e?e.__v_isVNode===!0:!1}function jt(e,t){return e.type===t.type&&e.key===t.key}const Nr="__vInternal",ll=({key:e})=>e??null,fr=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?me(e)||ze(e)||oe(e)?{i:Me,r:e,k:t,f:!!n}:e:null);function de(e,t=null,n=null,r=0,o=null,s=e===Ee?0:1,i=!1,a=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ll(t),ref:t&&fr(t),scopeId:Bi,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:s,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:Me};return a?(No(l,n),s&128&&e.normalize(l)):n&&(l.shapeFlag|=me(n)?8:16),Mn>0&&!i&&ot&&(l.patchFlag>0||s&6)&&l.patchFlag!==32&&ot.push(l),l}const ne=Ic;function Ic(e,t=null,n=null,r=0,o=null,s=!1){if((!e||e===Qa)&&(e=Qe),wr(e)){const a=$t(e,t,!0);return n&&No(a,n),Mn>0&&!s&&ot&&(a.shapeFlag&6?ot[ot.indexOf(e)]=a:ot.push(a)),a.patchFlag|=-2,a}if(Vc(e)&&(e=e.__vccOpts),t){t=$c(t);let{class:a,style:l}=t;a&&!me(a)&&(t.class=We(a)),Ce(l)&&(Ii(l)&&!X(l)&&(l=Re({},l)),t.style=Bn(l))}const i=me(e)?1:Za(e)?128:Rc(e)?64:Ce(e)?4:oe(e)?2:0;return de(e,t,n,r,o,i,s,!0)}function $c(e){return e?Ii(e)||Nr in e?Re({},e):e:null}function $t(e,t,n=!1){const{props:r,ref:o,patchFlag:s,children:i}=e,a=t?ho(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:a,key:a&&ll(a),ref:t&&t.ref?n&&o?X(o)?o.concat(fr(t)):[o,fr(t)]:fr(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ee?s===-1?16:s|16:s,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&$t(e.ssContent),ssFallback:e.ssFallback&&$t(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Nt(e=" ",t=0){return ne(fn,null,e,t)}function Nc(e,t){const n=ne(An,null,e);return n.staticCount=t,n}function Le(e="",t=!1){return t?(j(),ke(Qe,null,e)):ne(Qe,null,e)}function nt(e){return e==null||typeof e=="boolean"?ne(Qe):X(e)?ne(Ee,null,e.slice()):typeof e=="object"?kt(e):ne(fn,null,String(e))}function kt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:$t(e)}function No(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(X(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),No(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Nr in t)?t._ctx=Me:o===3&&Me&&(Me.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else oe(t)?(t={default:t,_ctx:Me},n=32):(t=String(t),r&64?(n=16,t=[Nt(t)]):n=8);e.children=t,e.shapeFlag|=n}function ho(...e){const t={};for(let n=0;n Ae||Me;let Ho,en,Es="__VUE_INSTANCE_SETTERS__";(en=to()[Es])||(en=to()[Es]=[]),en.push(e=>Ae=e),Ho=e=>{en.length>1?en.forEach(t=>t(e)):en[0](e)};const dn=e=>{Ho(e),e.scope.on()},qt=()=>{Ae&&Ae.scope.off(),Ho(null)};function al(e){return e.vnode.shapeFlag&4}let hn=!1;function Fc(e,t=!1){hn=t;const{props:n,children:r}=e.vnode,o=al(e);wc(e,n,o,t),Lc(e,r);const s=o?zc(e,t):void 0;return hn=!1,s}function zc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=$i(new Proxy(e.ctx,pc));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?jc(e):null;dn(e),_n();const s=Rt(r,e,0,[e.props,o]);if(bn(),qt(),gi(s)){if(s.then(qt,qt),t)return s.then(i=>{ws(e,i,t)}).catch(i=>{Vn(i,e,0)});e.asyncDep=s}else ws(e,s,t)}else cl(e,t)}function ws(e,t,n){oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ce(t)&&(e.setupState=Mi(t)),cl(e,n)}let Cs;function cl(e,t,n){const r=e.type;if(!e.render){if(!t&&Cs&&!r.render){const o=r.template||Io(e).template;if(o){const{isCustomElement:s,compilerOptions:i}=e.appContext.config,{delimiters:a,compilerOptions:l}=r,c=Re(Re({isCustomElement:s,delimiters:a},i),l);r.render=Cs(o,c)}}e.render=r.render||ut}{dn(e),_n();try{mc(e)}finally{bn(),qt()}}}function Bc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return qe(e,"get","$attrs"),t[n]}}))}function jc(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return Bc(e)},slots:e.slots,emit:e.emit,expose:t}}function Mr(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Mi($i(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in kn)return kn[n](e)},has(t,n){return n in t||n in kn}}))}function Uc(e,t=!0){return oe(e)?e.displayName||e.name:e.name||t&&e.__name}function Vc(e){return oe(e)&&"__vccOpts"in e}const B=(e,t)=>za(e,t,hn);function le(e,t,n){const r=arguments.length;return r===2?Ce(t)&&!X(t)?wr(t)?ne(e,null,[t]):ne(e,t):ne(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&wr(n)&&(n=[n]),ne(e,t,n))}const Kc=Symbol.for("v-scx"),Wc=()=>Se(Kc),qc="3.3.12",Gc="http://www.w3.org/2000/svg",Ut=typeof document<"u"?document:null,xs=Ut&&Ut.createElement("template"),Yc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?Ut.createElementNS(Gc,e):Ut.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Ut.createTextNode(e),createComment:e=>Ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,s){const i=n?n.previousSibling:t.lastChild;if(o&&(o===s||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===s||!(o=o.nextSibling)););else{xs.innerHTML=r?``:e;const a=xs.content;if(r){const l=a.firstChild;for(;l.firstChild;)a.appendChild(l.firstChild);a.removeChild(l)}t.insertBefore(a,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Lt="transition",En="animation",Hn=Symbol("_vtc"),Gn=(e,{slots:t})=>le(rc,Jc(e),t);Gn.displayName="Transition";const ul={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};Gn.props=Re({},Wi,ul);const Dt=(e,t=[])=>{X(e)?e.forEach(n=>n(...t)):e&&e(...t)},Ls=e=>e?X(e)?e.some(t=>t.length>1):e.length>1:!1;function Jc(e){const t={};for(const C in e)C in ul||(t[C]=e[C]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:s=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:l=s,appearActiveClass:c=i,appearToClass:u=a,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:d=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,y=Qc(o),w=y&&y[0],L=y&&y[1],{onBeforeEnter:k,onEnter:T,onEnterCancelled:v,onLeave:b,onLeaveCancelled:F,onBeforeAppear:W=k,onAppear:M=T,onAppearCancelled:_=v}=t,I=(C,N,te)=>{Ft(C,N?u:a),Ft(C,N?c:i),te&&te()},P=(C,N)=>{C._isLeaving=!1,Ft(C,f),Ft(C,m),Ft(C,d),N&&N()},K=C=>(N,te)=>{const se=C?M:T,O=()=>I(N,C,te);Dt(se,[N,O]),Ss(()=>{Ft(N,C?l:s),St(N,C?u:a),Ls(se)||Ts(N,r,w,O)})};return Re(t,{onBeforeEnter(C){Dt(k,[C]),St(C,s),St(C,i)},onBeforeAppear(C){Dt(W,[C]),St(C,l),St(C,c)},onEnter:K(!1),onAppear:K(!0),onLeave(C,N){C._isLeaving=!0;const te=()=>P(C,N);St(C,f),eu(),St(C,d),Ss(()=>{C._isLeaving&&(Ft(C,f),St(C,m),Ls(b)||Ts(C,r,L,te))}),Dt(b,[C,te])},onEnterCancelled(C){I(C,!1),Dt(v,[C])},onAppearCancelled(C){I(C,!0),Dt(_,[C])},onLeaveCancelled(C){P(C),Dt(F,[C])}})}function Qc(e){if(e==null)return null;if(Ce(e))return[Wr(e.enter),Wr(e.leave)];{const t=Wr(e);return[t,t]}}function Wr(e){return na(e)}function St(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Hn]||(e[Hn]=new Set)).add(t)}function Ft(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Hn];n&&(n.delete(t),n.size||(e[Hn]=void 0))}function Ss(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Xc=0;function Ts(e,t,n,r){const o=e._endId=++Xc,s=()=>{o===e._endId&&r()};if(n)return setTimeout(s,n);const{type:i,timeout:a,propCount:l}=Zc(e,t);if(!i)return r();const c=i+"end";let u=0;const f=()=>{e.removeEventListener(c,d),s()},d=m=>{m.target===e&&++u>=l&&f()};setTimeout(()=>{u (n[y]||"").split(", "),o=r(`${Lt}Delay`),s=r(`${Lt}Duration`),i=ks(o,s),a=r(`${En}Delay`),l=r(`${En}Duration`),c=ks(a,l);let u=null,f=0,d=0;t===Lt?i>0&&(u=Lt,f=i,d=s.length):t===En?c>0&&(u=En,f=c,d=l.length):(f=Math.max(i,c),u=f>0?i>c?Lt:En:null,d=u?u===Lt?s.length:l.length:0);const m=u===Lt&&/\b(transform|all)(,|$)/.test(r(`${Lt}Property`).toString());return{type:u,timeout:f,propCount:d,hasTransform:m}}function ks(e,t){for(;e.length As(n)+As(e[r])))}function As(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function eu(){return document.body.offsetHeight}function tu(e,t,n){const r=e[Hn];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Do=Symbol("_vod"),Cr={beforeMount(e,{value:t},{transition:n}){e[Do]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):wn(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),wn(e,!0),r.enter(e)):r.leave(e,()=>{wn(e,!1)}):wn(e,t))},beforeUnmount(e,{value:t}){wn(e,t)}};function wn(e,t){e.style.display=t?e[Do]:"none"}const nu=Symbol("");function ru(e,t,n){const r=e.style,o=me(n);if(n&&!o){if(t&&!me(t))for(const s in t)n[s]==null&&po(r,s,"");for(const s in n)po(r,s,n[s])}else{const s=r.display;if(o){if(t!==n){const i=r[nu];i&&(n+=";"+i),r.cssText=n}}else t&&e.removeAttribute("style");Do in e&&(r.display=s)}}const Ps=/\s*!important$/;function po(e,t,n){if(X(n))n.forEach(r=>po(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=ou(e,t);Ps.test(n)?e.setProperty(Jt(r),n.replace(Ps,""),"important"):e[r]=n}}const Rs=["Webkit","Moz","ms"],qr={};function ou(e,t){const n=qr[t];if(n)return n;let r=ft(t);if(r!=="filter"&&r in e)return qr[t]=r;r=kr(r);for(let o=0;o Gr||(fu.then(()=>Gr=0),Gr=Date.now());function hu(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;et(pu(r,n.value),t,5,[r])};return n.value=e,n.attached=du(),n}function pu(e,t){if(X(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const Ns=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,mu=(e,t,n,r,o=!1,s,i,a,l)=>{t==="class"?tu(e,r,o):t==="style"?ru(e,n,r):zn(t)?bo(t)||cu(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):gu(e,t,r,o))?iu(e,t,r,s,i,a,l):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),su(e,t,r,o))};function gu(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Ns(t)&&oe(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Ns(t)&&me(n)?!1:t in e}const vu={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},_u=(e,t)=>e._withKeys||(e._withKeys=n=>{if(!("key"in n))return;const r=Jt(n.key);if(t.some(o=>o===r||vu[o]===r))return e(n)}),bu=Re({patchProp:mu},Yc);let Yr,Ms=!1;function yu(){return Yr=Ms?Yr:kc(bu),Ms=!0,Yr}const Eu=(...e)=>{const t=yu().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=wu(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function wu(e){return me(e)?document.querySelector(e):e}const Cu="modulepreload",xu=function(e){return"/Gropify/"+e},Hs={},pe=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){const s=document.getElementsByTagName("link");o=Promise.all(n.map(i=>{if(i=xu(i),i in Hs)return;Hs[i]=!0;const a=i.endsWith(".css"),l=a?'[rel="stylesheet"]':"";if(!!r)for(let f=s.length-1;f>=0;f--){const d=s[f];if(d.href===i&&(!a||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${l}`))return;const u=document.createElement("link");if(u.rel=a?"stylesheet":Cu,a||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),a)return new Promise((f,d)=>{u.addEventListener("load",f),u.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})}))}return o.then(()=>t()).catch(s=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=s,window.dispatchEvent(i),!i.defaultPrevented)throw s})},Lu={"v-8daa1a0e":()=>pe(()=>import("./index.html-zPqCtEf7.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2d0a870d":()=>pe(()=>import("./index.html-J5Mpt7Vl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c0c85b84":()=>pe(()=>import("./index.html-7LpniZrm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-efb45d4c":()=>pe(()=>import("./home.html-TFY4cEol.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-72889797":()=>pe(()=>import("./quick-start.html-7AxcUCW_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7a15fe3b":()=>pe(()=>import("./about.html-h4rdh_fS.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f851d14":()=>pe(()=>import("./changelog.html-OIxI57Wq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-193cf592":()=>pe(()=>import("./contacts.html-fepWrcVL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ae7b83f2":()=>pe(()=>import("./future.html-mEvcxp6P.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41967128":()=>pe(()=>import("./about.html-6Xw5XEhi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0e6c3476":()=>pe(()=>import("./changelog.html-xI7_Sq17.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6cf86266":()=>pe(()=>import("./contacts.html-oiF8uxsH.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3106ca14":()=>pe(()=>import("./future.html-LX8OEuCN.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6a609e09":()=>pe(()=>import("./home.html-9eiAlurd.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-24840ff0":()=>pe(()=>import("./quick-start.html-wQnE0x98.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>pe(()=>import("./404.html-6Yl8cQE3.js"),__vite__mapDeps([])).then(({data:e})=>e)},Su=JSON.parse('{"base":"/Gropify/","lang":"en-US","title":"Gropify","description":"A type-safe and modern properties plugin for Gradle","head":[["link",{"rel":"icon","href":"/Gropify/images/logo.svg"}]],"locales":{"/en/":{"lang":"en-US","description":"A type-safe and modern properties plugin for Gradle"},"/zh-cn/":{"lang":"zh-CN","description":"一个类型安全且现代化的 Gradle 属性插件"}}}');var Tu=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),ku=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Tu(r);t.has(o)||(t.add(o),n.push(r))}),n},Yn=e=>/^(https?:)?\/\//.test(e),Au=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Fo=e=>Object.prototype.toString.call(e)==="[object Object]",fl=e=>e[e.length-1]==="/"?e.slice(0,-1):e,dl=e=>e[0]==="/"?e.slice(1):e,hl=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const s=o.split("/").length-r.split("/").length;return s!==0?s:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"};const pl={"v-8daa1a0e":De(()=>pe(()=>import("./index.html-7DNoxpGZ.js"),__vite__mapDeps([]))),"v-2d0a870d":De(()=>pe(()=>import("./index.html-H28pjygm.js"),__vite__mapDeps([]))),"v-c0c85b84":De(()=>pe(()=>import("./index.html-WpXt5Cz7.js"),__vite__mapDeps([]))),"v-efb45d4c":De(()=>pe(()=>import("./home.html-2op2IBCZ.js"),__vite__mapDeps([]))),"v-72889797":De(()=>pe(()=>import("./quick-start.html-f_E-gIx7.js"),__vite__mapDeps([]))),"v-7a15fe3b":De(()=>pe(()=>import("./about.html-jqvjl3Ob.js"),__vite__mapDeps([]))),"v-3f851d14":De(()=>pe(()=>import("./changelog.html-HK_jZl0_.js"),__vite__mapDeps([]))),"v-193cf592":De(()=>pe(()=>import("./contacts.html-umJCUAv2.js"),__vite__mapDeps([]))),"v-ae7b83f2":De(()=>pe(()=>import("./future.html-T9ih0RxQ.js"),__vite__mapDeps([]))),"v-41967128":De(()=>pe(()=>import("./about.html-AyhWm9Wa.js"),__vite__mapDeps([]))),"v-0e6c3476":De(()=>pe(()=>import("./changelog.html-dsukWq08.js"),__vite__mapDeps([]))),"v-6cf86266":De(()=>pe(()=>import("./contacts.html-mhfINZEn.js"),__vite__mapDeps([]))),"v-3106ca14":De(()=>pe(()=>import("./future.html-UrATvnbP.js"),__vite__mapDeps([]))),"v-6a609e09":De(()=>pe(()=>import("./home.html-no62ZQLF.js"),__vite__mapDeps([]))),"v-24840ff0":De(()=>pe(()=>import("./quick-start.html-umL0lxu-.js"),__vite__mapDeps([]))),"v-3706649a":De(()=>pe(()=>import("./404.html-UdYhvg0G.js"),__vite__mapDeps([])))};var Pu=Symbol(""),ml=Symbol(""),Ru=Un({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),Gt=()=>{const e=Se(ml);if(!e)throw new Error("pageData() is called without provider.");return e},gl=Symbol(""),vt=()=>{const e=Se(gl);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},vl=Symbol(""),Ou=()=>{const e=Se(vl);if(!e)throw new Error("usePageHead() is called without provider.");return e},Iu=Symbol(""),_l=Symbol(""),$u=()=>{const e=Se(_l);if(!e)throw new Error("usePageLang() is called without provider.");return e},bl=Symbol(""),Nu=()=>{const e=Se(bl);if(!e)throw new Error("usePageLayout() is called without provider.");return e},Mu=ve(Lu),zo=Symbol(""),Jn=()=>{const e=Se(zo);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},rn=ve(Su),yl=()=>rn,El=Symbol(""),Bo=()=>{const e=Se(El);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},Hu=Symbol(""),Du="Layout",Fu="NotFound",ht=jn({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageData:async e=>{const t=Mu.value[e];return await(t==null?void 0:t())??Ru},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=me(t.description)?t.description:n.description,o=[...X(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return ku(o)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let n;if(e.path){const r=e.frontmatter.layout;me(r)?n=r:n=Du}else n=Fu;return t[n]},resolveRouteLocale:(e,t)=>hl(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),jo=ce({name:"ClientOnly",setup(e,t){const n=ve(!1);return Ue(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),zu=ce({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Gt(),n=B(()=>pl[e.pageKey||t.value.key]);return()=>n.value?le(n.value):le("div","404 Not Found")}}),Mt=(e={})=>e,Uo=e=>Yn(e)?e:`/Gropify/${dl(e)}`;function wl(e,t,n){var r,o,s;t===void 0&&(t=50),n===void 0&&(n={});var i=(r=n.isImmediate)!=null&&r,a=(o=n.callback)!=null&&o,l=n.maxWait,c=Date.now(),u=[];function f(){if(l!==void 0){var m=Date.now()-c;if(m+t>=l)return l-m}return t}var d=function(){var m=[].slice.call(arguments),y=this;return new Promise(function(w,L){var k=i&&s===void 0;if(s!==void 0&&clearTimeout(s),s=setTimeout(function(){if(s=void 0,c=Date.now(),!i){var v=e.apply(y,m);a&&a(v),u.forEach(function(b){return(0,b.resolve)(v)}),u=[]}},f()),k){var T=e.apply(y,m);return a&&a(T),w(T)}u.push({resolve:w,reject:L})})};return d.cancel=function(m){s!==void 0&&clearTimeout(s),u.forEach(function(y){return(0,y.reject)(m)}),u=[]},d}/*! + * vue-router v4.2.5 + * (c) 2023 Eduardo San Martin Morote + * @license MIT + */const nn=typeof window<"u";function Bu(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const ge=Object.assign;function Jr(e,t){const n={};for(const r in t){const o=t[r];n[r]=st(o)?o.map(e):e(o)}return n}const Rn=()=>{},st=Array.isArray,ju=/\/$/,Uu=e=>e.replace(ju,"");function Qr(e,t,n="/"){let r,o={},s="",i="";const a=t.indexOf("#");let l=t.indexOf("?");return a =0&&(l=-1),l>-1&&(r=t.slice(0,l),s=t.slice(l+1,a>-1?a:t.length),o=e(s)),a>-1&&(r=r||t.slice(0,a),i=t.slice(a,t.length)),r=qu(r??t,n),{fullPath:r+(s&&"?")+s+i,path:r,query:o,hash:i}}function Vu(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Ds(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Ku(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&pn(t.matched[r],n.matched[o])&&Cl(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function pn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Cl(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!Wu(e[n],t[n]))return!1;return!0}function Wu(e,t){return st(e)?Fs(e,t):st(t)?Fs(t,e):e===t}function Fs(e,t){return st(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function qu(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),o=r[r.length-1];(o===".."||o===".")&&r.push("");let s=n.length-1,i,a;for(i=0;i 1&&s--;else break;return n.slice(0,s).join("/")+"/"+r.slice(i-(i===r.length?1:0)).join("/")}var Dn;(function(e){e.pop="pop",e.push="push"})(Dn||(Dn={}));var On;(function(e){e.back="back",e.forward="forward",e.unknown=""})(On||(On={}));function Gu(e){if(!e)if(nn){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Uu(e)}const Yu=/^[^#]+#/;function Ju(e,t){return e.replace(Yu,"#")+t}function Qu(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const Hr=()=>({left:window.pageXOffset,top:window.pageYOffset});function Xu(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),o=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=Qu(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.pageXOffset,t.top!=null?t.top:window.pageYOffset)}function zs(e,t){return(history.state?history.state.position-t:-1)+e}const mo=new Map;function Zu(e,t){mo.set(e,t)}function ef(e){const t=mo.get(e);return mo.delete(e),t}let tf=()=>location.protocol+"//"+location.host;function xl(e,t){const{pathname:n,search:r,hash:o}=t,s=e.indexOf("#");if(s>-1){let a=o.includes(e.slice(s))?e.slice(s).length:1,l=o.slice(a);return l[0]!=="/"&&(l="/"+l),Ds(l,"")}return Ds(n,e)+r+o}function nf(e,t,n,r){let o=[],s=[],i=null;const a=({state:d})=>{const m=xl(e,location),y=n.value,w=t.value;let L=0;if(d){if(n.value=m,t.value=d,i&&i===y){i=null;return}L=w?d.position-w.position:0}else r(m);o.forEach(k=>{k(n.value,y,{delta:L,type:Dn.pop,direction:L?L>0?On.forward:On.back:On.unknown})})};function l(){i=n.value}function c(d){o.push(d);const m=()=>{const y=o.indexOf(d);y>-1&&o.splice(y,1)};return s.push(m),m}function u(){const{history:d}=window;d.state&&d.replaceState(ge({},d.state,{scroll:Hr()}),"")}function f(){for(const d of s)d();s=[],window.removeEventListener("popstate",a),window.removeEventListener("beforeunload",u)}return window.addEventListener("popstate",a),window.addEventListener("beforeunload",u,{passive:!0}),{pauseListeners:l,listen:c,destroy:f}}function Bs(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?Hr():null}}function rf(e){const{history:t,location:n}=window,r={value:xl(e,n)},o={value:t.state};o.value||s(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function s(l,c,u){const f=e.indexOf("#"),d=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+l:tf()+e+l;try{t[u?"replaceState":"pushState"](c,"",d),o.value=c}catch(m){console.error(m),n[u?"replace":"assign"](d)}}function i(l,c){const u=ge({},t.state,Bs(o.value.back,l,o.value.forward,!0),c,{position:o.value.position});s(l,u,!0),r.value=l}function a(l,c){const u=ge({},o.value,t.state,{forward:l,scroll:Hr()});s(u.current,u,!0);const f=ge({},Bs(r.value,l,null),{position:u.position+1},c);s(l,f,!1),r.value=l}return{location:r,state:o,push:a,replace:i}}function of(e){e=Gu(e);const t=rf(e),n=nf(e,t.state,t.location,t.replace);function r(s,i=!0){i||n.pauseListeners(),history.go(s)}const o=ge({location:"",base:e,go:r,createHref:Ju.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}function sf(e){return typeof e=="string"||e&&typeof e=="object"}function Ll(e){return typeof e=="string"||typeof e=="symbol"}const pt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Sl=Symbol("");var js;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(js||(js={}));function mn(e,t){return ge(new Error,{type:e,[Sl]:!0},t)}function dt(e,t){return e instanceof Error&&Sl in e&&(t==null||!!(e.type&t))}const Us="[^/]+?",lf={sensitive:!1,strict:!1,start:!0,end:!0},af=/[.+*?^${}()[\]/\\]/g;function cf(e,t){const n=ge({},lf,t),r=[];let o=n.start?"^":"";const s=[];for(const c of e){const u=c.length?[]:[90];n.strict&&!c.length&&(o+="/");for(let f=0;f t.length?t.length===1&&t[0]===80?1:-1:0}function ff(e,t){let n=0;const r=e.score,o=t.score;for(;n 0&&t[t.length-1]<0}const df={type:0,value:""},hf=/[a-zA-Z0-9_]/;function pf(e){if(!e)return[[]];if(e==="/")return[[df]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${c}": ${m}`)}let n=0,r=n;const o=[];let s;function i(){s&&o.push(s),s=[]}let a=0,l,c="",u="";function f(){c&&(n===0?s.push({type:0,value:c}):n===1||n===2||n===3?(s.length>1&&(l==="*"||l==="+")&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),s.push({type:1,value:c,regexp:u,repeatable:l==="*"||l==="+",optional:l==="*"||l==="?"})):t("Invalid state to consume buffer"),c="")}function d(){c+=l}for(;a {i(T)}:Rn}function i(u){if(Ll(u)){const f=r.get(u);f&&(r.delete(u),n.splice(n.indexOf(f),1),f.children.forEach(i),f.alias.forEach(i))}else{const f=n.indexOf(u);f>-1&&(n.splice(f,1),u.record.name&&r.delete(u.record.name),u.children.forEach(i),u.alias.forEach(i))}}function a(){return n}function l(u){let f=0;for(;f =0&&(u.record.path!==n[f].record.path||!Tl(u,n[f]));)f++;n.splice(f,0,u),u.record.name&&!Ws(u)&&r.set(u.record.name,u)}function c(u,f){let d,m={},y,w;if("name"in u&&u.name){if(d=r.get(u.name),!d)throw mn(1,{location:u});w=d.record.name,m=ge(Ks(f.params,d.keys.filter(T=>!T.optional).map(T=>T.name)),u.params&&Ks(u.params,d.keys.map(T=>T.name))),y=d.stringify(m)}else if("path"in u)y=u.path,d=n.find(T=>T.re.test(y)),d&&(m=d.parse(y),w=d.record.name);else{if(d=f.name?r.get(f.name):n.find(T=>T.re.test(f.path)),!d)throw mn(1,{location:u,currentLocation:f});w=d.record.name,m=ge({},f.params,u.params),y=d.stringify(m)}const L=[];let k=d;for(;k;)L.unshift(k.record),k=k.parent;return{name:w,path:y,params:m,matched:L,meta:bf(L)}}return e.forEach(u=>s(u)),{addRoute:s,resolve:c,removeRoute:i,getRoutes:a,getRecordMatcher:o}}function Ks(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function vf(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:_f(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function _f(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function Ws(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function bf(e){return e.reduce((t,n)=>ge(t,n.meta),{})}function qs(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Tl(e,t){return t.children.some(n=>n===e||Tl(e,n))}const kl=/#/g,yf=/&/g,Ef=/\//g,wf=/=/g,Cf=/\?/g,Al=/\+/g,xf=/%5B/g,Lf=/%5D/g,Pl=/%5E/g,Sf=/%60/g,Rl=/%7B/g,Tf=/%7C/g,Ol=/%7D/g,kf=/%20/g;function Vo(e){return encodeURI(""+e).replace(Tf,"|").replace(xf,"[").replace(Lf,"]")}function Af(e){return Vo(e).replace(Rl,"{").replace(Ol,"}").replace(Pl,"^")}function go(e){return Vo(e).replace(Al,"%2B").replace(kf,"+").replace(kl,"%23").replace(yf,"%26").replace(Sf,"`").replace(Rl,"{").replace(Ol,"}").replace(Pl,"^")}function Pf(e){return go(e).replace(wf,"%3D")}function Rf(e){return Vo(e).replace(kl,"%23").replace(Cf,"%3F")}function Of(e){return e==null?"":Rf(e).replace(Ef,"%2F")}function xr(e){try{return decodeURIComponent(""+e)}catch{}return""+e}function If(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let o=0;o s&&go(s)):[r&&go(r)]).forEach(s=>{s!==void 0&&(t+=(t.length?"&":"")+n,s!=null&&(t+="="+s))})}return t}function $f(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=st(r)?r.map(o=>o==null?null:""+o):r==null?r:""+r)}return t}const Nf=Symbol(""),Ys=Symbol(""),Dr=Symbol(""),Ko=Symbol(""),vo=Symbol("");function Cn(){let e=[];function t(r){return e.push(r),()=>{const o=e.indexOf(r);o>-1&&e.splice(o,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function At(e,t,n,r,o){const s=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise((i,a)=>{const l=f=>{f===!1?a(mn(4,{from:n,to:t})):f instanceof Error?a(f):sf(f)?a(mn(2,{from:t,to:f})):(s&&r.enterCallbacks[o]===s&&typeof f=="function"&&s.push(f),i())},c=e.call(r&&r.instances[o],t,n,l);let u=Promise.resolve(c);e.length<3&&(u=u.then(l)),u.catch(f=>a(f))})}function Xr(e,t,n,r){const o=[];for(const s of e)for(const i in s.components){let a=s.components[i];if(!(t!=="beforeRouteEnter"&&!s.instances[i]))if(Mf(a)){const c=(a.__vccOpts||a)[t];c&&o.push(At(c,n,r,s,i))}else{let l=a();o.push(()=>l.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${i}" at "${s.path}"`));const u=Bu(c)?c.default:c;s.components[i]=u;const d=(u.__vccOpts||u)[t];return d&&At(d,n,r,s,i)()}))}}return o}function Mf(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Js(e){const t=Se(Dr),n=Se(Ko),r=B(()=>t.resolve(ee(e.to))),o=B(()=>{const{matched:l}=r.value,{length:c}=l,u=l[c-1],f=n.matched;if(!u||!f.length)return-1;const d=f.findIndex(pn.bind(null,u));if(d>-1)return d;const m=Qs(l[c-2]);return c>1&&Qs(u)===m&&f[f.length-1].path!==m?f.findIndex(pn.bind(null,l[c-2])):d}),s=B(()=>o.value>-1&&zf(n.params,r.value.params)),i=B(()=>o.value>-1&&o.value===n.matched.length-1&&Cl(n.params,r.value.params));function a(l={}){return Ff(l)?t[ee(e.replace)?"replace":"push"](ee(e.to)).catch(Rn):Promise.resolve()}return{route:r,href:B(()=>r.value.href),isActive:s,isExactActive:i,navigate:a}}const Hf=ce({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Js,setup(e,{slots:t}){const n=jn(Js(e)),{options:r}=Se(Dr),o=B(()=>({[Xs(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Xs(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const s=t.default&&t.default(n);return e.custom?s:le("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},s)}}}),Df=Hf;function Ff(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function zf(e,t){for(const n in t){const r=t[n],o=e[n];if(typeof r=="string"){if(r!==o)return!1}else if(!st(o)||o.length!==r.length||r.some((s,i)=>s!==o[i]))return!1}return!0}function Qs(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Xs=(e,t,n)=>e??t??n,Bf=ce({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=Se(vo),o=B(()=>e.route||r.value),s=Se(Ys,0),i=B(()=>{let c=ee(s);const{matched:u}=o.value;let f;for(;(f=u[c])&&!f.components;)c++;return c}),a=B(()=>o.value.matched[i.value]);Wt(Ys,B(()=>i.value+1)),Wt(Nf,a),Wt(vo,o);const l=ve();return Je(()=>[l.value,a.value,e.name],([c,u,f],[d,m,y])=>{u&&(u.instances[f]=c,m&&m!==u&&c&&c===d&&(u.leaveGuards.size||(u.leaveGuards=m.leaveGuards),u.updateGuards.size||(u.updateGuards=m.updateGuards))),c&&u&&(!m||!pn(u,m)||!d)&&(u.enterCallbacks[f]||[]).forEach(w=>w(c))},{flush:"post"}),()=>{const c=o.value,u=e.name,f=a.value,d=f&&f.components[u];if(!d)return Zs(n.default,{Component:d,route:c});const m=f.props[u],y=m?m===!0?c.params:typeof m=="function"?m(c):m:null,L=le(d,ge({},y,t,{onVnodeUnmounted:k=>{k.component.isUnmounted&&(f.instances[u]=null)},ref:l}));return Zs(n.default,{Component:L,route:c})||L}}});function Zs(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Il=Bf;function jf(e){const t=gf(e.routes,e),n=e.parseQuery||If,r=e.stringifyQuery||Gs,o=e.history,s=Cn(),i=Cn(),a=Cn(),l=Po(pt);let c=pt;nn&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const u=Jr.bind(null,x=>""+x),f=Jr.bind(null,Of),d=Jr.bind(null,xr);function m(x,U){let H,G;return Ll(x)?(H=t.getRecordMatcher(x),G=U):G=x,t.addRoute(G,H)}function y(x){const U=t.getRecordMatcher(x);U&&t.removeRoute(U)}function w(){return t.getRoutes().map(x=>x.record)}function L(x){return!!t.getRecordMatcher(x)}function k(x,U){if(U=ge({},U||l.value),typeof x=="string"){const g=Qr(n,x,U.path),E=t.resolve({path:g.path},U),S=o.createHref(g.fullPath);return ge(g,E,{params:d(E.params),hash:xr(g.hash),redirectedFrom:void 0,href:S})}let H;if("path"in x)H=ge({},x,{path:Qr(n,x.path,U.path).path});else{const g=ge({},x.params);for(const E in g)g[E]==null&&delete g[E];H=ge({},x,{params:f(g)}),U.params=f(U.params)}const G=t.resolve(H,U),ae=x.hash||"";G.params=u(d(G.params));const h=Vu(r,ge({},x,{hash:Af(ae),path:G.path})),p=o.createHref(h);return ge({fullPath:h,hash:ae,query:r===Gs?$f(x.query):x.query||{}},G,{redirectedFrom:void 0,href:p})}function T(x){return typeof x=="string"?Qr(n,x,l.value.path):ge({},x)}function v(x,U){if(c!==x)return mn(8,{from:U,to:x})}function b(x){return M(x)}function F(x){return b(ge(T(x),{replace:!0}))}function W(x){const U=x.matched[x.matched.length-1];if(U&&U.redirect){const{redirect:H}=U;let G=typeof H=="function"?H(x):H;return typeof G=="string"&&(G=G.includes("?")||G.includes("#")?G=T(G):{path:G},G.params={}),ge({query:x.query,hash:x.hash,params:"path"in G?{}:x.params},G)}}function M(x,U){const H=c=k(x),G=l.value,ae=x.state,h=x.force,p=x.replace===!0,g=W(H);if(g)return M(ge(T(g),{state:typeof g=="object"?ge({},ae,g.state):ae,force:h,replace:p}),U||H);const E=H;E.redirectedFrom=U;let S;return!h&&Ku(r,G,H)&&(S=mn(16,{to:E,from:G}),Ve(G,G,!0,!1)),(S?Promise.resolve(S):P(E,G)).catch(A=>dt(A)?dt(A,2)?A:$e(A):V(A,E,G)).then(A=>{if(A){if(dt(A,2))return M(ge({replace:p},T(A.to),{state:typeof A.to=="object"?ge({},ae,A.to.state):ae,force:h}),U||E)}else A=C(E,G,!0,p,ae);return K(E,G,A),A})}function _(x,U){const H=v(x,U);return H?Promise.reject(H):Promise.resolve()}function I(x){const U=wt.values().next().value;return U&&typeof U.runWithContext=="function"?U.runWithContext(x):x()}function P(x,U){let H;const[G,ae,h]=Uf(x,U);H=Xr(G.reverse(),"beforeRouteLeave",x,U);for(const g of G)g.leaveGuards.forEach(E=>{H.push(At(E,x,U))});const p=_.bind(null,x,U);return H.push(p),Ie(H).then(()=>{H=[];for(const g of s.list())H.push(At(g,x,U));return H.push(p),Ie(H)}).then(()=>{H=Xr(ae,"beforeRouteUpdate",x,U);for(const g of ae)g.updateGuards.forEach(E=>{H.push(At(E,x,U))});return H.push(p),Ie(H)}).then(()=>{H=[];for(const g of h)if(g.beforeEnter)if(st(g.beforeEnter))for(const E of g.beforeEnter)H.push(At(E,x,U));else H.push(At(g.beforeEnter,x,U));return H.push(p),Ie(H)}).then(()=>(x.matched.forEach(g=>g.enterCallbacks={}),H=Xr(h,"beforeRouteEnter",x,U),H.push(p),Ie(H))).then(()=>{H=[];for(const g of i.list())H.push(At(g,x,U));return H.push(p),Ie(H)}).catch(g=>dt(g,8)?g:Promise.reject(g))}function K(x,U,H){a.list().forEach(G=>I(()=>G(x,U,H)))}function C(x,U,H,G,ae){const h=v(x,U);if(h)return h;const p=U===pt,g=nn?history.state:{};H&&(G||p?o.replace(x.fullPath,ge({scroll:p&&g&&g.scroll},ae)):o.push(x.fullPath,ae)),l.value=x,Ve(x,U,H,p),$e()}let N;function te(){N||(N=o.listen((x,U,H)=>{if(!it.listening)return;const G=k(x),ae=W(G);if(ae){M(ge(ae,{replace:!0}),G).catch(Rn);return}c=G;const h=l.value;nn&&Zu(zs(h.fullPath,H.delta),Hr()),P(G,h).catch(p=>dt(p,12)?p:dt(p,2)?(M(p.to,G).then(g=>{dt(g,20)&&!H.delta&&H.type===Dn.pop&&o.go(-1,!1)}).catch(Rn),Promise.reject()):(H.delta&&o.go(-H.delta,!1),V(p,G,h))).then(p=>{p=p||C(G,h,!1),p&&(H.delta&&!dt(p,8)?o.go(-H.delta,!1):H.type===Dn.pop&&dt(p,20)&&o.go(-1,!1)),K(G,h,p)}).catch(Rn)}))}let se=Cn(),O=Cn(),Y;function V(x,U,H){$e(x);const G=O.list();return G.length?G.forEach(ae=>ae(x,U,H)):console.error(x),Promise.reject(x)}function Oe(){return Y&&l.value!==pt?Promise.resolve():new Promise((x,U)=>{se.add([x,U])})}function $e(x){return Y||(Y=!x,te(),se.list().forEach(([U,H])=>x?H(x):U()),se.reset()),x}function Ve(x,U,H,G){const{scrollBehavior:ae}=e;if(!nn||!ae)return Promise.resolve();const h=!H&&ef(zs(x.fullPath,0))||(G||!H)&&history.state&&history.state.scroll||null;return Kn().then(()=>ae(x,U,h)).then(p=>p&&Xu(p)).catch(p=>V(p,x,U))}const He=x=>o.go(x);let Et;const wt=new Set,it={currentRoute:l,listening:!0,addRoute:m,removeRoute:y,hasRoute:L,getRoutes:w,resolve:k,options:e,push:b,replace:F,go:He,back:()=>He(-1),forward:()=>He(1),beforeEach:s.add,beforeResolve:i.add,afterEach:a.add,onError:O.add,isReady:Oe,install(x){const U=this;x.component("RouterLink",Df),x.component("RouterView",Il),x.config.globalProperties.$router=U,Object.defineProperty(x.config.globalProperties,"$route",{enumerable:!0,get:()=>ee(l)}),nn&&!Et&&l.value===pt&&(Et=!0,b(o.location).catch(ae=>{}));const H={};for(const ae in pt)Object.defineProperty(H,ae,{get:()=>l.value[ae],enumerable:!0});x.provide(Dr,U),x.provide(Ko,Oi(H)),x.provide(vo,l);const G=x.unmount;wt.add(x),x.unmount=function(){wt.delete(x),wt.size<1&&(c=pt,N&&N(),N=null,l.value=pt,Et=!1,Y=!1),G()}}};function Ie(x){return x.reduce((U,H)=>U.then(()=>I(H)),Promise.resolve())}return it}function Uf(e,t){const n=[],r=[],o=[],s=Math.max(t.matched.length,e.matched.length);for(let i=0;i pn(c,a))?r.push(a):n.push(a));const l=e.matched[i];l&&(t.matched.find(c=>pn(c,l))||o.push(l))}return[n,r,o]}function Qt(){return Se(Dr)}function Xt(){return Se(Ko)}const Vf=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:r=5})=>{const o=Qt(),i=wl(()=>{var w,L;const a=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(a-0)d.some(T=>T.hash===k.hash));for(let k=0;k =(((w=T.parentElement)==null?void 0:w.offsetTop)??0)-r,F=!v||a<(((L=v.parentElement)==null?void 0:L.offsetTop)??0)-r;if(!(b&&F))continue;const M=decodeURIComponent(o.currentRoute.value.hash),_=decodeURIComponent(T.hash);if(M===_)return;if(f){for(let I=k+1;I {window.addEventListener("scroll",i)}),qn(()=>{window.removeEventListener("scroll",i)})},ei=async(e,t)=>{const{scrollBehavior:n}=e.options;e.options.scrollBehavior=void 0,await e.replace({query:e.currentRoute.value.query,hash:t}).finally(()=>e.options.scrollBehavior=n)},Kf="a.sidebar-item",Wf=".header-anchor",qf=300,Gf=5,Yf=Mt({setup(){Vf({headerLinkSelector:Kf,headerAnchorSelector:Wf,delay:qf,offset:Gf})}}),ti=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Jf=()=>window.scrollTo({top:0,behavior:"smooth"}),Qf=ce({name:"BackToTop",setup(){const e=ve(0),t=B(()=>e.value>300),n=wl(()=>{e.value=ti()},100);Ue(()=>{e.value=ti(),window.addEventListener("scroll",()=>n())});const r=le("div",{class:"back-to-top",onClick:Jf});return()=>le(Gn,{name:"back-to-top"},()=>t.value?r:null)}}),Xf=Mt({rootComponents:[Qf]}),Zf=le("svg",{class:"external-link-icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[le("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),le("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),ed=ce({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=Jn(),n=B(()=>e.locales[t.value]??{openInNewWindow:"open in new window"});return()=>le("span",[Zf,le("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}});var td={"/en/":{openInNewWindow:"open in new window"},"/zh-cn/":{openInNewWindow:"在新窗口中打开"},"/":{openInNewWindow:"open in new window"}};const nd=td,rd=Mt({enhance({app:e}){e.component("ExternalLinkIcon",le(ed,{locales:nd}))}});/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */var zt=Object.assign||function(e){for(var t=1;t 1&&arguments[1]!==void 0?arguments[1]:{},r=window.Promise||function(C){function N(){}C(N,N)},o=function(C){var N=C.target;if(N===I){y();return}v.indexOf(N)!==-1&&w({target:N})},s=function(){if(!(F||!_.original)){var C=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(W-C)>M.scrollOffset&&setTimeout(y,150)}},i=function(C){var N=C.key||C.keyCode;(N==="Escape"||N==="Esc"||N===27)&&y()},a=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},N=C;if(C.background&&(I.style.background=C.background),C.container&&C.container instanceof Object&&(N.container=zt({},M.container,C.container)),C.template){var te=dr(C.template)?C.template:document.querySelector(C.template);N.template=te}return M=zt({},M,N),v.forEach(function(se){se.dispatchEvent(tn("medium-zoom:update",{detail:{zoom:P}}))}),P},l=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(zt({},M,C))},c=function(){for(var C=arguments.length,N=Array(C),te=0;te 0?N.reduce(function(O,Y){return[].concat(O,ri(Y))},[]):v;return se.forEach(function(O){O.classList.remove("medium-zoom-image"),O.dispatchEvent(tn("medium-zoom:detach",{detail:{zoom:P}}))}),v=v.filter(function(O){return se.indexOf(O)===-1}),P},f=function(C,N){var te=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return v.forEach(function(se){se.addEventListener("medium-zoom:"+C,N,te)}),b.push({type:"medium-zoom:"+C,listener:N,options:te}),P},d=function(C,N){var te=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return v.forEach(function(se){se.removeEventListener("medium-zoom:"+C,N,te)}),b=b.filter(function(se){return!(se.type==="medium-zoom:"+C&&se.listener.toString()===N.toString())}),P},m=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},N=C.target,te=function(){var O={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},Y=void 0,V=void 0;if(M.container)if(M.container instanceof Object)O=zt({},O,M.container),Y=O.width-O.left-O.right-M.margin*2,V=O.height-O.top-O.bottom-M.margin*2;else{var Oe=dr(M.container)?M.container:document.querySelector(M.container),$e=Oe.getBoundingClientRect(),Ve=$e.width,He=$e.height,Et=$e.left,wt=$e.top;O=zt({},O,{width:Ve,height:He,left:Et,top:wt})}Y=Y||O.width-M.margin*2,V=V||O.height-M.margin*2;var it=_.zoomedHd||_.original,Ie=ni(it)?Y:it.naturalWidth||Y,x=ni(it)?V:it.naturalHeight||V,U=it.getBoundingClientRect(),H=U.top,G=U.left,ae=U.width,h=U.height,p=Math.min(Math.max(ae,Ie),Y)/ae,g=Math.min(Math.max(h,x),V)/h,E=Math.min(p,g),S=(-G+(Y-ae)/2+M.margin+O.left)/E,A=(-H+(V-h)/2+M.margin+O.top)/E,z="scale("+E+") translate3d("+S+"px, "+A+"px, 0)";_.zoomed.style.transform=z,_.zoomedHd&&(_.zoomedHd.style.transform=z)};return new r(function(se){if(N&&v.indexOf(N)===-1){se(P);return}var O=function Ve(){F=!1,_.zoomed.removeEventListener("transitionend",Ve),_.original.dispatchEvent(tn("medium-zoom:opened",{detail:{zoom:P}})),se(P)};if(_.zoomed){se(P);return}if(N)_.original=N;else if(v.length>0){var Y=v;_.original=Y[0]}else{se(P);return}if(_.original.dispatchEvent(tn("medium-zoom:open",{detail:{zoom:P}})),W=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,F=!0,_.zoomed=id(_.original),document.body.appendChild(I),M.template){var V=dr(M.template)?M.template:document.querySelector(M.template);_.template=document.createElement("div"),_.template.appendChild(V.content.cloneNode(!0)),document.body.appendChild(_.template)}if(_.original.parentElement&&_.original.parentElement.tagName==="PICTURE"&&_.original.currentSrc&&(_.zoomed.src=_.original.currentSrc),document.body.appendChild(_.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),_.original.classList.add("medium-zoom-image--hidden"),_.zoomed.classList.add("medium-zoom-image--opened"),_.zoomed.addEventListener("click",y),_.zoomed.addEventListener("transitionend",O),_.original.getAttribute("data-zoom-src")){_.zoomedHd=_.zoomed.cloneNode(),_.zoomedHd.removeAttribute("srcset"),_.zoomedHd.removeAttribute("sizes"),_.zoomedHd.removeAttribute("loading"),_.zoomedHd.src=_.zoomed.getAttribute("data-zoom-src"),_.zoomedHd.onerror=function(){clearInterval(Oe),console.warn("Unable to reach the zoom image target "+_.zoomedHd.src),_.zoomedHd=null,te()};var Oe=setInterval(function(){_.zoomedHd.complete&&(clearInterval(Oe),_.zoomedHd.classList.add("medium-zoom-image--opened"),_.zoomedHd.addEventListener("click",y),document.body.appendChild(_.zoomedHd),te())},10)}else if(_.original.hasAttribute("srcset")){_.zoomedHd=_.zoomed.cloneNode(),_.zoomedHd.removeAttribute("sizes"),_.zoomedHd.removeAttribute("loading");var $e=_.zoomedHd.addEventListener("load",function(){_.zoomedHd.removeEventListener("load",$e),_.zoomedHd.classList.add("medium-zoom-image--opened"),_.zoomedHd.addEventListener("click",y),document.body.appendChild(_.zoomedHd),te()})}else te()})},y=function(){return new r(function(C){if(F||!_.original){C(P);return}var N=function te(){_.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(_.zoomed),_.zoomedHd&&document.body.removeChild(_.zoomedHd),document.body.removeChild(I),_.zoomed.classList.remove("medium-zoom-image--opened"),_.template&&document.body.removeChild(_.template),F=!1,_.zoomed.removeEventListener("transitionend",te),_.original.dispatchEvent(tn("medium-zoom:closed",{detail:{zoom:P}})),_.original=null,_.zoomed=null,_.zoomedHd=null,_.template=null,C(P)};F=!0,document.body.classList.remove("medium-zoom--opened"),_.zoomed.style.transform="",_.zoomedHd&&(_.zoomedHd.style.transform=""),_.template&&(_.template.style.transition="opacity 150ms",_.template.style.opacity=0),_.original.dispatchEvent(tn("medium-zoom:close",{detail:{zoom:P}})),_.zoomed.addEventListener("transitionend",N)})},w=function(){var C=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},N=C.target;return _.original?y():m({target:N})},L=function(){return M},k=function(){return v},T=function(){return _.original},v=[],b=[],F=!1,W=0,M=n,_={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?M=t:(t||typeof t=="string")&&c(t),M=zt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},M);var I=sd(M.background);document.addEventListener("click",o),document.addEventListener("keyup",i),document.addEventListener("scroll",s),window.addEventListener("resize",y);var P={open:m,close:y,toggle:w,update:a,clone:l,attach:c,detach:u,on:f,off:d,getOptions:L,getImages:k,getZoomedImage:T};return P};function ad(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(!e||typeof document>"u")){var r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",n==="top"&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}var cd=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";ad(cd);const ud=ld,fd=Symbol("mediumZoom");var dd={};const hd=".theme-default-content > img, .theme-default-content :not(a) > img",pd=dd,md=300,gd=Mt({enhance({app:e,router:t}){const n=ud(pd);n.refresh=(r=hd)=>{n.detach(),n.attach(r)},e.provide(fd,n),t.afterEach(()=>{setTimeout(()=>n.refresh(),md)})}});/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const ue={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:''},status:null,set:e=>{const t=ue.isStarted();e=Zr(e,ue.settings.minimum,1),ue.status=e===1?null:e;const n=ue.render(!t),r=n.querySelector(ue.settings.barSelector),o=ue.settings.speed,s=ue.settings.easing;return n.offsetWidth,vd(i=>{lr(r,{transform:"translate3d("+oi(e)+"%,0,0)",transition:"all "+o+"ms "+s}),e===1?(lr(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){lr(n,{transition:"all "+o+"ms linear",opacity:"0"}),setTimeout(function(){ue.remove(),i()},o)},o)):setTimeout(()=>i(),o)}),ue},isStarted:()=>typeof ue.status=="number",start:()=>{ue.status||ue.set(0);const e=()=>{setTimeout(()=>{ue.status&&(ue.trickle(),e())},ue.settings.trickleSpeed)};return ue.settings.trickle&&e(),ue},done:e=>!e&&!ue.status?ue:ue.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=ue.status;return t?(typeof e!="number"&&(e=(1-t)*Zr(Math.random()*t,.1,.95)),t=Zr(t+e,0,.994),ue.set(t)):ue.start()},trickle:()=>ue.inc(Math.random()*ue.settings.trickleRate),render:e=>{if(ue.isRendered())return document.getElementById("nprogress");si(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=ue.settings.template;const n=t.querySelector(ue.settings.barSelector),r=e?"-100":oi(ue.status||0),o=document.querySelector(ue.settings.parent);return lr(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),o!==document.body&&si(o,"nprogress-custom-parent"),o==null||o.appendChild(t),t},remove:()=>{ii(document.documentElement,"nprogress-busy"),ii(document.querySelector(ue.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&_d(e)},isRendered:()=>!!document.getElementById("nprogress")},Zr=(e,t,n)=>e n?n:e,oi=e=>(-1+e)*100,vd=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),lr=function(){const e=["Webkit","O","Moz","ms"],t={};function n(i){return i.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,l){return l.toUpperCase()})}function r(i){const a=document.body.style;if(i in a)return i;let l=e.length;const c=i.charAt(0).toUpperCase()+i.slice(1);let u;for(;l--;)if(u=e[l]+c,u in a)return u;return i}function o(i){return i=n(i),t[i]??(t[i]=r(i))}function s(i,a,l){a=o(a),i.style[a]=l}return function(i,a){for(const l in a){const c=a[l];c!==void 0&&Object.prototype.hasOwnProperty.call(a,l)&&s(i,l,c)}}}(),$l=(e,t)=>(typeof e=="string"?e:Wo(e)).indexOf(" "+t+" ")>=0,si=(e,t)=>{const n=Wo(e),r=n+t;$l(n,t)||(e.className=r.substring(1))},ii=(e,t)=>{const n=Wo(e);if(!$l(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},Wo=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),_d=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},bd=()=>{Ue(()=>{const e=Qt(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||ue.start()}),e.afterEach(n=>{t.add(n.path),ue.done()})})},yd=Mt({setup(){bd()}}),Ed=JSON.parse(`{"logo":"/images/logo.svg","repo":"https://github.com/HighCapable/Gropify","docsRepo":"https://github.com/HighCapable/Gropify","docsBranch":"main","docsDir":"docs-source/src","editLinkPattern":":repo/edit/:branch/:path","sidebar":{"/en/":[{"text":"Get Started","collapsible":true,"children":["/en/guide/home","/en/guide/quick-start"]},{"text":"About","collapsible":true,"children":["/en/about/changelog","/en/about/future","/en/about/contacts","/en/about/about"]}],"/zh-cn/":[{"text":"入门","collapsible":true,"children":["/zh-cn/guide/home","/zh-cn/guide/quick-start"]},{"text":"关于","collapsible":true,"children":["/zh-cn/about/changelog","/zh-cn/about/future","/zh-cn/about/contacts","/zh-cn/about/about"]}]},"sidebarDepth":2,"locales":{"/en/":{"navbar":[{"text":"Navigation","children":[{"text":"Get Started","children":["/en/guide/home","/en/guide/quick-start"]},{"text":"About","children":["/en/about/changelog","/en/about/future","/en/about/contacts","/en/about/about"]}]},{"text":"Contact Us","link":"/en/about/contacts"}],"selectLanguageText":"English (US)","selectLanguageName":"English","editLinkText":"Edit this page on GitHub","tip":"Tips","warning":"Notice","danger":"Pay Attention"},"/zh-cn/":{"navbar":[{"text":"导航","children":[{"text":"入门","children":["/zh-cn/guide/home","/zh-cn/guide/quick-start"]},{"text":"关于","children":["/zh-cn/about/changelog","/zh-cn/about/future","/zh-cn/about/contacts","/zh-cn/about/about"]}]},{"text":"联系我们","link":"/zh-cn/about/contacts"}],"selectLanguageText":"简体中文 (CN)","selectLanguageName":"简体中文","editLinkText":"在 GitHub 上编辑此页","notFound":["这里什么都没有","我们怎么到这来了?","这是一个 404 页面","看起来我们进入了错误的链接"],"backToHome":"回到首页","contributorsText":"贡献者","lastUpdatedText":"上次更新","tip":"小提示","warning":"注意","danger":"特别注意","openInNewWindow":"在新窗口中打开","toggleColorMode":"切换颜色模式"},"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"navbar":[],"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),wd=ve(Ed),Nl=()=>wd,Ml=Symbol(""),Cd=()=>{const e=Se(Ml);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},xd=(e,t)=>{const{locales:n,...r}=e;return{...r,...n==null?void 0:n[t]}},Ld=Mt({enhance({app:e}){const t=Nl(),n=e._context.provides[zo],r=B(()=>xd(t.value,n.value));e.provide(Ml,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}}),Sd=ce({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(j(),Z("span",{class:We(["badge",e.type]),style:Bn({verticalAlign:e.vertical})},[ye(t.$slots,"default",{},()=>[Nt(Pe(e.text),1)])],6))}}),xe=(e,t)=>{const n=e.__vccOpts||e;for(const[r,o]of t)n[r]=o;return n},Td=xe(Sd,[["__file","Badge.vue"]]);function li(e,t){var n;const r=Po();return Vi(()=>{r.value=e()},{...t,flush:(n=t==null?void 0:t.flush)!=null?n:"sync"}),Un(r)}function kd(e,t){let n,r,o;const s=ve(!0),i=()=>{s.value=!0,o()};Je(e,i,{flush:"sync"});const a=typeof t=="function"?t:t.get,l=typeof t=="function"?void 0:t.set,c=Ma((u,f)=>(r=u,o=f,{get(){return s.value&&(n=a(),s.value=!1),r(),n},set(d){l==null||l(d)}}));return Object.isExtensible(c)&&(c.trigger=i),c}function Hl(e){return Ei()?(fa(e),!0):!1}function gn(e){return typeof e=="function"?e():ee(e)}const Ad=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Pd=Object.prototype.toString,Rd=e=>Pd.call(e)==="[object Object]",Od=()=>{};function Id(e,t){function n(...r){return new Promise((o,s)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(o).catch(s)})}return n}const Dl=e=>e();function $d(e=Dl){const t=ve(!0);function n(){t.value=!1}function r(){t.value=!0}const o=(...s)=>{t.value&&e(...s)};return{isActive:Un(t),pause:n,resume:r,eventFilter:o}}function Nd(e){return e||Mo()}function Md(e,t,n={}){const{eventFilter:r=Dl,...o}=n;return Je(e,Id(r,t),o)}function Hd(e,t,n={}){const{eventFilter:r,...o}=n,{eventFilter:s,pause:i,resume:a,isActive:l}=$d(r);return{stop:Md(e,t,{...o,eventFilter:s}),pause:i,resume:a,isActive:l}}function Dd(e,t=!0,n){const r=Nd(n);r?Ue(e,r):t?e():Kn(e)}function Fd(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,o=ze(e),s=ve(e);function i(a){if(arguments.length)return s.value=a,s.value;{const l=gn(n);return s.value=s.value===l?gn(r):l,s.value}}return o?i:[s,i]}function zd(e){var t;const n=gn(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Lr=Ad?window:void 0;function ai(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,o]=e,t=Lr):[t,n,r,o]=e,!t)return Od;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const s=[],i=()=>{s.forEach(u=>u()),s.length=0},a=(u,f,d,m)=>(u.addEventListener(f,d,m),()=>u.removeEventListener(f,d,m)),l=Je(()=>[zd(t),gn(o)],([u,f])=>{if(i(),!u)return;const d=Rd(f)?{...f}:f;s.push(...n.flatMap(m=>r.map(y=>a(u,m,y,d))))},{immediate:!0,flush:"post"}),c=()=>{l(),i()};return Hl(c),c}function Bd(){const e=ve(!1);return Mo()&&Ue(()=>{e.value=!0}),e}function jd(e){const t=Bd();return B(()=>(t.value,!!e()))}function Ud(e,t={}){const{window:n=Lr}=t,r=jd(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let o;const s=ve(!1),i=c=>{s.value=c.matches},a=()=>{o&&("removeEventListener"in o?o.removeEventListener("change",i):o.removeListener(i))},l=Vi(()=>{r.value&&(a(),o=n.matchMedia(gn(e)),"addEventListener"in o?o.addEventListener("change",i):o.addListener(i),s.value=o.matches)});return Hl(()=>{l(),a(),o=void 0}),s}const ar=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},cr="__vueuse_ssr_handlers__",Vd=Kd();function Kd(){return cr in ar||(ar[cr]=ar[cr]||{}),ar[cr]}function Wd(e,t){return Vd[e]||t}function qd(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 Gd={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()}},ci="vueuse-storage";function Fl(e,t,n,r={}){var o;const{flush:s="pre",deep:i=!0,listenToStorageChanges:a=!0,writeDefaults:l=!0,mergeDefaults:c=!1,shallow:u,window:f=Lr,eventFilter:d,onError:m=I=>{console.error(I)},initOnMounted:y}=r,w=(u?Po:ve)(typeof t=="function"?t():t);if(!n)try{n=Wd("getDefaultStorage",()=>{var I;return(I=Lr)==null?void 0:I.localStorage})()}catch(I){m(I)}if(!n)return w;const L=gn(t),k=qd(L),T=(o=r.serializer)!=null?o:Gd[k],{pause:v,resume:b}=Hd(w,()=>F(w.value),{flush:s,deep:i,eventFilter:d});return f&&a&&Dd(()=>{ai(f,"storage",_),ai(f,ci,M),y&&_()}),y||_(),w;function F(I){try{if(I==null)n.removeItem(e);else{const P=T.write(I),K=n.getItem(e);K!==P&&(n.setItem(e,P),f&&f.dispatchEvent(new CustomEvent(ci,{detail:{key:e,oldValue:K,newValue:P,storageArea:n}})))}}catch(P){m(P)}}function W(I){const P=I?I.newValue:n.getItem(e);if(P==null)return l&&L!=null&&n.setItem(e,T.write(L)),L;if(!I&&c){const K=T.read(P);return typeof c=="function"?c(K,L):k==="object"&&!Array.isArray(K)?{...L,...K}:K}else return typeof P!="string"?P:T.read(P)}function M(I){_(I.detail)}function _(I){if(!(I&&I.storageArea!==n)){if(I&&I.key==null){w.value=L;return}if(!(I&&I.key!==e)){v();try{(I==null?void 0:I.newValue)!==T.write(w.value)&&(w.value=W(I))}catch(P){m(P)}finally{I?Kn(b):b()}}}}}function Yd(e){return Ud("(prefers-color-scheme: dark)",e)}const Jd=ce({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const n=ve([]),r=ve(-1),o=Fl("vuepress-code-group",{}),s=B(()=>n.value.map(c=>c.innerText).join(","));Ue(()=>{Je(()=>o.value[s.value],(c=-1)=>{r.value!==c&&(r.value=c)},{immediate:!0}),Je(r,c=>{o.value[s.value]!==c&&(o.value[s.value]=c)})});const i=(c=r.value)=>{c {c>0?r.value=c-1:r.value=n.value.length-1,n.value[r.value].focus()},l=(c,u)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),r.value=u):c.key==="ArrowRight"?(c.preventDefault(),i(u)):c.key==="ArrowLeft"&&(c.preventDefault(),a(u))};return()=>{var u;const c=(((u=t.default)==null?void 0:u.call(t))||[]).filter(f=>f.type.name==="CodeGroupItem").map(f=>(f.props===null&&(f.props={}),f));return c.length===0?null:(r.value<0||r.value>c.length-1?(r.value=c.findIndex(f=>f.props.active===""||f.props.active===!0),r.value===-1&&(r.value=0)):c.forEach((f,d)=>{f.props.active=d===r.value}),le("div",{class:"code-group"},[le("div",{class:"code-group__nav"},le("ul",{class:"code-group__ul"},c.map((f,d)=>{const m=d===r.value;return le("li",{class:"code-group__li"},le("button",{ref:y=>{y&&(n.value[d]=y)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":m},ariaPressed:m,ariaExpanded:m,onClick:()=>r.value=d,onKeydown:y=>l(y,d)},f.props.title))}))),c]))}}}),Qd=["aria-selected"],Xd=ce({name:"CodeGroupItem"}),Zd=ce({...Xd,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(j(),Z("div",{class:We(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[ye(t.$slots,"default")],10,Qd))}}),eh=xe(Zd,[["__file","CodeGroupItem.vue"]]),th=()=>Nl(),je=()=>Cd(),zl=Symbol(""),qo=()=>{const e=Se(zl);if(!e)throw new Error("useDarkMode() is called without provider.");return e},nh=()=>{const e=je(),t=Yd(),n=Fl("vuepress-color-scheme",e.value.colorMode),r=B({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(o){o===t.value?n.value="auto":n.value=o?"dark":"light"}});Wt(zl,r),rh(r)},rh=e=>{const t=(n=e.value)=>{const r=window==null?void 0:window.document.querySelector("html");r==null||r.classList.toggle("dark",n)};Ue(()=>{Je(e,t,{immediate:!0})}),$r(()=>t())},Bl=(...e)=>{const n=Qt().resolve(...e),r=n.matched[n.matched.length-1];if(!(r!=null&&r.redirect))return n;const{redirect:o}=r,s=oe(o)?o(n):o,i=me(s)?{path:s}:s;return Bl({hash:n.hash,query:n.query,params:n.params,...i})},Go=e=>{const t=Bl(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let eo=null,xn=null;const oh={wait:()=>eo,pending:()=>{eo=new Promise(e=>xn=e)},resolve:()=>{xn==null||xn(),eo=null,xn=null}},jl=()=>oh,Ul=Symbol("sidebarItems"),Yo=()=>{const e=Se(Ul);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},sh=()=>{const e=je(),t=vt(),n=B(()=>ih(t.value,e.value));Wt(Ul,n)},ih=(e,t)=>{const n=e.sidebar??t.sidebar??"auto",r=e.sidebarDepth??t.sidebarDepth??2;return e.home||n===!1?[]:n==="auto"?ah(r):X(n)?Vl(n,r):Fo(n)?ch(n,r):[]},lh=(e,t)=>({text:e.title,link:e.link,children:Jo(e.children,t)}),Jo=(e,t)=>t>0?e.map(n=>lh(n,t-1)):[],ah=e=>{const t=Gt();return[{text:t.value.title,children:Jo(t.value.headers,e)}]},Vl=(e,t)=>{const n=Xt(),r=Gt(),o=s=>{var a;let i;if(me(s)?i=Go(s):i=s,i.children)return{...i,children:i.children.map(l=>o(l))};if(i.link===n.path){const l=((a=r.value.headers[0])==null?void 0:a.level)===1?r.value.headers[0].children:r.value.headers;return{...i,children:Jo(l,t)}}return i};return e.map(s=>o(s))},ch=(e,t)=>{const n=Xt(),r=hl(e,n.path),o=e[r]??[];return Vl(o,t)},uh="719px",fh={mobile:uh};var Fn;(function(e){e.MOBILE="mobile"})(Fn||(Fn={}));var pi;const dh={[Fn.MOBILE]:Number.parseInt((pi=fh.mobile)==null?void 0:pi.replace("px",""),10)},Kl=(e,t)=>{const n=dh[e];Number.isInteger(n)&&Ue(()=>{t(n),window.addEventListener("resize",()=>t(n),!1),window.addEventListener("orientationchange",()=>t(n),!1)})},hh={},ph={class:"theme-default-content"};function mh(e,t){const n=bt("Content");return j(),Z("div",ph,[ne(n)])}const gh=xe(hh,[["render",mh],["__file","HomeContent.vue"]]),vh={key:0,class:"features"},_h=ce({__name:"HomeFeatures",setup(e){const t=vt(),n=B(()=>X(t.value.features)?t.value.features:[]);return(r,o)=>n.value.length?(j(),Z("div",vh,[(j(!0),Z(Ee,null,It(n.value,s=>(j(),Z("div",{key:s.title,class:"feature"},[de("h2",null,Pe(s.title),1),de("p",null,Pe(s.details),1)]))),128))])):Le("v-if",!0)}}),bh=xe(_h,[["__file","HomeFeatures.vue"]]),yh=["innerHTML"],Eh=["textContent"],wh=ce({__name:"HomeFooter",setup(e){const t=vt(),n=B(()=>t.value.footer),r=B(()=>t.value.footerHtml);return(o,s)=>n.value?(j(),Z(Ee,{key:0},[Le(" eslint-disable-next-line vue/no-v-html "),r.value?(j(),Z("div",{key:0,class:"footer",innerHTML:n.value},null,8,yh)):(j(),Z("div",{key:1,class:"footer",textContent:Pe(n.value)},null,8,Eh))],64)):Le("v-if",!0)}}),Ch=xe(wh,[["__file","HomeFooter.vue"]]),xh=["href","rel","target","aria-label"],Lh=ce({inheritAttrs:!1}),Sh=ce({...Lh,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,n=Xt(),r=yl(),{item:o}=Pr(t),s=B(()=>Yn(o.value.link)),i=B(()=>!s.value&&Au(o.value.link)),a=B(()=>{if(!i.value){if(o.value.target)return o.value.target;if(s.value)return"_blank"}}),l=B(()=>a.value==="_blank"),c=B(()=>!s.value&&!i.value&&!l.value),u=B(()=>{if(!i.value){if(o.value.rel)return o.value.rel;if(l.value)return"noopener noreferrer"}}),f=B(()=>o.value.ariaLabel||o.value.text),d=B(()=>{const w=Object.keys(r.value.locales);return w.length?!w.some(L=>L===o.value.link):o.value.link!=="/"}),m=B(()=>d.value?n.path.startsWith(o.value.link):!1),y=B(()=>c.value?o.value.activeMatch?new RegExp(o.value.activeMatch).test(n.path):m.value:!1);return(w,L)=>{const k=bt("RouterLink"),T=bt("AutoLinkExternalIcon");return c.value?(j(),ke(k,ho({key:0,class:{"router-link-active":y.value},to:ee(o).link,"aria-label":f.value},w.$attrs),{default:Ne(()=>[ye(w.$slots,"before"),Nt(" "+Pe(ee(o).text)+" ",1),ye(w.$slots,"after")]),_:3},16,["class","to","aria-label"])):(j(),Z("a",ho({key:1,class:"external-link",href:ee(o).link,rel:u.value,target:a.value,"aria-label":f.value},w.$attrs),[ye(w.$slots,"before"),Nt(" "+Pe(ee(o).text)+" ",1),l.value?(j(),ke(T,{key:0})):Le("v-if",!0),ye(w.$slots,"after")],16,xh))}}}),_t=xe(Sh,[["__file","AutoLink.vue"]]),Th={class:"hero"},kh={key:0,id:"main-title"},Ah={key:1,class:"description"},Ph={key:2,class:"actions"},Rh=ce({__name:"HomeHero",setup(e){const t=vt(),n=Bo(),r=qo(),o=B(()=>r.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),s=B(()=>t.value.heroAlt||a.value||"hero"),i=B(()=>t.value.heroHeight||280),a=B(()=>t.value.heroText===null?null:t.value.heroText||n.value.title||"Hello"),l=B(()=>t.value.tagline===null?null:t.value.tagline||n.value.description||"Welcome to your VuePress site"),c=B(()=>X(t.value.actions)?t.value.actions.map(({text:f,link:d,type:m="primary"})=>({text:f,link:d,type:m})):[]),u=()=>{if(!o.value)return null;const f=le("img",{src:Uo(o.value),alt:s.value,height:i.value});return t.value.heroImageDark===void 0?f:le(jo,()=>f)};return(f,d)=>(j(),Z("header",Th,[ne(u),a.value?(j(),Z("h1",kh,Pe(a.value),1)):Le("v-if",!0),l.value?(j(),Z("p",Ah,Pe(l.value),1)):Le("v-if",!0),c.value.length?(j(),Z("p",Ph,[(j(!0),Z(Ee,null,It(c.value,m=>(j(),ke(_t,{key:m.text,class:We(["action-button",[m.type]]),item:m},null,8,["class","item"]))),128))])):Le("v-if",!0)]))}}),Oh=xe(Rh,[["__file","HomeHero.vue"]]),Ih={class:"home"},$h=ce({__name:"Home",setup(e){return(t,n)=>(j(),Z("main",Ih,[ne(Oh),ne(bh),ne(gh),ne(Ch)]))}}),Nh=xe($h,[["__file","Home.vue"]]),Mh=ce({__name:"NavbarBrand",setup(e){const t=Jn(),n=Bo(),r=je(),o=qo(),s=B(()=>r.value.home||t.value),i=B(()=>n.value.title),a=B(()=>o.value&&r.value.logoDark!==void 0?r.value.logoDark:r.value.logo),l=()=>{if(!a.value)return null;const c=le("img",{class:"logo",src:Uo(a.value),alt:i.value});return r.value.logoDark===void 0?c:le(jo,()=>c)};return(c,u)=>{const f=bt("RouterLink");return j(),ke(f,{to:s.value},{default:Ne(()=>[ne(l),i.value?(j(),Z("span",{key:0,class:We(["site-name",{"can-hide":a.value}])},Pe(i.value),3)):Le("v-if",!0)]),_:1},8,["to"])}}}),Hh=xe(Mh,[["__file","NavbarBrand.vue"]]),Dh=ce({__name:"DropdownTransition",setup(e){const t=r=>{r.style.height=r.scrollHeight+"px"},n=r=>{r.style.height=""};return(r,o)=>(j(),ke(Gn,{name:"dropdown",onEnter:t,onAfterEnter:n,onBeforeLeave:t},{default:Ne(()=>[ye(r.$slots,"default")]),_:3}))}}),Wl=xe(Dh,[["__file","DropdownTransition.vue"]]),Fh=["aria-label"],zh={class:"title"},Bh=de("span",{class:"arrow down"},null,-1),jh=["aria-label"],Uh={class:"title"},Vh={class:"navbar-dropdown"},Kh={class:"navbar-dropdown-subtitle"},Wh={key:1},qh={class:"navbar-dropdown-subitem-wrapper"},Gh=ce({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:n}=Pr(t),r=B(()=>n.value.ariaLabel||n.value.text),o=ve(!1),s=Xt();Je(()=>s.path,()=>{o.value=!1});const i=l=>{l.detail===0?o.value=!o.value:o.value=!1},a=(l,c)=>c[c.length-1]===l;return(l,c)=>(j(),Z("div",{class:We(["navbar-dropdown-wrapper",{open:o.value}])},[de("button",{class:"navbar-dropdown-title",type:"button","aria-label":r.value,onClick:i},[de("span",zh,Pe(ee(n).text),1),Bh],8,Fh),de("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":r.value,onClick:c[0]||(c[0]=u=>o.value=!o.value)},[de("span",Uh,Pe(ee(n).text),1),de("span",{class:We(["arrow",o.value?"down":"right"])},null,2)],8,jh),ne(Wl,null,{default:Ne(()=>[_r(de("ul",Vh,[(j(!0),Z(Ee,null,It(ee(n).children,u=>(j(),Z("li",{key:u.text,class:"navbar-dropdown-item"},[u.children?(j(),Z(Ee,{key:0},[de("h4",Kh,[u.link?(j(),ke(_t,{key:0,item:u,onFocusout:f=>a(u,ee(n).children)&&u.children.length===0&&(o.value=!1)},null,8,["item","onFocusout"])):(j(),Z("span",Wh,Pe(u.text),1))]),de("ul",qh,[(j(!0),Z(Ee,null,It(u.children,f=>(j(),Z("li",{key:f.link,class:"navbar-dropdown-subitem"},[ne(_t,{item:f,onFocusout:d=>a(f,u.children)&&a(u,ee(n).children)&&(o.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(j(),ke(_t,{key:1,item:u,onFocusout:f=>a(u,ee(n).children)&&(o.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[Cr,o.value]])]),_:1})],2))}}),Yh=xe(Gh,[["__file","NavbarDropdown.vue"]]),ui=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),Jh=(e,t)=>{if(t.hash===e)return!0;const n=ui(t.path),r=ui(e);return n===r},ql=(e,t)=>e.link&&Jh(e.link,t)?!0:e.children?e.children.some(n=>ql(n,t)):!1,Gl=e=>!Yn(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Qh={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},Xh=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const n=Gl(e);return n!==null?Qh[n]:null},Zh=({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:r,editLinkPattern:o})=>{if(!r)return null;const s=Xh({docsRepo:e,editLinkPattern:o});return s?s.replace(/:repo/,Yn(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,dl(`${fl(n)}/${r}`)):null},ep={key:0,class:"navbar-items"},tp=ce({__name:"NavbarItems",setup(e){const t=()=>{const u=Qt(),f=Jn(),d=yl(),m=Bo(),y=th(),w=je();return B(()=>{const L=Object.keys(d.value.locales);if(L.length<2)return[];const k=u.currentRoute.value.path,T=u.currentRoute.value.fullPath;return[{text:`${w.value.selectLanguageText}`,ariaLabel:`${w.value.selectLanguageAriaLabel??w.value.selectLanguageText}`,children:L.map(b=>{var P,K;const F=((P=d.value.locales)==null?void 0:P[b])??{},W=((K=y.value.locales)==null?void 0:K[b])??{},M=`${F.lang}`,_=W.selectLanguageName??M;let I;if(M===m.value.lang)I=T;else{const C=k.replace(f.value,b);u.getRoutes().some(N=>N.path===C)?I=T.replace(k,C):I=W.home??b}return{text:_,link:I}})}]})},n=()=>{const u=je(),f=B(()=>u.value.repo),d=B(()=>f.value?Gl(f.value):null),m=B(()=>f.value&&!Yn(f.value)?`https://github.com/${f.value}`:f.value),y=B(()=>m.value?u.value.repoLabel?u.value.repoLabel:d.value===null?"Source":d.value:null);return B(()=>!m.value||!y.value?[]:[{text:y.value,link:m.value}])},r=u=>me(u)?Go(u):u.children?{...u,children:u.children.map(r)}:u,o=()=>{const u=je();return B(()=>(u.value.navbar||[]).map(r))},s=ve(!1),i=o(),a=t(),l=n(),c=B(()=>[...i.value,...a.value,...l.value]);return Kl(Fn.MOBILE,u=>{window.innerWidthc.value.length?(j(),Z("nav",ep,[(j(!0),Z(Ee,null,It(c.value,d=>(j(),Z("div",{key:d.text,class:"navbar-item"},[d.children?(j(),ke(Yh,{key:0,item:d,class:We(s.value?"mobile":"")},null,8,["item","class"])):(j(),ke(_t,{key:1,item:d},null,8,["item"]))]))),128))])):Le("v-if",!0)}}),Yl=xe(tp,[["__file","NavbarItems.vue"]]),np=["title"],rp={class:"icon",focusable:"false",viewBox:"0 0 32 32"},op=Nc(' ',9),sp=[op],ip={class:"icon",focusable:"false",viewBox:"0 0 32 32"},lp=de("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),ap=[lp],cp=ce({__name:"ToggleColorModeButton",setup(e){const t=je(),n=qo(),r=()=>{n.value=!n.value};return(o,s)=>(j(),Z("button",{class:"toggle-color-mode-button",title:ee(t).toggleColorMode,onClick:r},[_r((j(),Z("svg",rp,sp,512)),[[Cr,!ee(n)]]),_r((j(),Z("svg",ip,ap,512)),[[Cr,ee(n)]])],8,np))}}),up=xe(cp,[["__file","ToggleColorModeButton.vue"]]),fp=["title"],dp=de("div",{class:"icon","aria-hidden":"true"},[de("span"),de("span"),de("span")],-1),hp=[dp],pp=ce({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=je();return(n,r)=>(j(),Z("div",{class:"toggle-sidebar-button",title:ee(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:r[0]||(r[0]=o=>n.$emit("toggle"))},hp,8,fp))}}),mp=xe(pp,[["__file","ToggleSidebarButton.vue"]]),gp=ce({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=je(),n=ve(null),r=ve(null),o=ve(0),s=B(()=>o.value?{maxWidth:o.value+"px"}:{});Kl(Fn.MOBILE,a=>{var c;const l=i(n.value,"paddingLeft")+i(n.value,"paddingRight");window.innerWidth{const c=bt("NavbarSearch");return j(),Z("header",{ref_key:"navbar",ref:n,class:"navbar"},[ne(mp,{onToggle:l[0]||(l[0]=u=>a.$emit("toggle-sidebar"))}),de("span",{ref_key:"navbarBrand",ref:r},[ne(Hh)],512),de("div",{class:"navbar-items-wrapper",style:Bn(s.value)},[ye(a.$slots,"before"),ne(Yl,{class:"can-hide"}),ye(a.$slots,"after"),ee(t).colorModeSwitch?(j(),ke(up,{key:0})):Le("v-if",!0),ne(c)],4)],512)}}}),vp=xe(gp,[["__file","Navbar.vue"]]),_p={class:"page-meta"},bp={key:0,class:"meta-item edit-link"},yp={key:1,class:"meta-item last-updated"},Ep={class:"meta-item-label"},wp={class:"meta-item-info"},Cp={key:2,class:"meta-item contributors"},xp={class:"meta-item-label"},Lp={class:"meta-item-info"},Sp=["title"],Tp=ce({__name:"PageMeta",setup(e){const t=()=>{const l=je(),c=Gt(),u=vt();return B(()=>{if(!(u.value.editLink??l.value.editLink??!0))return null;const{repo:d,docsRepo:m=d,docsBranch:y="main",docsDir:w="",editLinkText:L}=l.value;if(!m)return null;const k=Zh({docsRepo:m,docsBranch:y,docsDir:w,filePathRelative:c.value.filePathRelative,editLinkPattern:u.value.editLinkPattern??l.value.editLinkPattern});return k?{text:L??"Edit this page",link:k}:null})},n=()=>{const l=je(),c=Gt(),u=vt();return B(()=>{var m,y;return!(u.value.lastUpdated??l.value.lastUpdated??!0)||!((m=c.value.git)!=null&&m.updatedTime)?null:new Date((y=c.value.git)==null?void 0:y.updatedTime).toLocaleString()})},r=()=>{const l=je(),c=Gt(),u=vt();return B(()=>{var d;return u.value.contributors??l.value.contributors??!0?((d=c.value.git)==null?void 0:d.contributors)??null:null})},o=je(),s=t(),i=n(),a=r();return(l,c)=>{const u=bt("ClientOnly");return j(),Z("footer",_p,[ee(s)?(j(),Z("div",bp,[ne(_t,{class:"meta-item-label",item:ee(s)},null,8,["item"])])):Le("v-if",!0),ee(i)?(j(),Z("div",yp,[de("span",Ep,Pe(ee(o).lastUpdatedText)+": ",1),ne(u,null,{default:Ne(()=>[de("span",wp,Pe(ee(i)),1)]),_:1})])):Le("v-if",!0),ee(a)&&ee(a).length?(j(),Z("div",Cp,[de("span",xp,Pe(ee(o).contributorsText)+": ",1),de("span",Lp,[(j(!0),Z(Ee,null,It(ee(a),(f,d)=>(j(),Z(Ee,{key:d},[de("span",{class:"contributor",title:`email: ${f.email}`},Pe(f.name),9,Sp),d!==ee(a).length-1?(j(),Z(Ee,{key:0},[Nt(", ")],64)):Le("v-if",!0)],64))),128))])])):Le("v-if",!0)])}}}),kp=xe(Tp,[["__file","PageMeta.vue"]]),Ap={key:0,class:"page-nav"},Pp={class:"inner"},Rp={key:0,class:"prev"},Op={key:1,class:"next"},Ip=ce({__name:"PageNav",setup(e){const t=l=>l===!1?null:me(l)?Go(l):Fo(l)?l:!1,n=(l,c,u)=>{const f=l.findIndex(d=>d.link===c);if(f!==-1){const d=l[f+u];return d!=null&&d.link?d:null}for(const d of l)if(d.children){const m=n(d.children,c,u);if(m)return m}return null},r=vt(),o=Yo(),s=Xt(),i=B(()=>{const l=t(r.value.prev);return l!==!1?l:n(o.value,s.path,-1)}),a=B(()=>{const l=t(r.value.next);return l!==!1?l:n(o.value,s.path,1)});return(l,c)=>i.value||a.value?(j(),Z("nav",Ap,[de("p",Pp,[i.value?(j(),Z("span",Rp,[ne(_t,{item:i.value},null,8,["item"])])):Le("v-if",!0),a.value?(j(),Z("span",Op,[ne(_t,{item:a.value},null,8,["item"])])):Le("v-if",!0)])])):Le("v-if",!0)}}),$p=xe(Ip,[["__file","PageNav.vue"]]),Np={class:"page"},Mp={class:"theme-default-content"},Hp=ce({__name:"Page",setup(e){return(t,n)=>{const r=bt("Content");return j(),Z("main",Np,[ye(t.$slots,"top"),de("div",Mp,[ye(t.$slots,"content-top"),ne(r),ye(t.$slots,"content-bottom")]),ne(kp),ne($p),ye(t.$slots,"bottom")])}}}),Dp=xe(Hp,[["__file","Page.vue"]]),Fp={class:"sidebar-item-children"},zp=ce({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:n,depth:r}=Pr(t),o=Xt(),s=Qt(),i=B(()=>ql(n.value,o)),a=B(()=>({"sidebar-item":!0,"sidebar-heading":r.value===0,active:i.value,collapsible:n.value.collapsible})),l=B(()=>n.value.collapsible?i.value:!0),[c,u]=Fd(l.value),f=m=>{n.value.collapsible&&(m.preventDefault(),u())},d=s.afterEach(m=>{Kn(()=>{c.value=l.value})});return qn(()=>{d()}),(m,y)=>{var L;const w=bt("SidebarItem",!0);return j(),Z("li",null,[ee(n).link?(j(),ke(_t,{key:0,class:We(a.value),item:ee(n)},null,8,["class","item"])):(j(),Z("p",{key:1,tabindex:"0",class:We(a.value),onClick:f,onKeydown:_u(f,["enter"])},[Nt(Pe(ee(n).text)+" ",1),ee(n).collapsible?(j(),Z("span",{key:0,class:We(["arrow",ee(c)?"down":"right"])},null,2)):Le("v-if",!0)],34)),(L=ee(n).children)!=null&&L.length?(j(),ke(Wl,{key:2},{default:Ne(()=>[_r(de("ul",Fp,[(j(!0),Z(Ee,null,It(ee(n).children,k=>(j(),ke(w,{key:`${ee(r)}${k.text}${k.link}`,item:k,depth:ee(r)+1},null,8,["item","depth"]))),128))],512),[[Cr,ee(c)]])]),_:1})):Le("v-if",!0)])}}}),Bp=xe(zp,[["__file","SidebarItem.vue"]]),jp={key:0,class:"sidebar-items"},Up=ce({__name:"SidebarItems",setup(e){const t=Xt(),n=Yo();return Ue(()=>{Je(()=>t.hash,r=>{const o=document.querySelector(".sidebar");if(!o)return;const s=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${r}"]`);if(!s)return;const{top:i,height:a}=o.getBoundingClientRect(),{top:l,height:c}=s.getBoundingClientRect();li+a&&s.scrollIntoView(!1)})}),(r,o)=>ee(n).length?(j(),Z("ul",jp,[(j(!0),Z(Ee,null,It(ee(n),s=>(j(),ke(Bp,{key:`${s.text}${s.link}`,item:s},null,8,["item"]))),128))])):Le("v-if",!0)}}),Vp=xe(Up,[["__file","SidebarItems.vue"]]),Kp={class:"sidebar"},Wp=ce({__name:"Sidebar",setup(e){return(t,n)=>(j(),Z("aside",Kp,[ne(Yl),ye(t.$slots,"top"),ne(Vp),ye(t.$slots,"bottom")]))}}),qp=xe(Wp,[["__file","Sidebar.vue"]]),Gp=ce({__name:"Layout",setup(e){const t=Gt(),n=vt(),r=je(),o=B(()=>n.value.navbar!==!1&&r.value.navbar!==!1),s=Yo(),i=ve(!1),a=L=>{i.value=typeof L=="boolean"?L:!i.value},l={x:0,y:0},c=L=>{l.x=L.changedTouches[0].clientX,l.y=L.changedTouches[0].clientY},u=L=>{const k=L.changedTouches[0].clientX-l.x,T=L.changedTouches[0].clientY-l.y;Math.abs(k)>Math.abs(T)&&Math.abs(k)>40&&(k>0&&l.x<=80?a(!0):a(!1))},f=B(()=>[{"no-navbar":!o.value,"no-sidebar":!s.value.length,"sidebar-open":i.value},n.value.pageClass]);let d;Ue(()=>{d=Qt().afterEach(()=>{a(!1)})}),$r(()=>{d()});const m=jl(),y=m.resolve,w=m.pending;return(L,k)=>(j(),Z("div",{class:We(["theme-container",f.value]),onTouchstart:c,onTouchend:u},[ye(L.$slots,"navbar",{},()=>[o.value?(j(),ke(vp,{key:0,onToggleSidebar:a},{before:Ne(()=>[ye(L.$slots,"navbar-before")]),after:Ne(()=>[ye(L.$slots,"navbar-after")]),_:3})):Le("v-if",!0)]),de("div",{class:"sidebar-mask",onClick:k[0]||(k[0]=T=>a(!1))}),ye(L.$slots,"sidebar",{},()=>[ne(qp,null,{top:Ne(()=>[ye(L.$slots,"sidebar-top")]),bottom:Ne(()=>[ye(L.$slots,"sidebar-bottom")]),_:3})]),ye(L.$slots,"page",{},()=>[ee(n).home?(j(),ke(Nh,{key:0})):(j(),ke(Gn,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:ee(y),onBeforeLeave:ee(w)},{default:Ne(()=>[(j(),ke(Dp,{key:ee(t).path},{top:Ne(()=>[ye(L.$slots,"page-top")]),"content-top":Ne(()=>[ye(L.$slots,"page-content-top")]),"content-bottom":Ne(()=>[ye(L.$slots,"page-content-bottom")]),bottom:Ne(()=>[ye(L.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),Yp=xe(Gp,[["__file","Layout.vue"]]),Jp={class:"theme-container"},Qp={class:"page"},Xp={class:"theme-default-content"},Zp=de("h1",null,"404",-1),em=ce({__name:"NotFound",setup(e){const t=Jn(),n=je(),r=n.value.notFound??["Not Found"],o=()=>r[Math.floor(Math.random()*r.length)],s=n.value.home??t.value,i=n.value.backToHome??"Back to home";return(a,l)=>{const c=bt("RouterLink");return j(),Z("div",Jp,[de("main",Qp,[de("div",Xp,[Zp,de("blockquote",null,Pe(o()),1),ne(c,{to:ee(s)},{default:Ne(()=>[Nt(Pe(ee(i)),1)]),_:1},8,["to"])])])])}}}),tm=xe(em,[["__file","NotFound.vue"]]),nm=Mt({enhance({app:e,router:t}){e.component("Badge",Td),e.component("CodeGroup",Jd),e.component("CodeGroupItem",eh),e.component("AutoLinkExternalIcon",()=>{const r=e.component("ExternalLinkIcon");return r?le(r):null}),e.component("NavbarSearch",()=>{const r=e.component("Docsearch")||e.component("SearchBox");return r?le(r):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...r)=>(await jl().wait(),n(...r))},setup(){nh(),sh()},layouts:{Layout:Yp,NotFound:tm}}),rm=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,om=(e,t)=>t.some(n=>{if(me(n))return n===e.key;const{key:r,ctrl:o=!1,shift:s=!1,alt:i=!1}=n;return r===e.key&&o===e.ctrlKey&&s===e.shiftKey&&i===e.altKey}),sm=/[^\x00-\x7F]/,im=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),fi=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),di=(e,t)=>{const n=t.join(" "),r=im(e);if(sm.test(e))return r.some(i=>n.toLowerCase().indexOf(i)>-1);const o=e.endsWith(" ");return new RegExp(r.map((i,a)=>r.length===a+1&&!o?`(?=.*\\b${fi(i)})`:`(?=.*\\b${fi(i)}\\b)`).join("")+".+","gi").test(n)},lm=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const n=r=>{e.value&&om(r,t.value)&&!rm(r.target)&&(r.preventDefault(),e.value.focus())};Ue(()=>{document.addEventListener("keydown",n)}),qn(()=>{document.removeEventListener("keydown",n)})},am=[{title:"Home",headers:[],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"首页",headers:[],path:"/zh-cn/",pathLocale:"/zh-cn/",extraFields:[]},{title:"Introduction",headers:[{level:2,title:"Background",slug:"background",link:"#background",children:[]},{level:2,title:"Usage",slug:"usage",link:"#usage",children:[]},{level:2,title:"Language Requirement",slug:"language-requirement",link:"#language-requirement",children:[]},{level:2,title:"Contribution",slug:"contribution",link:"#contribution",children:[]}],path:"/en/guide/home.html",pathLocale:"/en/",extraFields:[]},{title:"Quick Start",headers:[{level:2,title:"Deploy Plugin",slug:"deploy-plugin",link:"#deploy-plugin",children:[]},{level:2,title:"Feature Configuration",slug:"feature-configuration",link:"#feature-configuration",children:[{level:3,title:"Common Configuration",slug:"common-configuration",link:"#common-configuration",children:[]},{level:3,title:"Build Script Configuration",slug:"build-script-configuration",link:"#build-script-configuration",children:[]},{level:3,title:"Android Project Configuration",slug:"android-project-configuration",link:"#android-project-configuration",children:[]},{level:3,title:"JVM Project Configuration",slug:"jvm-project-configuration",link:"#jvm-project-configuration",children:[]},{level:3,title:"Kotlin Multiplatform Project Configuration",slug:"kotlin-multiplatform-project-configuration",link:"#kotlin-multiplatform-project-configuration",children:[]}]},{level:2,title:"Usage Examples",slug:"usage-examples",link:"#usage-examples",children:[]},{level:2,title:"Possible Issues",slug:"possible-issues",link:"#possible-issues",children:[]},{level:2,title:"Limitations",slug:"limitations",link:"#limitations",children:[]}],path:"/en/guide/quick-start.html",pathLocale:"/en/",extraFields:[]},{title:"About This Document",headers:[{level:2,title:"License",slug:"license",link:"#license",children:[]}],path:"/en/about/about.html",pathLocale:"/en/",extraFields:[]},{title:"Changelog",headers:[{level:3,title:"1.0.1 | 2025.11.16",slug:"_1-0-1-2025-11-16",link:"#_1-0-1-2025-11-16",children:[]},{level:3,title:"1.0.0 | 2025.11.11",slug:"_1-0-0-2025-11-11",link:"#_1-0-0-2025-11-11",children:[]}],path:"/en/about/changelog.html",pathLocale:"/en/",extraFields:[]},{title:"Contact Us",headers:[{level:2,title:"Help with Maintenance",slug:"help-with-maintenance",link:"#help-with-maintenance",children:[]}],path:"/en/about/contacts.html",pathLocale:"/en/",extraFields:[]},{title:"Looking Toward the Future",headers:[{level:2,title:"Future Plans",slug:"future-plans",link:"#future-plans",children:[{level:3,title:"Support More Project Types",slug:"support-more-project-types",link:"#support-more-project-types",children:[]}]}],path:"/en/about/future.html",pathLocale:"/en/",extraFields:[]},{title:"关于此文档",headers:[{level:2,title:"许可证",slug:"许可证",link:"#许可证",children:[]}],path:"/zh-cn/about/about.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"更新日志",headers:[{level:3,title:"1.0.1 | 2025.11.16",slug:"_1-0-1-2025-11-16",link:"#_1-0-1-2025-11-16",children:[]},{level:3,title:"1.0.0 | 2025.11.11",slug:"_1-0-0-2025-11-11",link:"#_1-0-0-2025-11-11",children:[]}],path:"/zh-cn/about/changelog.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"联系我们",headers:[{level:2,title:"助力维护",slug:"助力维护",link:"#助力维护",children:[]}],path:"/zh-cn/about/contacts.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"展望未来",headers:[{level:2,title:"未来的计划",slug:"未来的计划",link:"#未来的计划",children:[{level:3,title:"支持更多项目类型",slug:"支持更多项目类型",link:"#支持更多项目类型",children:[]}]}],path:"/zh-cn/about/future.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"介绍",headers:[{level:2,title:"背景",slug:"背景",link:"#背景",children:[]},{level:2,title:"用途",slug:"用途",link:"#用途",children:[]},{level:2,title:"语言要求",slug:"语言要求",link:"#语言要求",children:[]},{level:2,title:"功能贡献",slug:"功能贡献",link:"#功能贡献",children:[]}],path:"/zh-cn/guide/home.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"快速开始",headers:[{level:2,title:"部署插件",slug:"部署插件",link:"#部署插件",children:[]},{level:2,title:"功能配置",slug:"功能配置",link:"#功能配置",children:[{level:3,title:"通用配置",slug:"通用配置",link:"#通用配置",children:[]},{level:3,title:"构建脚本配置",slug:"构建脚本配置",link:"#构建脚本配置",children:[]},{level:3,title:"Android 项目配置",slug:"android-项目配置",link:"#android-项目配置",children:[]},{level:3,title:"JVM 项目配置",slug:"jvm-项目配置",link:"#jvm-项目配置",children:[]},{level:3,title:"Kotlin 多平台项目配置",slug:"kotlin-多平台项目配置",link:"#kotlin-多平台项目配置",children:[]}]},{level:2,title:"使用示例",slug:"使用示例",link:"#使用示例",children:[]},{level:2,title:"可能遇到的问题",slug:"可能遇到的问题",link:"#可能遇到的问题",children:[]},{level:2,title:"局限性说明",slug:"局限性说明",link:"#局限性说明",children:[]}],path:"/zh-cn/guide/quick-start.html",pathLocale:"/zh-cn/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],cm=ve(am),um=()=>cm,fm=({searchIndex:e,routeLocale:t,query:n,maxSuggestions:r})=>{const o=B(()=>e.value.filter(s=>s.pathLocale===t.value));return B(()=>{const s=n.value.trim().toLowerCase();if(!s)return[];const i=[],a=(l,c)=>{di(s,[c.title])&&i.push({link:`${l.path}#${c.slug}`,title:l.title,header:c.title});for(const u of c.children){if(i.length>=r.value)return;a(l,u)}};for(const l of o.value){if(i.length>=r.value)break;if(di(s,[l.title,...l.extraFields])){i.push({link:l.path,title:l.title});continue}for(const c of l.headers){if(i.length>=r.value)break;a(l,c)}}return i})},dm=e=>{const t=ve(0);return{focusIndex:t,focusNext:()=>{t.value {t.value>0?t.value-=1:t.value=e.value.length-1}}},hm=ce({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:n,maxSuggestions:r}=Pr(e),o=Qt(),s=Jn(),i=um(),a=ve(null),l=ve(!1),c=ve(""),u=B(()=>t.value[s.value]??{}),f=fm({searchIndex:i,routeLocale:s,query:c,maxSuggestions:r}),{focusIndex:d,focusNext:m,focusPrev:y}=dm(f);lm({input:a,hotKeys:n});const w=B(()=>l.value&&!!f.value.length),L=()=>{w.value&&y()},k=()=>{w.value&&m()},T=v=>{if(!w.value)return;const b=f.value[v];b&&o.push(b.link).then(()=>{c.value="",d.value=0})};return()=>le("form",{class:"search-box",role:"search"},[le("input",{ref:a,type:"search",placeholder:u.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>l.value=!0,onBlur:()=>l.value=!1,onInput:v=>c.value=v.target.value,onKeydown:v=>{switch(v.key){case"ArrowUp":{L();break}case"ArrowDown":{k();break}case"Enter":{v.preventDefault(),T(d.value);break}}}}),w.value&&le("ul",{class:"suggestions",onMouseleave:()=>d.value=-1},f.value.map(({link:v,title:b,header:F},W)=>le("li",{class:["suggestion",{focus:d.value===W}],onMouseenter:()=>d.value=W,onMousedown:()=>T(W)},le("a",{href:v,onClick:M=>M.preventDefault()},[le("span",{class:"page-title"},b),F&&le("span",{class:"page-header"},`> ${F}`)]))))])}});var pm=["s","/"],mm={"/en/":{placeholder:"Search"},"/zh-cn/":{placeholder:"搜索"}};const gm=mm,vm=pm,_m=5,bm=Mt({enhance({app:e}){e.component("SearchBox",t=>le(hm,{locales:gm,hotKeys:vm,maxSuggestions:_m,...t}))}}),ur=[Yf,Xf,rd,gd,yd,Ld,nm,bm],ym=[["v-8daa1a0e","/",{title:""},["/index.md"]],["v-2d0a870d","/en/",{title:"Home"},["/en/index.md"]],["v-c0c85b84","/zh-cn/",{title:"首页"},["/zh-cn/index.md"]],["v-efb45d4c","/en/guide/home.html",{title:"Introduction"},[":md"]],["v-72889797","/en/guide/quick-start.html",{title:"Quick Start"},[":md"]],["v-7a15fe3b","/en/about/about.html",{title:"About This Document"},[":md"]],["v-3f851d14","/en/about/changelog.html",{title:"Changelog"},[":md"]],["v-193cf592","/en/about/contacts.html",{title:"Contact Us"},[":md"]],["v-ae7b83f2","/en/about/future.html",{title:"Looking Toward the Future"},[":md"]],["v-41967128","/zh-cn/about/about.html",{title:"关于此文档"},[":md"]],["v-0e6c3476","/zh-cn/about/changelog.html",{title:"更新日志"},[":md"]],["v-6cf86266","/zh-cn/about/contacts.html",{title:"联系我们"},[":md"]],["v-3106ca14","/zh-cn/about/future.html",{title:"展望未来"},[":md"]],["v-6a609e09","/zh-cn/guide/home.html",{title:"介绍"},[":md"]],["v-24840ff0","/zh-cn/guide/quick-start.html",{title:"快速开始"},[":md"]],["v-3706649a","/404.html",{title:""},[]]];var hi=ce({name:"Vuepress",setup(){const e=Nu();return()=>le(e.value)}}),Em=()=>ym.reduce((e,[t,n,r,o])=>(e.push({name:t,path:n,component:hi,meta:r},{path:n.endsWith("/")?n+"index.html":n.substring(0,n.length-5),redirect:n},...o.map(s=>({path:s===":md"?n.substring(0,n.length-5)+".md":s,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:hi}]),wm=of,Cm=()=>{const e=jf({history:wm(fl("/Gropify/")),routes:Em(),scrollBehavior:(t,n,r)=>r||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var r;(t.path!==n.path||n===pt)&&([t.meta._data]=await Promise.all([ht.resolvePageData(t.name),(r=pl[t.name])==null?void 0:r.__asyncLoader()]))}),e},xm=e=>{e.component("ClientOnly",jo),e.component("Content",zu)},Lm=(e,t,n)=>{const r=li(()=>t.currentRoute.value.path),o=li(()=>ht.resolveRouteLocale(rn.value.locales,r.value)),s=kd(r,()=>t.currentRoute.value.meta._data),i=B(()=>ht.resolveLayouts(n)),a=B(()=>ht.resolveSiteLocaleData(rn.value,o.value)),l=B(()=>ht.resolvePageFrontmatter(s.value)),c=B(()=>ht.resolvePageHeadTitle(s.value,a.value)),u=B(()=>ht.resolvePageHead(c.value,l.value,a.value)),f=B(()=>ht.resolvePageLang(s.value,a.value)),d=B(()=>ht.resolvePageLayout(s.value,i.value));return e.provide(Pu,i),e.provide(ml,s),e.provide(gl,l),e.provide(Iu,c),e.provide(vl,u),e.provide(_l,f),e.provide(bl,d),e.provide(zo,o),e.provide(El,a),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>l.value},$head:{get:()=>u.value},$headTitle:{get:()=>c.value},$lang:{get:()=>f.value},$page:{get:()=>s.value},$routeLocale:{get:()=>o.value},$site:{get:()=>rn.value},$siteLocale:{get:()=>a.value},$withBase:{get:()=>Uo}}),{layouts:i,pageData:s,pageFrontmatter:l,pageHead:u,pageHeadTitle:c,pageLang:f,pageLayout:d,routeLocale:o,siteData:rn,siteLocaleData:a}},Sm=()=>{const e=Ou(),t=$u(),n=ve([]),r=()=>{e.value.forEach(s=>{const i=Tm(s);i&&n.value.push(i)})},o=()=>{document.documentElement.lang=t.value,n.value.forEach(s=>{s.parentNode===document.head&&document.head.removeChild(s)}),n.value.splice(0,n.value.length),e.value.forEach(s=>{const i=km(s);i!==null&&(document.head.appendChild(i),n.value.push(i))})};Wt(Hu,o),Ue(()=>{r(),o(),Je(()=>e.value,o)})},Tm=([e,t,n=""])=>{const r=Object.entries(t).map(([a,l])=>me(l)?`[${a}=${JSON.stringify(l)}]`:l===!0?`[${a}]`:"").join(""),o=`head > ${e}${r}`;return Array.from(document.querySelectorAll(o)).find(a=>a.innerText===n)||null},km=([e,t,n])=>{if(!me(e))return null;const r=document.createElement(e);return Fo(t)&&Object.entries(t).forEach(([o,s])=>{me(s)?r.setAttribute(o,s):s===!0&&r.setAttribute(o,"")}),me(n)&&r.appendChild(document.createTextNode(n)),r},Am=Eu,Pm=async()=>{var n;const e=Am({name:"VuepressApp",setup(){var r;Sm();for(const o of ur)(r=o.setup)==null||r.call(o);return()=>[le(Il),...ur.flatMap(({rootComponents:o=[]})=>o.map(s=>le(s)))]}}),t=Cm();xm(e),Lm(e,t,ur);for(const r of ur)await((n=r.enhance)==null?void 0:n.call(r,{app:e,router:t,siteData:rn}));return e.use(t),{app:e,router:t}};Pm().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{xe as _,de as a,Nt as b,Z as c,Pm as createVueApp,ne as d,Nc as e,j as o,bt as r}; +function __vite__mapDeps(indexes) { + if (!__vite__mapDeps.viteFileDeps) { + __vite__mapDeps.viteFileDeps = [] + } + return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) +} \ No newline at end of file diff --git a/assets/changelog.html-HK_jZl0_.js b/assets/changelog.html-HK_jZl0_.js new file mode 100644 index 0000000..0a573d1 --- /dev/null +++ b/assets/changelog.html-HK_jZl0_.js @@ -0,0 +1 @@ +import{_ as a,r as s,o as d,c as l,a as e,b as o,d as n,e as i}from"./app-aH6YcK-Q.js";const c={},r=i(' # Changelog
The version update history of
Gropifyis recorded here.Pay Attention
We will only maintain the latest API version. If you are using an outdated API version, you voluntarily renounce any possibility of maintenance.
',4),u={id:"_1-0-1-2025-11-16",tabindex:"-1"},h=e("a",{class:"header-anchor",href:"#_1-0-1-2025-11-16","aria-hidden":"true"},"#",-1),p=i("Notice
To avoid translation time consumption, Changelog will use Google Translation from Chinese to English, please refer to the original text for actual reference.
Time zone of version release date: UTC+8
",1),g={id:"_1-0-0-2025-11-11",tabindex:"-1"},f=e("a",{class:"header-anchor",href:"#_1-0-0-2025-11-11","aria-hidden":"true"},"#",-1),m=e("ul",null,[e("li",null,"The first version is submitted to Maven")],-1);function _(y,v){const t=s("Badge");return d(),l("div",null,[r,e("h3",u,[h,o(" 1.0.1 | 2025.11.16 "),n(t,{type:"tip",text:"latest",vertical:"middle"})]),p,e("h3",g,[f,o(" 1.0.0 | 2025.11.11 "),n(t,{type:"warning",text:"stale",vertical:"middle"})]),m])}const b=a(c,[["render",_],["__file","changelog.html.vue"]]);export{b as default}; diff --git a/assets/changelog.html-OIxI57Wq.js b/assets/changelog.html-OIxI57Wq.js new file mode 100644 index 0000000..675651f --- /dev/null +++ b/assets/changelog.html-OIxI57Wq.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3f851d14","path":"/en/about/changelog.html","title":"Changelog","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"1.0.1 | 2025.11.16","slug":"_1-0-1-2025-11-16","link":"#_1-0-1-2025-11-16","children":[]},{"level":3,"title":"1.0.0 | 2025.11.11","slug":"_1-0-0-2025-11-11","link":"#_1-0-0-2025-11-11","children":[]}],"git":{"updatedTime":1763226900000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":2}]},"filePathRelative":"en/about/changelog.md"}');export{e as data}; diff --git a/assets/changelog.html-dsukWq08.js b/assets/changelog.html-dsukWq08.js new file mode 100644 index 0000000..b196db2 --- /dev/null +++ b/assets/changelog.html-dsukWq08.js @@ -0,0 +1 @@ +import{_ as a,r as i,o as c,c as n,a as e,b as o,d as l,e as d}from"./app-aH6YcK-Q.js";const s={},r=e("h1",{id:"更新日志",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#更新日志","aria-hidden":"true"},"#"),o(" 更新日志")],-1),_=e("blockquote",null,[e("p",null,[o("这里记录了 "),e("code",null,"Gropify"),o(" 的版本更新历史。")])],-1),h=e("div",{class:"custom-container danger"},[e("p",{class:"custom-container-title"},"特别注意"),e("p",null,"我们只会对最新的 API 版本进行维护,若你正在使用过时的 API 版本则代表你自愿放弃一切维护的可能性。")],-1),u={id:"_1-0-1-2025-11-16",tabindex:"-1"},p=e("a",{class:"header-anchor",href:"#_1-0-1-2025-11-16","aria-hidden":"true"},"#",-1),m=d("
- Fixed the issue where
permanentKeyValueswas incorrectly configured toreplacementKeyValues- Optimized the automatic type conversion function for property key-values, fixed the problem of negative long integers being converted to integers
- Optimized log output function, added tags and text colors for each type of log
- Added
keyValueRulesto manually specify the type of property key-values, effective whenuseTypeAutoConversionis enabled- Enhanced debugging function, added detailed log output in debug mode
- Fixed the issue where
extensionNamewas judged as empty and illegal under default settings- Added judgment content for default extension method names that may cause conflicts
- Added
manifestPlaceholdersproperty key-value synchronization function toandroidconfiguration method block- Fixed the problem of Javapoet and Kotlinpoet processing special escape characters in source code generation
- Fixed other issues that may cause build script compilation failure
",1),f={id:"_1-0-0-2025-11-11",tabindex:"-1"},x=e("a",{class:"header-anchor",href:"#_1-0-0-2025-11-11","aria-hidden":"true"},"#",-1),v=e("ul",null,[e("li",null,"首个版本提交至 Maven")],-1);function g(y,V){const t=i("Badge");return c(),n("div",null,[r,_,h,e("h3",u,[p,o(" 1.0.1 | 2025.11.16 "),l(t,{type:"tip",text:"最新",vertical:"middle"})]),m,e("h3",f,[x,o(" 1.0.0 | 2025.11.11 "),l(t,{type:"warning",text:"过旧",vertical:"middle"})]),v])}const B=a(s,[["render",g],["__file","changelog.html.vue"]]);export{B as default}; diff --git a/assets/changelog.html-xI7_Sq17.js b/assets/changelog.html-xI7_Sq17.js new file mode 100644 index 0000000..057f008 --- /dev/null +++ b/assets/changelog.html-xI7_Sq17.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-0e6c3476","path":"/zh-cn/about/changelog.html","title":"更新日志","lang":"zh-CN","frontmatter":{},"headers":[{"level":3,"title":"1.0.1 | 2025.11.16","slug":"_1-0-1-2025-11-16","link":"#_1-0-1-2025-11-16","children":[]},{"level":3,"title":"1.0.0 | 2025.11.11","slug":"_1-0-0-2025-11-11","link":"#_1-0-0-2025-11-11","children":[]}],"git":{"updatedTime":1763226900000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":2}]},"filePathRelative":"zh-cn/about/changelog.md"}');export{e as data}; diff --git a/assets/contacts.html-fepWrcVL.js b/assets/contacts.html-fepWrcVL.js new file mode 100644 index 0000000..4539fc3 --- /dev/null +++ b/assets/contacts.html-fepWrcVL.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-193cf592","path":"/en/about/contacts.html","title":"Contact Us","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Help with Maintenance","slug":"help-with-maintenance","link":"#help-with-maintenance","children":[]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"en/about/contacts.md"}');export{t as data}; diff --git a/assets/contacts.html-mhfINZEn.js b/assets/contacts.html-mhfINZEn.js new file mode 100644 index 0000000..0187ca9 --- /dev/null +++ b/assets/contacts.html-mhfINZEn.js @@ -0,0 +1 @@ +import{_ as r,r as a,o as l,c as s,a as e,b as t,d as o}from"./app-aH6YcK-Q.js";const c={},_=e("h1",{id:"联系我们",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#联系我们","aria-hidden":"true"},"#"),t(" 联系我们")],-1),i=e("blockquote",null,[e("p",null,"如在使用中有任何问题,或有任何建设性的建议,都可以联系我们。")],-1),h=e("p",null,"加入我们的开发者群组。",-1),d={href:"https://t.me/HighCapable_Dev",target:"_blank",rel:"noopener noreferrer"},u={href:"https://qm.qq.com/cgi-bin/qm/qr?k=Pnsc5RY6N2mBKFjOLPiYldbAbprAU3V7&jump_from=webapi&authKey=X5EsOVzLXt1dRunge8ryTxDRrh9/IiW1Pua75eDLh9RE3KXE+bwXIYF5cWri/9lf",target:"_blank",rel:"noopener noreferrer"},p=e("strong",null,"酷安",-1),f={href:"http://www.coolapk.com/u/876977",target:"_blank",rel:"noopener noreferrer"},m=e("h2",{id:"助力维护",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#助力维护","aria-hidden":"true"},"#"),t(" 助力维护")],-1),b=e("p",null,[t("感谢您选择并使用 "),e("code",null,"Gropify"),t(",如有代码相关的建议和请求,可在 GitHub 提交 Pull Request。")],-1);function k(x,g){const n=a("ExternalLinkIcon");return l(),s("div",null,[_,i,h,e("ul",null,[e("li",null,[e("a",d,[t("点击加入 Telegram 群组 (开发者)"),o(n)])]),e("li",null,[e("a",u,[t("点击加入 QQ 群 (开发者)"),o(n)])])]),e("p",null,[t("在 "),p,t(" 找到我 "),e("a",f,[t("@星夜不荟"),o(n)]),t("。")]),m,b])}const E=r(c,[["render",k],["__file","contacts.html.vue"]]);export{E as default}; diff --git a/assets/contacts.html-oiF8uxsH.js b/assets/contacts.html-oiF8uxsH.js new file mode 100644 index 0000000..eb1a32d --- /dev/null +++ b/assets/contacts.html-oiF8uxsH.js @@ -0,0 +1 @@ +const t=JSON.parse('{"key":"v-6cf86266","path":"/zh-cn/about/contacts.html","title":"联系我们","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"助力维护","slug":"助力维护","link":"#助力维护","children":[]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"zh-cn/about/contacts.md"}');export{t as data}; diff --git a/assets/contacts.html-umJCUAv2.js b/assets/contacts.html-umJCUAv2.js new file mode 100644 index 0000000..ce333e3 --- /dev/null +++ b/assets/contacts.html-umJCUAv2.js @@ -0,0 +1 @@ +import{_ as a,r as s,o as r,c,a as e,b as n,d as o}from"./app-aH6YcK-Q.js";const l={},i=e("h1",{id:"contact-us",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#contact-us","aria-hidden":"true"},"#"),n(" Contact Us")],-1),u=e("blockquote",null,[e("p",null,"If you have any questions during usage, or have any constructive suggestions, you can contact us.")],-1),h=e("p",null,"Join our developers group.",-1),d={href:"https://t.me/HighCapable_Dev",target:"_blank",rel:"noopener noreferrer"},_=e("strong",null,"Twitter",-1),p={href:"https://twitter.com/fankesyooni",target:"_blank",rel:"noopener noreferrer"},f=e("h2",{id:"help-with-maintenance",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#help-with-maintenance","aria-hidden":"true"},"#"),n(" Help with Maintenance")],-1),g=e("p",null,[n("Thank you for choosing and using "),e("code",null,"Gropify"),n(".")],-1),m=e("p",null,"If you have code-related suggestions and requests, you can submit a Pull Request on GitHub.",-1);function k(v,y){const t=s("ExternalLinkIcon");return r(),c("div",null,[i,u,h,e("ul",null,[e("li",null,[e("a",d,[n("Click to join Telegram group (Developer)"),o(t)])])]),e("p",null,[n("Find me on "),_,n(),e("a",p,[n("@fankesyooni"),o(t)]),n(".")]),f,g,m])}const x=a(l,[["render",k],["__file","contacts.html.vue"]]);export{x as default}; diff --git a/assets/future.html-LX8OEuCN.js b/assets/future.html-LX8OEuCN.js new file mode 100644 index 0000000..c41dc2b --- /dev/null +++ b/assets/future.html-LX8OEuCN.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-3106ca14","path":"/zh-cn/about/future.html","title":"展望未来","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"未来的计划","slug":"未来的计划","link":"#未来的计划","children":[{"level":3,"title":"支持更多项目类型","slug":"支持更多项目类型","link":"#支持更多项目类型","children":[]}]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"zh-cn/about/future.md"}');export{e as data}; diff --git a/assets/future.html-T9ih0RxQ.js b/assets/future.html-T9ih0RxQ.js new file mode 100644 index 0000000..cd06e4a --- /dev/null +++ b/assets/future.html-T9ih0RxQ.js @@ -0,0 +1 @@ +import{_ as e,o as t,c as o,e as r}from"./app-aH6YcK-Q.js";const a={},d=r('
- 修复
permanentKeyValues被错误地配置到replacementKeyValues的问题- 优化属性键值的类型自动转换功能,修复负数长整型被转换为整型的问题
- 优化日志输出功能,加入每种日志的标签和文字颜色
- 新增
keyValueRules可手动指定属性键值的类型,在启用了useTypeAutoConversion时生效- 增强调试功能,加入了调试模式下的详细日志输出
- 修复
extensionName在默认设置情况下被判断为空格式非法的问题- 增加了可能造成冲突的默认扩展方法名称判断内容
android配置方法块新增manifestPlaceholders属性键值同步功能- 修复源代码生成 Javapoet 和 Kotlinpoet 处理特殊转义字符的问题
- 修复其它可能导致构建脚本编译失败的问题
# Looking Toward the Future
The future is bright and uncertain, let us look forward to the future development potential of
Gropify.# Future Plans
Features that
Gropifymay add later are included here.# Support More Project Types
',6),c=[d];function u(n,i){return t(),o("div",null,c)}const p=e(a,[["render",u],["__file","future.html.vue"]]);export{p as default}; diff --git a/assets/future.html-UrATvnbP.js b/assets/future.html-UrATvnbP.js new file mode 100644 index 0000000..6df0223 --- /dev/null +++ b/assets/future.html-UrATvnbP.js @@ -0,0 +1 @@ +import{_ as e,o,c as a,e as r}from"./app-aH6YcK-Q.js";const t={},c=r('
Gropifycurrently supports generating properties into the source code of Kotlin, Java, and Android projects. In the future, it may support more projects that can participate in Gradle builds, such as C/C++ (Android JNI), Swift, etc., to meet the needs of more developers.# 展望未来
未来是美好的,也是不确定的,让我们共同期待
Gropify在未来的发展空间。# 未来的计划
这里收录了
Gropify可能会在后期添加的功能。# 支持更多项目类型
',6),d=[c];function i(n,h){return o(),a("div",null,d)}const l=e(t,[["render",i],["__file","future.html.vue"]]);export{l as default}; diff --git a/assets/future.html-mEvcxp6P.js b/assets/future.html-mEvcxp6P.js new file mode 100644 index 0000000..f1290cd --- /dev/null +++ b/assets/future.html-mEvcxp6P.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-ae7b83f2","path":"/en/about/future.html","title":"Looking Toward the Future","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Future Plans","slug":"future-plans","link":"#future-plans","children":[{"level":3,"title":"Support More Project Types","slug":"support-more-project-types","link":"#support-more-project-types","children":[]}]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"en/about/future.md"}');export{e as data}; diff --git a/assets/home.html-2op2IBCZ.js b/assets/home.html-2op2IBCZ.js new file mode 100644 index 0000000..8779152 --- /dev/null +++ b/assets/home.html-2op2IBCZ.js @@ -0,0 +1,11 @@ +import{_ as n,r,o as i,c as l,a as e,b as s,d as a,e as p}from"./app-aH6YcK-Q.js";const t={},c=e("h1",{id:"introduction",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#introduction","aria-hidden":"true"},"#"),s(" Introduction")],-1),d=e("blockquote",null,[e("p",null,[e("code",null,"Gropify"),s(" is a type-safe and modern properties plugin for Gradle.")])],-1),u=e("h2",{id:"background",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#background","aria-hidden":"true"},"#"),s(" Background")],-1),y=e("p",null,[s("This plugin is designed for Gradle build scripts. It aims to bring properties similar to those in the "),e("code",null,"gradle.properties"),s(" file into build scripts in a type-safe way, avoiding problems that hard-coded strings might cause.")],-1),h={href:"https://github.com/Lagrio",target:"_blank",rel:"noopener noreferrer"},m=e("strong",null,"G",-1),g=e("strong",null,"ropify",-1),b={href:"https://github.com/HighCapable/SweetProperty",target:"_blank",rel:"noopener noreferrer"},f=p(`
Gropify目前支持将属性生成到 Kotlin、Java 和 Android 项目的源代码中,在未来可能会支持更多能够参与 Gradle 构建的项目,例如 C/C++ (Android JNI)、Swift 等,以满足更多开发者的需求。The configuration plan format of
Gropifyis similar toSweetProperty. If you are usingSweetProperty, you can consider migrating toGropify.# Usage
Gropifyis mainly designed for Kotlin DSL build scripts. Groovy can directly use properties from thegradle.propertiesfile as variables, but you can still useGropifyto achieve type-safe property access.
Gropifyalso supports generating properties (similar to those defined in agradle.propertiesfile) in a type-safe way into the source code of Kotlin, Java, and Android projects for use at application runtime—similar to Android'sBuildConfig'sbuildConfigFieldfeature.Suppose we have the following
gradle.propertiesfile.The following example
project.app.name=Gropify-Demo +project.app.version=1.0.0 +Here is an example of calling the code automatically generated by
Gropify.Build Script (Kotlin DSL, Groovy DSL)
val appName = gropify.project.app.name +val appVersion = gropify.project.app.version +def appName = gropify.project.app.name +def appVersion = gropify.project.app.version +Source Code (Kotlin, Java)
val appName = MyAppProperties.PROJECT_APP_NAME +val appVersion = MyAppProperties.PROJECT_APP_VERSION +var appName = MyAppProperties.PROJECT_APP_NAME; +var appVersion = MyAppProperties.PROJECT_APP_VERSION; +
Gropifyalso supports Kotlin Multiplatform projects, and you can use the generated property classes in thecommonMainsource set.# Language Requirement
It's recommended to use Kotlin DSL to configure your project's build scripts. Groovy is also supported, but in pure Groovy projects some configuration syntax may have compatibility issues.
In Groovy DSL, we will no longer be responsible for troubleshooting and fixing any issues that arise from using this plugin, and it may be completely unsupported in future versions.
# Contribution
The maintenance of this project is inseparable from the support and contributions of all developers.
This project is currently in its early stages, and there may still be some problems or lack of functions you need.
`,21),v={href:"https://github.com/HighCapable/Gropify/issues",target:"_blank",rel:"noopener noreferrer"};function _(k,A){const o=r("ExternalLinkIcon");return i(),l("div",null,[c,d,u,y,e("p",null,[s("The project icon was designed by "),e("a",h,[s("MaiTungTM"),a(o)]),s(". The name comes from "),m,s("radleP"),g,s(", meaning a plugin for Gradle properties.")]),e("p",null,[s("It is a brand-new project rebuilt from "),e("a",b,[s("SweetProperty"),a(o)]),s(", borrowing previous design ideas and making it more polished and easier to use.")]),f,e("p",null,[s("If possible, feel free to submit a PR to contribute features you think are needed to this project or go to "),e("a",v,[s("GitHub Issues"),a(o)]),s(" to make suggestions to us.")])])}const D=n(t,[["render",_],["__file","home.html.vue"]]);export{D as default}; diff --git a/assets/home.html-9eiAlurd.js b/assets/home.html-9eiAlurd.js new file mode 100644 index 0000000..6dbd892 --- /dev/null +++ b/assets/home.html-9eiAlurd.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-6a609e09","path":"/zh-cn/guide/home.html","title":"介绍","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"背景","slug":"背景","link":"#背景","children":[]},{"level":2,"title":"用途","slug":"用途","link":"#用途","children":[]},{"level":2,"title":"语言要求","slug":"语言要求","link":"#语言要求","children":[]},{"level":2,"title":"功能贡献","slug":"功能贡献","link":"#功能贡献","children":[]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"zh-cn/guide/home.md"}');export{e as data}; diff --git a/assets/home.html-TFY4cEol.js b/assets/home.html-TFY4cEol.js new file mode 100644 index 0000000..46f19df --- /dev/null +++ b/assets/home.html-TFY4cEol.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-efb45d4c","path":"/en/guide/home.html","title":"Introduction","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Background","slug":"background","link":"#background","children":[]},{"level":2,"title":"Usage","slug":"usage","link":"#usage","children":[]},{"level":2,"title":"Language Requirement","slug":"language-requirement","link":"#language-requirement","children":[]},{"level":2,"title":"Contribution","slug":"contribution","link":"#contribution","children":[]}],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"en/guide/home.md"}');export{e as data}; diff --git a/assets/home.html-no62ZQLF.js b/assets/home.html-no62ZQLF.js new file mode 100644 index 0000000..d3692b6 --- /dev/null +++ b/assets/home.html-no62ZQLF.js @@ -0,0 +1,11 @@ +import{_ as n,r as l,o as p,c as r,a as e,b as s,d as o,e as i}from"./app-aH6YcK-Q.js";const c={},t=e("h1",{id:"介绍",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#介绍","aria-hidden":"true"},"#"),s(" 介绍")],-1),d=e("blockquote",null,[e("p",null,[e("code",null,"Gropify"),s(" 是一个类型安全且现代化的 Gradle 属性插件。")])],-1),y=e("h2",{id:"背景",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#背景","aria-hidden":"true"},"#"),s(" 背景")],-1),u=e("p",null,[s("这是一个为 Gradle 构建脚本设计的插件,旨在将类似 "),e("code",null,"gradle.properties"),s(" 文件中的属性以类型安全的方式引入到构建脚本中,从而避免硬编码字符串可能带来的问题。")],-1),h={href:"https://github.com/Lagrio",target:"_blank",rel:"noopener noreferrer"},v=e("strong",null,"G",-1),m=e("strong",null,"ropify",-1),b={href:"https://github.com/HighCapable/SweetProperty",target:"_blank",rel:"noopener noreferrer"},_=i(`
Gropify的配置方案与SweetProperty类似,如果你正在使用SweetProperty,你可以考虑将其迁移到Gropify。# 用途
Gropify主要针对 Kotlin DSL 构建脚本设计,Groovy 语言可以直接将gradle.properties文件中的属性作为变量使用,但是你也可以通过Gropify来实现类型安全的属性访问。
Gropify同时支持将类似gradle.properties文件中的属性以类型安全的方式生成到 Kotlin、Java、Android 项目的源码中以供应用程序运行时使用,功能类似 Android 的BuildConfig中的buildConfigField功能。假设我们有以下
gradle.properties文件。示例如下
project.app.name=Gropify-Demo +project.app.version=1.0.0 +这是
Gropify自动生成的代码调用示例。构建脚本 (Kotlin DSL、Groovy DSL)
val appName = gropify.project.app.name +val appVersion = gropify.project.app.version +def appName = gropify.project.app.name +def appVersion = gropify.project.app.version +源代码 (Kotlin、Java)
val appName = MyAppProperties.PROJECT_APP_NAME +val appVersion = MyAppProperties.PROJECT_APP_VERSION +var appName = MyAppProperties.PROJECT_APP_NAME; +var appVersion = MyAppProperties.PROJECT_APP_VERSION; +
Gropify同样支持 Kotlin Multiplatform 项目,你可以在commonMain源集中使用生成的属性类。# 语言要求
推荐使用 Kotlin DSL 来配置项目的构建脚本,Groovy 语言同样受支持,但在纯 Groovy 项目中部分配置语法可能存在兼容性问题。
在 Groovy DSL 中使用此插件发生的任何问题,我们都将不再负责排查和修复,并且在后期版本可能会完全不再支持 Groovy DSL。
# 功能贡献
`,19),g={href:"https://github.com/HighCapable/Gropify/issues",target:"_blank",rel:"noopener noreferrer"};function A(F,f){const a=l("ExternalLinkIcon");return p(),r("div",null,[t,d,y,u,e("p",null,[s("项目图标由 "),e("a",h,[s("MaiTungTM"),o(a)]),s(" 设计,名称取自 "),v,s("radleP"),m,s(",意为针对 Gradle 属性的插件。")]),e("p",null,[s("它是基于 "),e("a",b,[s("SweetProperty"),o(a)]),s(" 重构的全新项目,借鉴了以往的设计方案,使得其在原有基础上更加完善和易用。")]),_,e("p",null,[s("本项目的维护离不开各位开发者的支持和贡献,目前这个项目处于初期阶段,可能依然存在一些问题或者缺少你需要的功能, 如果可能,欢迎提交 PR 为此项目贡献你认为需要的功能或前往 "),e("a",g,[s("GitHub Issues"),o(a)]),s(" 向我们提出建议。")])])}const k=n(c,[["render",A],["__file","home.html.vue"]]);export{k as default}; diff --git a/assets/index.html-7DNoxpGZ.js b/assets/index.html-7DNoxpGZ.js new file mode 100644 index 0000000..8b4fd3c --- /dev/null +++ b/assets/index.html-7DNoxpGZ.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-aH6YcK-Q.js";const n={};function _(o,r){return c(),t("div")}const a=e(n,[["render",_],["__file","index.html.vue"]]);export{a as default}; diff --git a/assets/index.html-7LpniZrm.js b/assets/index.html-7LpniZrm.js new file mode 100644 index 0000000..9c52c22 --- /dev/null +++ b/assets/index.html-7LpniZrm.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-c0c85b84","path":"/zh-cn/","title":"首页","lang":"zh-CN","frontmatter":{"home":true,"title":"首页","heroImage":"/images/logo.svg","actions":[{"text":"快速上手","link":"/zh-cn/guide/home","type":"primary"},{"text":"更新日志","link":"/zh-cn/about/changelog","type":"secondary"}],"footer":"Apache-2.0 License | Copyright (C) 2019 HighCapable"},"headers":[],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"zh-cn/index.md"}');export{e as data}; diff --git a/assets/index.html-H28pjygm.js b/assets/index.html-H28pjygm.js new file mode 100644 index 0000000..8b4fd3c --- /dev/null +++ b/assets/index.html-H28pjygm.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-aH6YcK-Q.js";const n={};function _(o,r){return c(),t("div")}const a=e(n,[["render",_],["__file","index.html.vue"]]);export{a as default}; diff --git a/assets/index.html-J5Mpt7Vl.js b/assets/index.html-J5Mpt7Vl.js new file mode 100644 index 0000000..e2802a0 --- /dev/null +++ b/assets/index.html-J5Mpt7Vl.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-2d0a870d","path":"/en/","title":"Home","lang":"en-US","frontmatter":{"home":true,"title":"Home","heroImage":"/images/logo.svg","actions":[{"text":"Get Started","link":"/en/guide/home","type":"primary"},{"text":"Changelog","link":"/en/about/changelog","type":"secondary"}],"footer":"Apache-2.0 License | Copyright (C) 2019 HighCapable"},"headers":[],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"en/index.md"}');export{e as data}; diff --git a/assets/index.html-WpXt5Cz7.js b/assets/index.html-WpXt5Cz7.js new file mode 100644 index 0000000..8b4fd3c --- /dev/null +++ b/assets/index.html-WpXt5Cz7.js @@ -0,0 +1 @@ +import{_ as e,o as c,c as t}from"./app-aH6YcK-Q.js";const n={};function _(o,r){return c(),t("div")}const a=e(n,[["render",_],["__file","index.html.vue"]]);export{a as default}; diff --git a/assets/index.html-zPqCtEf7.js b/assets/index.html-zPqCtEf7.js new file mode 100644 index 0000000..ff4ec75 --- /dev/null +++ b/assets/index.html-zPqCtEf7.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-8daa1a0e","path":"/","title":"","lang":"en-US","frontmatter":{"home":true,"navbar":false,"sidebar":false,"title":null,"heroAlt":null,"heroText":null,"tagline":"Select a language","actions":[{"text":"English","link":"/en/","type":"secondary"},{"text":"简体中文","link":"/zh-cn/","type":"secondary"}],"footer":"Apache-2.0 License | Copyright (C) 2019 HighCapable"},"headers":[],"git":{"updatedTime":1762849016000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":1}]},"filePathRelative":"index.md"}');export{e as data}; diff --git a/assets/quick-start.html-7AxcUCW_.js b/assets/quick-start.html-7AxcUCW_.js new file mode 100644 index 0000000..027851e --- /dev/null +++ b/assets/quick-start.html-7AxcUCW_.js @@ -0,0 +1 @@ +const i=JSON.parse('{"key":"v-72889797","path":"/en/guide/quick-start.html","title":"Quick Start","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Deploy Plugin","slug":"deploy-plugin","link":"#deploy-plugin","children":[]},{"level":2,"title":"Feature Configuration","slug":"feature-configuration","link":"#feature-configuration","children":[{"level":3,"title":"Common Configuration","slug":"common-configuration","link":"#common-configuration","children":[]},{"level":3,"title":"Build Script Configuration","slug":"build-script-configuration","link":"#build-script-configuration","children":[]},{"level":3,"title":"Android Project Configuration","slug":"android-project-configuration","link":"#android-project-configuration","children":[]},{"level":3,"title":"JVM Project Configuration","slug":"jvm-project-configuration","link":"#jvm-project-configuration","children":[]},{"level":3,"title":"Kotlin Multiplatform Project Configuration","slug":"kotlin-multiplatform-project-configuration","link":"#kotlin-multiplatform-project-configuration","children":[]}]},{"level":2,"title":"Usage Examples","slug":"usage-examples","link":"#usage-examples","children":[]},{"level":2,"title":"Possible Issues","slug":"possible-issues","link":"#possible-issues","children":[]},{"level":2,"title":"Limitations","slug":"limitations","link":"#limitations","children":[]}],"git":{"updatedTime":1763223336000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":5}]},"filePathRelative":"en/guide/quick-start.md"}');export{i as data}; diff --git a/assets/quick-start.html-f_E-gIx7.js b/assets/quick-start.html-f_E-gIx7.js new file mode 100644 index 0000000..b31d6b0 --- /dev/null +++ b/assets/quick-start.html-f_E-gIx7.js @@ -0,0 +1,493 @@ +import{_ as s,o as n,c as a,e}from"./app-aH6YcK-Q.js";const l={},o=e(`# Quick Start
Integrate
Gropifyinto your project.# Deploy Plugin
Gropifydependencies are published on Maven Central and our public repository. You can configure the repository as follows.We recommend using Gradle version
7.x.xor higher, and recommend using Kotlin DSL as the Gradle build script language. This documentation will no longer detail how to use it in Groovy DSL.We recommend using the new
pluginManagementmethod for deployment, which is a feature added since Gradle version7.x.x.If your project is still using
buildscriptfor management, we recommend migrating to the new method. Instructions for the old version will no longer be provided here.First, configure the plugin repository in your project's
settings.gradle.kts.The following example
pluginManagement { + repositories { + gradlePluginPortal() // Optional + google() // Optional + mavenCentral() // Required + // (Optional) You can add this URL to use our public repository + // This repository is added as an alternative when Sonatype-OSS fails to publish dependencies + // For details, please visit: https://github.com/HighCapable/maven-repository + maven("https://raw.githubusercontent.com/HighCapable/maven-repository/main/repository/releases") + } +} +Then add the
Gropifyplugin dependency inplugininsettings.gradle.kts. Please note do not addapply falseafter it.The following example
plugins { + id("com.highcapable.gropify") version "<version>" +} +Please replace
<version>with the version shown at the top of this section.After completing the above configuration, run Gradle sync once.
Gropifywill automatically search forgradle.propertiesfiles in the root project and each subproject, read the property key-values in them, and generate corresponding code for each project.Notice
Gropifycan only be applied tosettings.gradle.kts, configuring it once will take effect globally. Please do not apply it tobuild.gradle.kts, otherwise the functionality will be invalid.# Feature Configuration
You can configure
Gropifyto implement customization and personalized features.
Gropifyprovides relatively rich customizable features. Below are the descriptions and configuration methods for these features.Please add the
gropifymethod block in yoursettings.gradle.ktsto start configuringGropify.To use in Groovy DSL, please change all variable
=to spaces, removeisbeforeEnabled.If you encounter a
Gradle DSL method not founderror, the solution is to migrate to Kotlin DSL.If you don't want to use Kotlin DSL entirely, you can also migrate only
settings.gradletosettings.gradle.kts.The following example
gropify { + // Enable Gropify, setting it to \`false\` will disable all features. + isEnabled = true + + // Whether to enable debug mode. + // + // You can help us identify the problem by enabling this option + // to print more debugging information in the logs. + // + // - Note: THIS IS ONLY FOR DEBUGGING! + // The debug log will contain your local environment, + // which may contain sensitive information. + // Please be sure to protect this information. + debugMode = false +} +
Gropify's configuration mode is divided into three types:globalglobal configuration, androotProject,projectsroot project and subproject configuration.You can continue to configure and integrate the configuration of the parent project in the child code blocks.
All configurations below are performed in the
gropifymethod block.The following example
// Global configuration. +// +// You can modify configurations in all projects in the global configuration. +// Configurations not declared in each project will use the global configuration. +// The functions in each configuration method block are exactly the same. +// +// You can refer to the configuration methods of root project and subprojects below. +global { + // Common configuration. + common { + // Configure "common". + } + + // Build script configuration. + buildscript { + // Configure "buildscript". + } + + // Android project configuration. + android { + // Configure "android". + } + + // JVM project configuration. + jvm { + // Configure "jvm". + } + + // Kotlin Multiplatform project configuration. + kmp { + // Configure "kmp". + } +} + +// Root project configuration. +// +// This is a special configuration method block that can only be used for the root project. +rootProject { + common { + // Configure "common". + } + buildscript { + // Configure "buildscript". + } + android { + // Configure "android". + } + jvm { + // Configure "jvm". + } + kmp { + // Configure "kmp". + } +} + +// Other projects and subprojects configuration. +// +// Fill in the full name of the project you need to configure in the +// method parameters to configure the corresponding project. +// +// If the current project is a subproject, you must include the ":" before +// the subproject name, such as ":app". +// +// If the current project is a nested subproject, such as app → sub, +// you need to use ":" to separate multiple subprojects, such as ":app:sub". +// +// The name of the root project cannot be used directly to configure subprojects, +// please use "rootProject". +// +// You can configure multiple projects and subprojects at the same time by filling +// in an array of full project names in the method parameters to +// configure each corresponding project. +projects(":app", ":modules:library1", ":modules:library2") { + common { + // Configure "common". + } + buildscript { + // Configure "buildscript". + } + android { + // Configure "android". + } + jvm { + // Configure "jvm". + } + kmp { + // Configure "kmp". + } +} +You can continue below to learn how to configure the features in each method block.
# Common Configuration
Here you can configure related features for all configuration types at the same time. The configurations here will be applied down to Build Script Configuration, Android Project Configuration, JVM Project Configuration, Kotlin Multiplatform Project Configuration.
The following example
common { + // Enable feature. + // + // You can set [buildscript], [android], [jvm], [kmp] separately. + isEnabled = true + + // Whether to exclude the non-string type key-values content. + // + // Enabled by default, when enabled, key-values and content that are not + // string types will be excluded from properties' key-values. + excludeNonStringValue = true + + // Whether to use type auto conversion. + // + // Enabled by default, when enabled, the type in the properties' key-values will be + // automatically identified and converted to the corresponding type. + // + // After enabling, if you want to force the content of a key-values to be a string type, + // you can use single quotes or double quotes to wrap the entire string. + // + // - Note: After disabled this function, the functions mentioned above will also be invalid. + useTypeAutoConversion = true + + // Whether to use key-values content interpolation. + // + // Enabled by default, after enabling it will automatically identify + // the \`\${...}\` content in the properties' key-values content and replace it. + // + // Note: The interpolated content will only be looked up from the + // current (current configuration file) properties' key-values list. + useValueInterpolation = true + + // Set exists property files. + // + // The property files will be automatically obtained from the root directory + // of the current root project, + // subproject and user directory according to the file name you set. + // + // By default, will add "gradle.properties" if [addDefault] is \`true\`. + // + // You can add multiple sets of property files name, they will be read in order. + // + // - Note: Generally there is no need to modify this setting, + // an incorrect file name will result in obtaining empty key-values content. + existsPropertyFiles( + "some-other-1.properties", + "some-other-2.properties", + addDefault = true + ) + + // Set a permanent list of properties' key-values. + // + // Here you can set some key-values that must exist, these key-values will be + // generated regardless of whether they can be obtained from the properties' key-values. + // + // These keys use the content of the properties' key if it exists, + // use the content set here if it does not exist. + // + // - Note: Special symbols and spaces cannot exist in properties' key names, + // otherwise the generation may fail. + permanentKeyValues( + "permanent.some.key1" to "some_value_1", + "permanent.some.key2" to "some_value_2" + ) + + // Set a replacement list of properties' key-values. + // + // Here you can set some key-values that need to be replaced, these key-values + // will be replaced the existing properties' key-values, if not exist, they will be ignored. + // + // The key-values set here will also overwrite the key-values set in [permanentKeyValues]. + replacementKeyValues( + "some.key1" to "new.value1", + "some.key2" to "new.value2" + ) + + // Set a key list of properties' key-values name that need to be excluded. + // + // Here you can set some key names that you want to exclude from + // known properties' key-values. + // + // These keys are excluded if they are present in the properties' key, + // will not appear in the generated code. + // + // - Note: If you exclude key-values set in [permanentKeyValues], then they will + // only change to the initial key-values content you set and continue to exist. + excludeKeys( + "exclude.some.key1", + "exclude.some.key2" + ) + + // Set a key list of properties' key-values name that need to be included. + // + // Here you can set some key value names that you want to include from + // known properties' key-values. + // + // These keys are included if the properties' key exists, + // unincluded keys will not appear in the generated code. + includeKeys( + "include.some.key1", + "include.some.key2" + ) + + // Set properties' key-values rules. + // + // You can set up a set of key-values rules, + // use [ValueRule] to create new rule for parsing the obtained key-values content. + // + // These key-values rules are applied when properties' keys exist. + keyValuesRules( + "some.key1" to ValueRule { if (it.contains("_")) it.replace("_", "-") else it }, + "some.key2" to ValueRule { "$it-value" }, + // You can also specify the expected type class, + // the type you specify will be used during generation, + // and an exception will be thrown if the type cannot be converted correctly. + // If the [useTypeAutoConversion] is not enabled, this parameter will be ignored. + "some.key3" to ValueRule(Int::class) + ) + + // Set where to find properties' key-values. + // + // Defaults are [GropifyLocation.CurrentProject], [GropifyLocation.RootProject]. + // + // You can set this up using the following types. + // + // - [GropifyLocation.CurrentProject] + // - [GropifyLocation.RootProject] + // - [GropifyLocation.Global] + // - [GropifyLocation.System] + // - [GropifyLocation.SystemEnv] + // + // We will generate properties' key-values in sequence from the locations you set, + // the order of the generation locations follows the order you set. + // + // - Risk warning: [GropifyLocation.Global], [GropifyLocation.System], + // [GropifyLocation.SystemEnv] may have keys and certificates, + // please manage the generated code carefully. + locations(GropifyLocation.CurrentProject, GropifyLocation.RootProject) +} +Tips
When referencing
GropifyLocation, the build script may generate the following at the top of the build script when used with IDE auto-import.import com.highcapable.gropify.plugin.config.type.GropifyLocation +
Gropifydoes alias processing for this, you can directly delete this import statement.# Build Script Configuration
The code generated in the build script can be directly used by the current
build.gradle.kts,build.gradle.The configuration here includes the configuration in
common, and you can override it.The following example
buildscript { + // Custom buildscript extension name. + // + // Default is "gropify". + extensionName = "gropify" +} +Notice
Gradle also has a
buildscriptmethod block, please be careful to use the correct DSL level.# Android Project Configuration
The content in this configuration block only takes effect for projects with AGP.
The configuration here includes the configuration in
common, and you can override it.The following example
android { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment \`sourceSet\` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "main". + sourceSetName = "main" + + // Custom generated package name. + // + // Android projects use the \`namespace\` in the \`android\` configuration method block + // by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to use Kotlin language generation. + // + // Enabled by default, when enabled will generate Kotlin code, + // disabled will generate Java code. + // + // - Note: This option will be disabled when this project is a pure Java project. + useKotlin = true + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the \`internal\` modifier to + // generated Kotlin classes or remove the \`public\` modifier to generated Java classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true + + // Whether to use manifest placeholders' generation. + // + // Disabled by default, when enabled will synchronize the properties' key-values + // to the \`manifestPlaceholders\` in the \`android\` configuration method block. + manifestPlaceholders = false +} +# JVM Project Configuration
The content in this configuration block only takes effect for pure JVM projects (including Kotlin and Java projects). For Android projects, please refer to Android Project Configuration for configuration.
The configuration here includes the configuration in
common, and you can override it.The following example
jvm { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment \`sourceSet\` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "main". + sourceSetName = "main" + + // Custom generated package name. + // + // Java, Kotlin projects use the \`project.group\` of the project settings by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to use Kotlin language generation. + // + // Enabled by default, when enabled will generate Kotlin code, + // disabled will generate Java code. + // + // - Note: This option will be disabled when this project is a pure Java project. + useKotlin = true + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the \`internal\` modifier to + // generated Kotlin classes or remove the \`public\` modifier to generated Java classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true +} +# Kotlin Multiplatform Project Configuration
The content in this configuration block only takes effect for projects with the Kotlin Multiplatform plugin.
The configuration here includes the configuration in
common, and you can override it.The following example
kmp { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment \`sourceSet\` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "commonMain". + sourceSetName = "commonMain" + + // Custom generated package name. + // + // Kotlin Multiplatform projects use the \`project.group\` of the project settings + // by default. + // + // In a Kotlin Multiplatform project, if the AGP plugin is also applied, + // the \`namespace\` will still be used as the package name by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the \`internal\` modifier to + // generated Kotlin classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true +} +# Usage Examples
Below is a project's
gradle.propertiesconfiguration file.The following example
project.groupName=com.highcapable.gropifydemo +project.description=Hello Gropify Demo! +project.version=1.0.0 +In the build script
build.gradle.kts, we can directly use these key-values as shown below.Here is an example of the Maven publish configuration section.
The following example
publications { + create<MavenPublication>("maven") { + groupId = gropify.project.groupName + version = gropify.project.version + pom.description.set(gropify.project.description) + + from(components["java"]) + } +} +Similarly, you can also call the generated key-values in the current project.
Kotlin
val groupName = GropifyDemoProperties.PROJECT_GROUP_NAME +val description = GropifyDemoProperties.PROJECT_DESCRIPTION +val version = GropifyDemoProperties.PROJECT_VERSION +Java
var groupName = GropifyDemoProperties.PROJECT_GROUP_NAME; +var description = GropifyDemoProperties.PROJECT_DESCRIPTION; +var version = GropifyDemoProperties.PROJECT_VERSION; +Let's take another example with an Android project.
In Android projects, many repetitive and fixed properties usually need to be configured, such as
targetSdk.The following example
project.namespace=com.highcapable.gropifydemo +project.appName=Gropify Demo +project.compileSdk=36 +project.targetSdk=36 +project.minSdk=26 +When you set
useTypeAutoConversion = true,Gropifywill try to convert it to the corresponding type during the entity class generation process under the default configuration.For example, the key-values used below can be identified as string and integer types, which can be directly used by the project configuration.
The following example
android { + namespace = gropify.project.namespace + compileSdk = gropify.project.compileSdk + + defaultConfig { + minSdk = gropify.project.minSdk + targetSdk = gropify.project.targetSdk + } +} +When you set
manifestPlaceholders = true, Gropify will automatically synchronize these properties' key-values tomanifestPlaceholdersin the android configuration method block.You can then use these placeholders directly in
AndroidManifest.xml.The following example
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application + android:label="\${project.appName}" + android:icon="@mipmap/ic_launcher"> + + ... + </application> +</manifest> +You no longer need to use
buildConfigFieldto add code toBuildConfig. With the property key-value code generated byGropify, you can manage your project more flexibly.You can also use interpolation
\${...}in property key-values to reference each other's content, but recursive references are not allowed.When you set
useValueInterpolation = true,Gropifywill automatically merge these referenced contents to the corresponding positions.The following example
project.name=MyDemo +project.developer.name=myname +project.url=https://github.com/\${project.developer.name}/\${project.name} +If you add
GropifyLocation.SystemEnvtolocations, you can also directly reference system environment variables.The following example
# Use the $USER environment variable in Linux or macOS systems to get the current username. +project.developer.name=\${USER} +# Assume you have a system environment variable called SECRET_KEY (PLEASE BE SURE TO BE SAFE). +project.secretKey=\${SECRET_KEY} +Notice
This feature is provided by
Gropify. Nativegradle.propertiesdoes not support this feature.The interpolated content is searched and replaced from top to bottom through the
locationshierarchy. If there are duplicate key names, the last found content will be used for replacement.# Possible Issues
If your project only has a root project and no subprojects are imported, and the extension method cannot be generated normally at this time, you can migrate your root project to a subproject and import this subproject in
settings.gradle.kts, which can solve this problem.We generally recommend categorizing the functions of the project, with the root project only used to manage plugins and some configurations.
# Limitations
`,98),p=[o];function i(c,t){return n(),a("div",null,p)}const d=s(l,[["render",i],["__file","quick-start.html.vue"]]);export{d as default}; diff --git a/assets/quick-start.html-umL0lxu-.js b/assets/quick-start.html-umL0lxu-.js new file mode 100644 index 0000000..ec30790 --- /dev/null +++ b/assets/quick-start.html-umL0lxu-.js @@ -0,0 +1,461 @@ +import{_ as s,o as n,c as a,e as l}from"./app-aH6YcK-Q.js";const e={},p=l(`
Gropifycannot generate extension methods insettings.gradle.ktsbecause it is upstream ofGropify.# 快速开始
集成
Gropify到你的项目中。# 部署插件
Gropify的依赖发布在 Maven Central 和我们的公共存储库中,你可以使用如下方式配置存储库。我们建议使用不低于
7.x.x版本的 Gradle,并推荐使用 Kotlin DSL 作为 Gradle 构建脚本语言,文档中将不再详细介绍在 Groovy DSL 中的使用方法。我们推荐使用
pluginManagement新方式进行部署,它是自 Gradle7.x.x版本开始添加的功能。如果你的项目依然在使用
buildscript的方式进行管理,推荐迁移到新方式,这里将不再提供旧版本的使用方式说明。首先,在你的项目
settings.gradle.kts中配置插件的存储库。示例如下
pluginManagement { + repositories { + gradlePluginPortal() // 可选 + google() // 可选 + mavenCentral() // 必须 + // (可选) 你可以添加此 URL 以使用我们的公共存储库 + // 当 Sonatype-OSS 发生故障无法发布依赖时,此存储库作为备选进行添加 + // 详情请前往:https://github.com/HighCapable/maven-repository + maven("https://raw.githubusercontent.com/HighCapable/maven-repository/main/repository/releases") + } +} +然后在
settings.gradle.kts中plugin添加Gropify插件依赖,请注意不要在后方加入apply false。示例如下
plugins { + id("com.highcapable.gropify") version "<version>" +} +请将
<version>修改为此小结顶部显示的版本。上述配置完成后,运行一次 Gradle Sync。
Gropify将会自动搜索根项目和每个子项目中的gradle.properties文件,并读取其中的属性键值,为每个项目生成对应的代码。注意
Gropify只能被应用到settings.gradle.kts中,配置一次即可全局生效,请勿将其应用到build.gradle.kts中,否则功能将会无效。# 功能配置
你可以对
Gropify进行配置来实现自定义和个性化功能。
Gropify为你提供了相对丰富的可自定义功能,下面是这些功能的说明与配置方法。请在你的
settings.gradle.kts中添加gropify方法块以开始配置Gropify。如需在 Groovy DSL 中使用,请将所有变量的
=改为空格,并删除Enabled前方的is即可。如果你遇到了
Gradle DSL method not found错误,解决方案为迁移到 Kotlin DSL。如果你不想全部使用 Kotlin DSL,你也可以仅将
settings.gradle迁移到settings.gradle.kts。示例如下
gropify { + // 启用 Gropify,设置为 \`false\` 将禁用所有功能 + isEnabled = true + + // 是否启用调试模式 + // + // 你可以通过启用此选项在日志中打印更多调试信息帮助我们定位问题 + // + // - 注意: 此功能仅用于调试! + // 调试日志将包含你的本地环境,其中可能包含敏感信息,请务必保护好这些信息 + debugMode = false +} +
Gropify的配置模式分为global全局配置和rootProject、projects根项目和子项目配置三种。你可以在子项的代码块中继续配置和集成顶层项目的配置。
以下配置均在
gropify方法块中进行。示例如下
// 全局配置 +// +// 你可以在全局配置中修改所有项目中的配置 +// 每个项目中未进行声明的配置将使用全局配置 +// 每个配置方法块中的功能完全一致 +// +// 你可以参考下方根项目、子项目的配置方法 +global { + // 通用配置 + common { + // 配置 "common" + } + + // 构建脚本配置 + buildscript { + // 配置 "buildscript" + } + + // Android 项目配置 + android { + // 配置 "android" + } + + // JVM 项目配置 + jvm { + // 配置 "jvm" + } + + // Kotlin 多平台项目配置 + kmp { + // 配置 "kmp" + } +} + +// 根项目 (Root Project) 配置 +// +// 这是一个特殊的配置方法块,只能用于根项目 +rootProject { + common { + // 配置 "common" + } + buildscript { + // 配置 "buildscript" + } + android { + // 配置 "android" + } + jvm { + // 配置 "jvm" + } + kmp { + // 配置 "kmp" + } +} + +// 其它项目与子项目配置 +// +// 在方法参数中填入需要配置的项目完整名称来配置对应的项目 +// +// 如果当前项目是子项目,你必须填写子项目前面的 ":",例如 ":app" +// +// 如果当前项目为嵌套型子项目,例如 app → sub +// 此时你需要使用 ":" 来分隔多个子项目,例如 ":app:sub" +// +// 根项目的名称不能直接用来配置子项目,请使用 "rootProject" +// 你可以同时进行多个项目与子项目配置,在方法参数中填入需要配置的项目完整名称数组来配置每个对应的项目 +projects(":app", ":modules:library1", ":modules:library2") { + common { + // 配置 "common" + } + buildscript { + // 配置 "buildscript" + } + android { + // 配置 "android" + } + jvm { + // 配置 "jvm" + } + kmp { + // 配置 "kmp" + } +} +你可以继续在下方了解如何配置每个方法块中的功能。
# 通用配置
在这里你可以同时配置所有配置类型的相关功能,这里的配置会向下应用到 构建脚本配置、Android 项目配置、JVM 项目配置、Kotlin 多平台项目配置 中。
示例如下
common { + // 启用功能 + // + // 你可以分别对 [buildscript]、[android]、[jvm]、[kmp] 进行设置 + isEnabled = true + + // 是否排除非字符串类型的键值内容 + // + // 默认启用,启用后将排除非字符串类型的键值和内容 + excludeNonStringValue = true + + // 是否使用类型自动转换 + // + // 默认启用,启用后将自动识别属性键值中的类型并转换为对应类型 + // + // 启用后,如果你想强制将键值内容设为字符串类型, + // 可以使用单引号或双引号包裹整个字符串 + // + // - 注意: 禁用此功能后,上述功能也将失效 + useTypeAutoConversion = true + + // 是否使用键值内容插值 + // + // 默认启用,启用后将自动识别属性键值内容中的 \`\${...}\` 并进行替换 + // + // 注意: 插值内容仅会从当前 (当前配置文件) 属性键值列表中查找 + useValueInterpolation = true + + // 设置已存在的属性文件 + // + // 属性文件将根据你设置的文件名自动从当前根项目、 + // 子项目和用户目录的根目录获取 + // + // 默认情况下,如果 [addDefault] 为 \`true\`,将添加 "gradle.properties" + // + // 你可以添加多组属性文件名,它们将按顺序读取 + // + // - 注意: 通常无需修改此设置,错误的文件名将导致获取空键值内容 + existsPropertyFiles( + "some-other-1.properties", + "some-other-2.properties", + addDefault = true + ) + + // 设置永久属性键值列表 + // + // 在这里你可以设置一些必须存在的键值,无论是否能从属性键值中获取, + // 这些键值都将被生成 + // + // 这些键如果存在于属性键中则使用属性键的内容, + // 如果不存在则使用这里设置的内容 + // + // - 注意: 属性键名称中不能存在特殊符号和空格,否则可能导致生成失败 + permanentKeyValues( + "permanent.some.key1" to "some_value_1", + "permanent.some.key2" to "some_value_2" + ) + + // 设置替换属性键值列表 + // + // 在这里你可以设置一些需要替换的键值,这些键值 + // 将替换现有的属性键值,如果不存在则忽略 + // + // 这里设置的键值也会覆盖 [permanentKeyValues] 中设置的键值 + replacementKeyValues( + "some.key1" to "new.value1", + "some.key2" to "new.value2" + ) + + // 设置需要排除的属性键值名称列表 + // + // 在这里你可以设置一些要从已知属性键值中排除的键名称 + // + // 如果这些键存在于属性键中则排除它们, + // 不会出现在生成的代码中 + // + // - 注意: 如果你排除了 [permanentKeyValues] 中设置的键值,那么它们将 + // 仅更改为你设置的初始键值内容并继续存在 + excludeKeys( + "exclude.some.key1", + "exclude.some.key2" + ) + + // 设置需要包含的属性键值名称列表 + // + // 在这里你可以设置一些要从已知属性键值中包含的键名称 + // + // 如果属性键存在则包含这些键,未包含的键不会出现在生成的代码中 + includeKeys( + "include.some.key1", + "include.some.key2" + ) + + // 设置属性键值规则 + // + // 你可以设置一组键值规则, + // 使用 [ValueRule] 创建新规则来解析获取的键值内容 + // + // 当属性键存在时应用这些键值规则 + keyValuesRules( + "some.key1" to ValueRule { if (it.contains("_")) it.replace("_", "-") else it }, + "some.key2" to ValueRule { "$it-value" }, + // 你还可以指定期望的类型类,生成时将使用你指定的类型, + // 如果类型无法正确转换,将抛出异常 + // 如果未启用 [useTypeAutoConversion],此参数将被忽略 + "some.key3" to ValueRule(Int::class) + ) + + // 设置查找属性键值的位置 + // + // 默认为 [GropifyLocation.CurrentProject]、[GropifyLocation.RootProject] + // + // 你可以使用以下类型进行设置 + // + // - [GropifyLocation.CurrentProject] + // - [GropifyLocation.RootProject] + // - [GropifyLocation.Global] + // - [GropifyLocation.System] + // - [GropifyLocation.SystemEnv] + // + // 我们将按顺序从你设置的位置生成属性键值,生成位置的顺序遵循你设置的顺序 + // + // - 风险警告: [GropifyLocation.Global]、[GropifyLocation.System]、 + // [GropifyLocation.SystemEnv] 可能包含密钥和证书,请谨慎管理生成的代码 + locations(GropifyLocation.CurrentProject, GropifyLocation.RootProject) +} +小提示
在引用
GropifyLocation时,构建脚本在配合 IDE 自动导入时可能会在构建脚本顶部生成以下内容。import com.highcapable.gropify.plugin.config.type.GropifyLocation +
Gropify对此做了 alias 处理,你可以直接删除此 import 语句。# 构建脚本配置
在构建脚本中生成的代码可直接被当前
build.gradle.kts、build.gradle使用。这里的配置包括
common中的配置,你可以对其进行复写。示例如下
buildscript { + // 自定义构建脚本扩展名称 + // + // 默认为 "gropify" + extensionName = "gropify" +} +注意
Gradle 中也有一个
buildscript方法块,请注意使用正确的 DSL 层级。# Android 项目配置
此配置块中的内容仅对存在 AGP 的项目生效。
这里的配置包括
common中的配置,你可以对其进行复写。示例如下
android { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 \`sourceSet\` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义 + // + // 默认为 "main" + sourceSetName = "main" + + // 自定义生成的包名 + // + // Android 项目默认使用 \`android\` 配置方法块中的 \`namespace\` + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否使用 Kotlin 语言生成 + // + // 默认启用,启用后将生成 Kotlin 代码, + // 禁用后将生成 Java 代码 + // + // - 注意: 当此项目为纯 Java 项目时,此选项将被禁用 + useKotlin = true + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 \`internal\` 修饰符, + // 或为生成的 Java 类移除 \`public\` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true + + // 是否使用清单占位符的生成。 + // + // 默认禁用,启用后将同步属性的键值到 \`android\` 配置方法块中的 \`manifestPlaceholders\` + manifestPlaceholders = false +} +# JVM 项目配置
此配置块中的内容仅对纯 JVM 项目生效 (包括 Kotlin、Java 项目),如果是 Android 项目请参考 Android 项目配置 进行配置。
这里的配置包括
common中的配置,你可以对其进行复写。示例如下
jvm { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 \`sourceSet\` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义 + // + // 默认为 "main" + sourceSetName = "main" + + // 自定义生成的包名 + // + // Java、Kotlin 项目默认使用项目设置的 \`project.group\` + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否使用 Kotlin 语言生成 + // + // 默认启用,启用后将生成 Kotlin 代码, + // 禁用后将生成 Java 代码 + // + // - 注意: 当此项目为纯 Java 项目时,此选项将被禁用 + useKotlin = true + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 \`internal\` 修饰符, + // 或为生成的 Java 类移除 \`public\` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true +} +# Kotlin 多平台项目配置
此配置块中的内容仅对含有 Kotlin Multiplatform 插件的项目生效。
这里的配置包括
common中的配置,你可以对其进行复写。kmp { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 \`sourceSet\` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义。 + // + // 默认为 "commonMain" + sourceSetName = "commonMain" + + // 自定义生成的包名 + // + // Kotlin 多平台项目默认使用项目设置的 \`project.group\` + // + // 在 Kotlin 多平台项目中,如果同时应用了 AGP 插件, + // 仍将默认使用 \`namespace\` 作为包名 + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 \`internal\` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true +} +# 使用示例
下面是一个项目的
gradle.properties配置文件。示例如下
project.groupName=com.highcapable.gropifydemo +project.description=Hello Gropify Demo! +project.version=1.0.0 +在构建脚本
build.gradle.kts中,我们就可以如下所示这样直接去使用这些键值。这里以 Maven 发布的配置部分举例。
示例如下
publications { + create<MavenPublication>("maven") { + groupId = gropify.project.groupName + version = gropify.project.version + pom.description.set(gropify.project.description) + + from(components["java"]) + } +} +同样地,你也可以在当前项目中调用生成的键值。
Kotlin
val groupName = GropifyDemoProperties.PROJECT_GROUP_NAME +val description = GropifyDemoProperties.PROJECT_DESCRIPTION +val version = GropifyDemoProperties.PROJECT_VERSION +Java
var groupName = GropifyDemoProperties.PROJECT_GROUP_NAME; +var description = GropifyDemoProperties.PROJECT_DESCRIPTION; +var version = GropifyDemoProperties.PROJECT_VERSION; +下面再以 Android 项目举例。
在 Android 项目中通常需要配置很多重复、固定的属性,例如
targetSdk。示例如下
project.namespace=com.highcapable.gropifydemo +project.appName=Gropify Demo +project.compileSdk=36 +project.targetSdk=36 +project.minSdk=26 +当你设置了
useTypeAutoConversion = true时,Gropify在生成实体类过程在默认配置下将尝试将其转换为对应的类型。例如下方所使用的键值,其类型可被识别为字符串和整型,可被项目配置直接使用。
示例如下
android { + namespace = gropify.project.namespace + compileSdk = gropify.project.compileSdk + + defaultConfig { + minSdk = gropify.project.minSdk + targetSdk = gropify.project.targetSdk + } +} +当你设置了
manifestPlaceholders = true时,Gropify将自动将这些属性键值同步到android配置方法块中的manifestPlaceholders。此时你可以直接在
AndroidManifest.xml中使用这些占位符。示例如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application + android:label="\${project.appName}" + android:icon="@mipmap/ic_launcher"> + + ... + </application> +</manifest> +你可以无需再使用
buildConfigField向BuildConfig添加代码,有了Gropify生成的属性键值代码,你可以更加灵活地管理你的项目。你还可以在属性键值中使用插值
\${...}互相引用其中的内容,但不允许递归引用。当你设置了
useValueInterpolation = true时,Gropify将自动合并这些引用的内容到对应位置。示例如下
project.name=MyDemo +project.developer.name=myname +project.url=https://github.com/\${project.developer.name}/\${project.name} +如果你在
locations中添加了GropifyLocation.SystemEnv,你还可以直接引用系统环境变量。示例如下
# Linux 或 macOS 系统中使用 $USER 环境变量可以获取当前用户名 +project.developer.name=\${USER} +# 假设你有一个名为 SECRET_KEY 的系统环境变量 (请确保安全) +project.secretKey=\${SECRET_KEY} +注意
这个特性是
Gropify提供的,原生的gradle.properties并不支持此功能。插值内容通过
locations的层级自上而下进行查找替换,如果存在重复的键值名称,将使用最后查找到的内容进行替换。# 可能遇到的问题
如果你的项目仅存在一个根项目,且没有导入任何子项目,此时如果扩展方法不能正常生成, 你可以将你的根项目迁移至子项目并在
settings.gradle.kts中导入这个子项目,这样即可解决此问题。我们一般推荐将项目的功能进行分类,根项目仅用来管理插件和一些配置。
# 局限性说明
`,97),o=[p];function i(c,r){return n(),a("div",null,o)}const d=s(e,[["render",i],["__file","quick-start.html.vue"]]);export{d as default}; diff --git a/assets/quick-start.html-wQnE0x98.js b/assets/quick-start.html-wQnE0x98.js new file mode 100644 index 0000000..3758ec5 --- /dev/null +++ b/assets/quick-start.html-wQnE0x98.js @@ -0,0 +1 @@ +const l=JSON.parse('{"key":"v-24840ff0","path":"/zh-cn/guide/quick-start.html","title":"快速开始","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"部署插件","slug":"部署插件","link":"#部署插件","children":[]},{"level":2,"title":"功能配置","slug":"功能配置","link":"#功能配置","children":[{"level":3,"title":"通用配置","slug":"通用配置","link":"#通用配置","children":[]},{"level":3,"title":"构建脚本配置","slug":"构建脚本配置","link":"#构建脚本配置","children":[]},{"level":3,"title":"Android 项目配置","slug":"android-项目配置","link":"#android-项目配置","children":[]},{"level":3,"title":"JVM 项目配置","slug":"jvm-项目配置","link":"#jvm-项目配置","children":[]},{"level":3,"title":"Kotlin 多平台项目配置","slug":"kotlin-多平台项目配置","link":"#kotlin-多平台项目配置","children":[]}]},{"level":2,"title":"使用示例","slug":"使用示例","link":"#使用示例","children":[]},{"level":2,"title":"可能遇到的问题","slug":"可能遇到的问题","link":"#可能遇到的问题","children":[]},{"level":2,"title":"局限性说明","slug":"局限性说明","link":"#局限性说明","children":[]}],"git":{"updatedTime":1763223336000,"contributors":[{"name":"fankesyooni","email":"qzmmcn@163.com","commits":5}]},"filePathRelative":"zh-cn/guide/quick-start.md"}');export{l as data}; diff --git a/assets/style-ZvMm2Cad.css b/assets/style-ZvMm2Cad.css new file mode 100644 index 0000000..a42a1c1 --- /dev/null +++ b/assets/style-ZvMm2Cad.css @@ -0,0 +1 @@ +:root{--back-to-top-z-index: 5;--back-to-top-color: #3eaf7c;--back-to-top-color-hover: #71cda3}.back-to-top{cursor:pointer;position:fixed;bottom:2rem;right:2.5rem;width:2rem;height:1.2rem;background-color:var(--back-to-top-color);-webkit-mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;mask:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2049.484%2028.284'%3e%3cg%20transform='translate(-229%20-126.358)'%20fill='currentColor'%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-45%20296.902%20-200.874)'/%3e%3crect%20width='35'%20height='5'%20rx='2'%20transform='rotate(-135%20169.502%2020.377)'/%3e%3c/g%3e%3c/svg%3e") no-repeat;z-index:var(--back-to-top-z-index)}.back-to-top:hover{background-color:var(--back-to-top-color-hover)}@media (max-width: 959px){.back-to-top{display:none}}@media print{.back-to-top{display:none}}.back-to-top-enter-active,.back-to-top-leave-active{transition:opacity .3s}.back-to-top-enter-from,.back-to-top-leave-to{opacity:0}:root{--external-link-icon-color: #aaa}.external-link-icon{position:relative;display:inline-block;color:var(--external-link-icon-color);vertical-align:middle;top:-1px}@media print{.external-link-icon{display:none}}.external-link-icon-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--medium-zoom-z-index: 100;--medium-zoom-bg-color: #ffffff;--medium-zoom-opacity: 1}.medium-zoom-overlay{background-color:var(--medium-zoom-bg-color)!important;z-index:var(--medium-zoom-z-index)}.medium-zoom-overlay~img{z-index:calc(var(--medium-zoom-z-index) + 1)}.medium-zoom--opened .medium-zoom-overlay{opacity:var(--medium-zoom-opacity)}:root{--nprogress-color: #29d;--nprogress-z-index: 1031}#nprogress{pointer-events:none}#nprogress .bar{background:var(--nprogress-color);position:fixed;z-index:var(--nprogress-z-index);top:0;left:0;width:100%;height:2px}:root{--c-brand: #3eaf7c;--c-brand-light: #4abf8a;--c-bg: #ffffff;--c-bg-light: #f3f4f5;--c-bg-lighter: #eeeeee;--c-bg-dark: #ebebec;--c-bg-darker: #e6e6e6;--c-bg-navbar: var(--c-bg);--c-bg-sidebar: var(--c-bg);--c-bg-arrow: #cccccc;--c-text: #2c3e50;--c-text-accent: var(--c-brand);--c-text-light: #3a5169;--c-text-lighter: #4e6e8e;--c-text-lightest: #6a8bad;--c-text-quote: #999999;--c-border: #eaecef;--c-border-dark: #dfe2e5;--c-tip: #42b983;--c-tip-bg: var(--c-bg-light);--c-tip-title: var(--c-text);--c-tip-text: var(--c-text);--c-tip-text-accent: var(--c-text-accent);--c-warning: #ffc310;--c-warning-bg: #fffae3;--c-warning-bg-light: #fff3ba;--c-warning-bg-lighter: #fff0b0;--c-warning-border-dark: #f7dc91;--c-warning-details-bg: #fff5ca;--c-warning-title: #f1b300;--c-warning-text: #746000;--c-warning-text-accent: #edb100;--c-warning-text-light: #c1971c;--c-warning-text-quote: #ccab49;--c-danger: #f11e37;--c-danger-bg: #ffe0e0;--c-danger-bg-light: #ffcfde;--c-danger-bg-lighter: #ffc9c9;--c-danger-border-dark: #f1abab;--c-danger-details-bg: #ffd4d4;--c-danger-title: #ed1e2c;--c-danger-text: #660000;--c-danger-text-accent: #bd1a1a;--c-danger-text-light: #b5474d;--c-danger-text-quote: #c15b5b;--c-details-bg: #eeeeee;--c-badge-tip: var(--c-tip);--c-badge-warning: #ecc808;--c-badge-warning-text: var(--c-bg);--c-badge-danger: #dc2626;--c-badge-danger-text: var(--c-bg);--t-color: .3s ease;--t-transform: .3s ease;--code-bg-color: #282c34;--code-hl-bg-color: rgba(0, 0, 0, .66);--code-ln-color: #9e9e9e;--code-ln-wrapper-width: 3.5rem;--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-family-code: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;--navbar-height: 3.6rem;--navbar-padding-v: .7rem;--navbar-padding-h: 1.5rem;--sidebar-width: 20rem;--sidebar-width-mobile: calc(var(--sidebar-width) * .82);--content-width: 740px;--homepage-width: 960px}.back-to-top{--back-to-top-color: var(--c-brand);--back-to-top-color-hover: var(--c-brand-light)}.DocSearch{--docsearch-primary-color: var(--c-brand);--docsearch-text-color: var(--c-text);--docsearch-highlight-color: var(--c-brand);--docsearch-muted-color: var(--c-text-quote);--docsearch-container-background: rgba(9, 10, 17, .8);--docsearch-modal-background: var(--c-bg-light);--docsearch-searchbox-background: var(--c-bg-lighter);--docsearch-searchbox-focus-background: var(--c-bg);--docsearch-searchbox-shadow: inset 0 0 0 2px var(--c-brand);--docsearch-hit-color: var(--c-text-light);--docsearch-hit-active-color: var(--c-bg);--docsearch-hit-background: var(--c-bg);--docsearch-hit-shadow: 0 1px 3px 0 var(--c-border-dark);--docsearch-footer-background: var(--c-bg)}.external-link-icon{--external-link-icon-color: var(--c-text-quote)}.medium-zoom-overlay{--medium-zoom-bg-color: var(--c-bg)}#nprogress{--nprogress-color: var(--c-brand)}.pwa-popup{--pwa-popup-text-color: var(--c-text);--pwa-popup-bg-color: var(--c-bg);--pwa-popup-border-color: var(--c-brand);--pwa-popup-shadow: 0 4px 16px var(--c-brand);--pwa-popup-btn-text-color: var(--c-bg);--pwa-popup-btn-bg-color: var(--c-brand);--pwa-popup-btn-hover-bg-color: var(--c-brand-light)}.search-box{--search-bg-color: var(--c-bg);--search-accent-color: var(--c-brand);--search-text-color: var(--c-text);--search-border-color: var(--c-border);--search-item-text-color: var(--c-text-lighter);--search-item-focus-bg-color: var(--c-bg-light)}html.dark{--c-brand: #3aa675;--c-brand-light: #349469;--c-bg: #22272e;--c-bg-light: #2b313a;--c-bg-lighter: #262c34;--c-bg-dark: #343b44;--c-bg-darker: #37404c;--c-text: #adbac7;--c-text-light: #96a7b7;--c-text-lighter: #8b9eb0;--c-text-lightest: #8094a8;--c-border: #3e4c5a;--c-border-dark: #34404c;--c-tip: #318a62;--c-warning: #e0ad15;--c-warning-bg: #2d2f2d;--c-warning-bg-light: #423e2a;--c-warning-bg-lighter: #44442f;--c-warning-border-dark: #957c35;--c-warning-details-bg: #39392d;--c-warning-title: #fdca31;--c-warning-text: #d8d96d;--c-warning-text-accent: #ffbf00;--c-warning-text-light: #ddb84b;--c-warning-text-quote: #ccab49;--c-danger: #fc1e38;--c-danger-bg: #39232c;--c-danger-bg-light: #4b2b35;--c-danger-bg-lighter: #553040;--c-danger-border-dark: #a25151;--c-danger-details-bg: #482936;--c-danger-title: #fc2d3b;--c-danger-text: #ea9ca0;--c-danger-text-accent: #fd3636;--c-danger-text-light: #d9777c;--c-danger-text-quote: #d56b6b;--c-details-bg: #323843;--c-badge-warning: var(--c-warning);--c-badge-warning-text: #3c2e05;--c-badge-danger: var(--c-danger);--c-badge-danger-text: #401416;--code-hl-bg-color: #363b46}html.dark .DocSearch{--docsearch-logo-color: var(--c-text);--docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;--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-gradient: linear-gradient(-225deg, #444950, #1c1e21);--docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, .5), 0 -4px 8px 0 rgba(0, 0, 0, .2)}html,body{padding:0;margin:0;background-color:var(--c-bg);transition:background-color var(--t-color)}html.dark{color-scheme:dark}html{font-size:16px}body{font-family:var(--font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:1rem;color:var(--c-text)}a{font-weight:500;color:var(--c-text-accent);text-decoration:none;overflow-wrap:break-word}p a code{font-weight:400;color:var(--c-text-accent)}kbd{font-family:var(--font-family-code);color:var(--c-text);background:var(--c-bg-lighter);border:solid .15rem var(--c-border-dark);border-bottom:solid .25rem var(--c-border-dark);border-radius:.15rem;padding:0 .15em}code{font-family:var(--font-family-code);color:var(--c-text-lighter);padding:.25rem .5rem;margin:0;font-size:.85em;background-color:var(--c-bg-light);border-radius:3px;overflow-wrap:break-word;transition:background-color var(--t-color)}blockquote{font-size:1rem;color:var(--c-text-quote);border-left:.2rem solid var(--c-border-dark);margin:1rem 0;padding:.25rem 0 .25rem 1rem;overflow-wrap:break-word}blockquote>p{margin:0}ul,ol{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;overflow-wrap:break-word}h1:focus-visible,h2:focus-visible,h3:focus-visible,h4:focus-visible,h5:focus-visible,h6:focus-visible{outline:none}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color)}h3{font-size:1.35rem}h4{font-size:1.15rem}h5{font-size:1.05rem}h6{font-size:1rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media print{a.header-anchor{display:none}}a.header-anchor:hover{text-decoration:none}a.header-anchor:focus-visible{opacity:1}@media print{a[href^="http://"]:after,a[href^="https://"]:after{content:" (" attr(href) ") "}}p,ul,ol{line-height:1.7;overflow-wrap:break-word}hr{border:0;border-top:1px solid var(--c-border)}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto;transition:border-color var(--t-color)}tr{border-top:1px solid var(--c-border-dark);transition:border-color var(--t-color)}tr:nth-child(2n){background-color:var(--c-bg-light);transition:background-color var(--t-color)}tr:nth-child(2n) code{background-color:var(--c-bg-dark)}th,td{padding:.6em 1em;border:1px solid var(--c-border-dark);transition:border-color var(--t-color)}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:6px solid var(--c-bg-arrow)}.arrow.down{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid var(--c-bg-arrow)}.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:6px solid var(--c-bg-arrow)}.arrow.left{border-top:4px solid transparent;border-bottom:4px solid transparent;border-right:6px solid var(--c-bg-arrow)}.badge{display:inline-block;font-size:14px;font-weight:600;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:var(--c-bg);vertical-align:top;transition:color var(--t-color),background-color var(--t-color)}.badge.tip{background-color:var(--c-badge-tip)}.badge.warning{background-color:var(--c-badge-warning);color:var(--c-badge-warning-text)}.badge.danger{background-color:var(--c-badge-danger);color:var(--c-badge-danger-text)}.badge+.badge{margin-left:5px}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:var(--font-family-code);font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#ec5975}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.375;padding:1.3rem 1.5rem;margin:.85rem 0;border-radius:6px;overflow:auto}.theme-default-content pre code,.theme-default-content pre[class*=language-] code{color:#fff;padding:0;background-color:transparent!important;border-radius:0;overflow-wrap:unset;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.theme-default-content .line-number{font-family:var(--font-family-code)}div[class*=language-]{position:relative;background-color:var(--code-bg-color);border-radius:6px}div[class*=language-]:before{content:attr(data-ext);position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:var(--code-ln-color)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent!important;position:relative;z-index:1}div[class*=language-] .highlight-lines{-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.375}div[class*=language-] .highlight-lines .highlight-line{background-color:var(--code-hl-bg-color)}div[class*=language-]:not(.line-numbers-mode) .line-numbers{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlight-line:before{content:" ";position:absolute;z-index:2;left:0;top:0;display:block;width:var(--code-ln-wrapper-width);height:100%}div[class*=language-].line-numbers-mode pre{margin-left:var(--code-ln-wrapper-width);padding-left:1rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers{position:absolute;top:0;width:var(--code-ln-wrapper-width);text-align:center;color:var(--code-ln-color);padding-top:1.25rem;line-height:1.375;counter-reset:line-number}div[class*=language-].line-numbers-mode .line-numbers .line-number{position:relative;z-index:3;-webkit-user-select:none;-moz-user-select:none;user-select:none;height:1.375em}div[class*=language-].line-numbers-mode .line-numbers .line-number:before{counter-increment:line-number;content:counter(line-number);font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;top:0;left:0;width:var(--code-ln-wrapper-width);height:100%;border-radius:6px 0 0 6px;border-right:1px solid var(--code-hl-bg-color)}@media (max-width: 419px){.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.code-group__nav{margin-top:.85rem;margin-bottom:calc(-1.7rem - 6px);padding-bottom:calc(1.7rem - 6px);padding-left:10px;padding-top:10px;border-top-left-radius:6px;border-top-right-radius:6px;background-color:var(--code-bg-color)}.code-group__ul{margin:auto 0;padding-left:0;display:inline-flex;list-style:none}.code-group__nav-tab{border:0;padding:5px;cursor:pointer;background-color:transparent;font-size:.85em;line-height:1.4;color:#ffffffe6;font-weight:600}.code-group__nav-tab:focus{outline:none}.code-group__nav-tab:focus-visible{outline:1px solid rgba(255,255,255,.9)}.code-group__nav-tab-active{border-bottom:var(--c-brand) 1px solid}@media (max-width: 419px){.code-group__nav{margin-left:-1.5rem;margin-right:-1.5rem;border-radius:0}}.code-group-item{display:none}.code-group-item__active{display:block}.code-group-item>pre{background-color:orange}.custom-container{transition:color var(--t-color),border-color var(--t-color),background-color var(--t-color)}.custom-container .custom-container-title{font-weight:600}.custom-container .custom-container-title:not(:only-child){margin-bottom:-.4rem}.custom-container.tip,.custom-container.warning,.custom-container.danger{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-container.tip{border-color:var(--c-tip);background-color:var(--c-tip-bg);color:var(--c-tip-text)}.custom-container.tip .custom-container-title{color:var(--c-tip-title)}.custom-container.tip a{color:var(--c-tip-text-accent)}.custom-container.tip code{background-color:var(--c-bg-dark)}.custom-container.warning{border-color:var(--c-warning);background-color:var(--c-warning-bg);color:var(--c-warning-text)}.custom-container.warning .custom-container-title{color:var(--c-warning-title)}.custom-container.warning a{color:var(--c-warning-text-accent)}.custom-container.warning blockquote{border-left-color:var(--c-warning-border-dark);color:var(--c-warning-text-quote)}.custom-container.warning code{color:var(--c-warning-text-light);background-color:var(--c-warning-bg-light)}.custom-container.warning details{background-color:var(--c-warning-details-bg)}.custom-container.warning details code{background-color:var(--c-warning-bg-lighter)}.custom-container.warning .external-link-icon{--external-link-icon-color: var(--c-warning-text-quote)}.custom-container.danger{border-color:var(--c-danger);background-color:var(--c-danger-bg);color:var(--c-danger-text)}.custom-container.danger .custom-container-title{color:var(--c-danger-title)}.custom-container.danger a{color:var(--c-danger-text-accent)}.custom-container.danger blockquote{border-left-color:var(--c-danger-border-dark);color:var(--c-danger-text-quote)}.custom-container.danger code{color:var(--c-danger-text-light);background-color:var(--c-danger-bg-light)}.custom-container.danger details{background-color:var(--c-danger-details-bg)}.custom-container.danger details code{background-color:var(--c-danger-bg-lighter)}.custom-container.danger .external-link-icon{--external-link-icon-color: var(--c-danger-text-quote)}.custom-container.details{display:block;position:relative;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:var(--c-details-bg)}.custom-container.details code{background-color:var(--c-bg-darker)}.custom-container.details h4{margin-top:0}.custom-container.details figure:last-child,.custom-container.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-container.details summary{outline:none;cursor:pointer}.home{padding:var(--navbar-height) 2rem 0;max-width:var(--homepage-width);margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.8rem auto}.home .hero .actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:var(--c-text-lightest)}.home .hero .action-button{display:inline-block;font-size:1.2rem;padding:.8rem 1.6rem;border-width:2px;border-style:solid;border-radius:4px;transition:background-color var(--t-color);box-sizing:border-box}.home .hero .action-button.primary{color:var(--c-bg);background-color:var(--c-brand);border-color:var(--c-brand)}.home .hero .action-button.primary:hover{background-color:var(--c-brand-light)}.home .hero .action-button.secondary{color:var(--c-brand);background-color:var(--c-bg);border-color:var(--c-brand)}.home .hero .action-button.secondary:hover{color:var(--c-bg);background-color:var(--c-brand-light)}.home .features{border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:var(--c-text-light)}.home .feature p{color:var(--c-text-lighter)}.home .theme-default-content{padding:0;margin:0}.home .footer{padding:2.5rem;border-top:1px solid var(--c-border);text-align:center;color:var(--c-text-lighter);transition:border-color var(--t-color)}@media (max-width: 719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width: 419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero h1,.home .hero .description,.home .hero .actions{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.page{padding-top:var(--navbar-height);padding-left:var(--sidebar-width)}.navbar{position:fixed;z-index:20;top:0;left:0;right:0;height:var(--navbar-height);box-sizing:border-box;border-bottom:1px solid var(--c-border);background-color:var(--c-bg-navbar);transition:background-color var(--t-color),border-color var(--t-color)}.sidebar{font-size:16px;width:var(--sidebar-width);position:fixed;z-index:10;margin:0;top:var(--navbar-height);left:0;bottom:0;box-sizing:border-box;border-right:1px solid var(--c-border);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--c-brand) var(--c-border);background-color:var(--c-bg-sidebar);transition:transform var(--t-transform),background-color var(--t-color),border-color var(--t-color)}.sidebar::-webkit-scrollbar{width:7px}.sidebar::-webkit-scrollbar-track{background-color:var(--c-border)}.sidebar::-webkit-scrollbar-thumb{background-color:var(--c-brand)}.sidebar-mask{position:fixed;z-index:9;top:0;left:0;width:100vw;height:100vh;display:none}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1){transform:rotate(45deg) translate3d(5.5px,5.5px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(2){transform:scale3d(0,1,1)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform:rotate(-45deg) translate3d(6px,-6px,0)}.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(1),.theme-container.sidebar-open .navbar>.toggle-sidebar-button .icon span:nth-child(3){transform-origin:center}.theme-container.no-navbar .theme-default-content h1,.theme-container.no-navbar .theme-default-content h2,.theme-container.no-navbar .theme-default-content h3,.theme-container.no-navbar .theme-default-content h4,.theme-container.no-navbar .theme-default-content h5,.theme-container.no-navbar .theme-default-content h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .page{padding-top:0}.theme-container.no-navbar .sidebar{top:0}.theme-container.no-sidebar .sidebar{display:none}@media (max-width: 719px){.theme-container.no-sidebar .sidebar{display:block}}.theme-container.no-sidebar .page{padding-left:0}.theme-default-content a:hover{text-decoration:underline}.theme-default-content img{max-width:100%}.theme-default-content h1,.theme-default-content h2,.theme-default-content h3,.theme-default-content h4,.theme-default-content h5,.theme-default-content h6{margin-top:calc(.5rem - var(--navbar-height));padding-top:calc(1rem + var(--navbar-height));margin-bottom:0}.theme-default-content h1:first-child,.theme-default-content h2:first-child,.theme-default-content h3:first-child,.theme-default-content h4:first-child,.theme-default-content h5:first-child,.theme-default-content h6:first-child{margin-bottom:1rem}.theme-default-content h1:first-child+p,.theme-default-content h1:first-child+pre,.theme-default-content h1:first-child+.custom-container,.theme-default-content h2:first-child+p,.theme-default-content h2:first-child+pre,.theme-default-content h2:first-child+.custom-container,.theme-default-content h3:first-child+p,.theme-default-content h3:first-child+pre,.theme-default-content h3:first-child+.custom-container,.theme-default-content h4:first-child+p,.theme-default-content h4:first-child+pre,.theme-default-content h4:first-child+.custom-container,.theme-default-content h5:first-child+p,.theme-default-content h5:first-child+pre,.theme-default-content h5:first-child+.custom-container,.theme-default-content h6:first-child+p,.theme-default-content h6:first-child+pre,.theme-default-content h6:first-child+.custom-container{margin-top:2rem}@media (max-width: 959px){.sidebar{font-size:15px;width:var(--sidebar-width-mobile)}.page{padding-left:var(--sidebar-width-mobile)}}@media (max-width: 719px){.sidebar{top:0;padding-top:var(--navbar-height);transform:translate(-100%)}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translate(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width: 419px){h1{font-size:1.9rem}}.navbar{--navbar-line-height: calc( var(--navbar-height) - 2 * var(--navbar-padding-v) );padding:var(--navbar-padding-v) var(--navbar-padding-h);line-height:var(--navbar-line-height)}.navbar .logo{height:var(--navbar-line-height);margin-right:var(--navbar-padding-v);vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:var(--c-text);position:relative}.navbar .navbar-items-wrapper{display:flex;position:absolute;box-sizing:border-box;top:var(--navbar-padding-v);right:var(--navbar-padding-h);height:var(--navbar-line-height);padding-left:var(--navbar-padding-h);white-space:nowrap;font-size:.9rem}.navbar .navbar-items-wrapper .search-box{flex:0 0 auto;vertical-align:top}@media screen and (max-width: 719px){.navbar{padding-left:4rem}.navbar .site-name{display:block;width:calc(100vw - 11rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.navbar .can-hide{display:none}}.navbar-items{display:inline-block}@media print{.navbar-items{display:none}}.navbar-items a{display:inline-block;line-height:1.4rem;color:inherit}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text)}.navbar-items .navbar-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:var(--navbar-line-height)}.navbar-items .navbar-item:first-child{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:-2px;border-bottom:2px solid var(--c-text-accent)}@media (max-width: 719px){.navbar-items .navbar-item{margin-left:0}.navbar-items .navbar-item>a:hover,.navbar-items .navbar-item>a.router-link-active{margin-bottom:0;border-bottom:none}.navbar-items a:hover,.navbar-items a.router-link-active{color:var(--c-text-accent)}}.toggle-sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}.toggle-sidebar-button .icon{display:flex;flex-direction:column;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;cursor:inherit}.toggle-sidebar-button .icon span{display:inline-block;width:100%;height:2px;border-radius:2px;background-color:var(--c-text);transition:transform var(--t-transform)}.toggle-sidebar-button .icon span:nth-child(2){margin:6px 0}@media screen and (max-width: 719px){.toggle-sidebar-button{display:block}}.toggle-color-mode-button{display:flex;margin:auto;margin-left:1rem;border:0;background:none;color:var(--c-text);opacity:.8;cursor:pointer}@media print{.toggle-color-mode-button{display:none}}.toggle-color-mode-button:hover{opacity:1}.toggle-color-mode-button .icon{width:1.25rem;height:1.25rem}.DocSearch{transition:background-color var(--t-color)}.navbar-dropdown-wrapper{cursor:pointer}.navbar-dropdown-wrapper .navbar-dropdown-title,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:block;font-size:.9rem;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;font-weight:500;color:var(--c-text)}.navbar-dropdown-wrapper .navbar-dropdown-title:hover,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{border-color:transparent}.navbar-dropdown-wrapper .navbar-dropdown-title .arrow,.navbar-dropdown-wrapper .navbar-dropdown-title-mobile .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile{display:none;font-weight:600;font-size:inherit}.navbar-dropdown-wrapper .navbar-dropdown-title-mobile:hover{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item{color:inherit;line-height:1.7rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{margin:.45rem 0 0;border-top:1px solid var(--c-border);padding:1rem 0 .45rem;font-size:.9rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>span{padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a{font-weight:inherit}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle>a.router-link-active:after{display:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper{padding:0;list-style:none}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem-wrapper .navbar-dropdown-subitem{font-size:.9em}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a:hover,.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active{color:var(--c-text-accent)}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid var(--c-text-accent);border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item:first-child .navbar-dropdown-subtitle{margin-top:0;padding-top:0;border-top:0}.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile.open .navbar-dropdown-title-mobile{margin-bottom:.5rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title,.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:none}.navbar-dropdown-wrapper.mobile .navbar-dropdown-title-mobile{display:block}.navbar-dropdown-wrapper.mobile .navbar-dropdown{transition:height .1s ease-out;overflow:hidden}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle{border-top:0;margin-top:0;padding-top:0;padding-bottom:0}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subtitle,.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item>a{font-size:15px;line-height:2rem}.navbar-dropdown-wrapper.mobile .navbar-dropdown .navbar-dropdown-item .navbar-dropdown-subitem{font-size:14px;padding-left:1rem}.navbar-dropdown-wrapper:not(.mobile){height:1.8rem}.navbar-dropdown-wrapper:not(.mobile):hover .navbar-dropdown,.navbar-dropdown-wrapper:not(.mobile).open .navbar-dropdown{display:block!important}.navbar-dropdown-wrapper:not(.mobile).open:blur{display:none}.navbar-dropdown-wrapper:not(.mobile) .navbar-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:var(--c-bg-navbar);padding:.6rem 0;border:1px solid var(--c-border);border-bottom-color:var(--c-border-dark);text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}.page{padding-bottom:2rem;display:block}.page .theme-default-content{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem;padding-top:0}@media (max-width: 959px){.page .theme-default-content{padding:2rem}}@media (max-width: 419px){.page .theme-default-content{padding:1.5rem}}.page-meta{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem;overflow:auto}@media (max-width: 959px){.page-meta{padding:2rem}}@media (max-width: 419px){.page-meta{padding:1.5rem}}.page-meta .meta-item{cursor:default;margin-top:.8rem}.page-meta .meta-item .meta-item-label{font-weight:500;color:var(--c-text-lighter)}.page-meta .meta-item .meta-item-info{font-weight:400;color:var(--c-text-quote)}.page-meta .edit-link{display:inline-block;margin-right:.25rem}@media print{.page-meta .edit-link{display:none}}.page-meta .last-updated{float:right}@media (max-width: 719px){.page-meta .last-updated{font-size:.8em;float:none}.page-meta .contributors{font-size:.8em}}.page-nav{max-width:var(--content-width);margin:0 auto;padding:1rem 2.5rem 2rem;padding-bottom:0}@media (max-width: 959px){.page-nav{padding:2rem}}@media (max-width: 419px){.page-nav{padding:1.5rem}}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid var(--c-border);transition:border-color var(--t-color);padding-top:1rem;overflow:auto}.page-nav .prev a:before{content:"←"}.page-nav .next{float:right}.page-nav .next a:after{content:"→"}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .navbar-items{display:none;border-bottom:1px solid var(--c-border);transition:border-color var(--t-color);padding:.5rem 0 .75rem}.sidebar .navbar-items a{font-weight:600}.sidebar .navbar-items .navbar-item{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar .sidebar-items{padding:1.5rem 0}@media (max-width: 719px){.sidebar .navbar-items{display:block}.sidebar .navbar-items .navbar-dropdown-wrapper .navbar-dropdown .navbar-dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar .sidebar-items{padding:1rem 0}}.sidebar-item{cursor:default;border-left:.25rem solid transparent;color:var(--c-text)}.sidebar-item:focus-visible{outline-width:1px;outline-offset:-1px}.sidebar-item.active:not(p.sidebar-heading){font-weight:600;color:var(--c-text-accent);border-left-color:var(--c-text-accent)}.sidebar-item.sidebar-heading{transition:color .15s ease;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0}.sidebar-item.sidebar-heading+.sidebar-item-children{transition:height .1s ease-out;overflow:hidden;margin-bottom:.75rem}.sidebar-item.collapsible{cursor:pointer}.sidebar-item.collapsible .arrow{position:relative;top:-.12em;left:.5em}.sidebar-item:not(.sidebar-heading){font-size:1em;font-weight:400;display:inline-block;margin:0;padding:.35rem 1rem .35rem 2rem;line-height:1.4;width:100%;box-sizing:border-box}.sidebar-item:not(.sidebar-heading)+.sidebar-item-children{padding-left:1rem;font-size:.95em}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading){padding:.25rem 1rem .25rem 1.75rem}.sidebar-item-children .sidebar-item-children .sidebar-item:not(.sidebar-heading).active{font-weight:500;border-left-color:transparent}a.sidebar-heading+.sidebar-item-children .sidebar-item:not(.sidebar-heading).active{border-left-color:transparent}a.sidebar-item{cursor:pointer}a.sidebar-item:hover{color:var(--c-text-accent)}.table-of-contents .badge{vertical-align:middle}.dropdown-enter-from,.dropdown-leave-to{height:0!important}.fade-slide-y-enter-active{transition:all .2s ease}.fade-slide-y-leave-active{transition:all .2s cubic-bezier(1,.5,.8,1)}.fade-slide-y-enter-from,.fade-slide-y-leave-to{transform:translateY(10px);opacity:0}:root{--c-brand: rgb(98, 95, 124);--c-brand-light: rgb(145, 132, 151);--content-width: 965px}code{padding:3px 5px;border-radius:5px}.badge{margin-bottom:5px}.custom-container{border-radius:5px}.sidebar-item{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.language-text ::-webkit-scrollbar-track{background:#625f7c;border-radius:50px}.language-text ::-webkit-scrollbar-thumb:hover{background:#918497}.language-kotlin ::-webkit-scrollbar-track{background:#625f7c;border-radius:50px}.language-kotlin ::-webkit-scrollbar-thumb:hover{background:#918497}.language-java ::-webkit-scrollbar-track{background:#625f7c;border-radius:50px}.language-java ::-webkit-scrollbar-thumb:hover{background:#918497}.language-groovy ::-webkit-scrollbar-track{background:#625f7c;border-radius:50px}.language-groovy ::-webkit-scrollbar-thumb:hover{background:#918497}.language-xml ::-webkit-scrollbar-track{background:#625f7c;border-radius:50px}.language-xml ::-webkit-scrollbar-thumb:hover{background:#918497}.hidden-anchor-page h6{color:transparent;margin-bottom:-35px;padding-top:50px}.code-page h1{font-size:24pt}.code-page h2{font-size:18pt}.code-page h3{font-size:15pt}.code-page h4{font-size:12pt}.code-page h5{font-size:9.6pt}.code-page h6{font-size:8.4pt}.code-page .symbol{color:#8e9ba8}.code-page .deprecated{color:#8e9ba8;text-decoration:line-through}html{scroll-behavior:smooth}html ::-webkit-scrollbar{width:8px;height:6.5px}html ::-webkit-scrollbar-track{background:#eaecef}html ::-webkit-scrollbar-thumb{background:#bdbdbd;border-radius:50px}html ::-webkit-scrollbar-thumb:hover{background:#858585;border-radius:50px}html.dark{--c-brand: rgb(98, 95, 124);--c-brand-light: rgb(145, 132, 151);--content-width: 965px}html.dark ::-webkit-scrollbar{width:8px;height:6.5px}html.dark ::-webkit-scrollbar-track{background:#292e35}html.dark ::-webkit-scrollbar-thumb{background:#414853;border-radius:50px}html.dark ::-webkit-scrollbar-thumb:hover{background:#383e48;border-radius:50px}:root{--search-bg-color: #ffffff;--search-accent-color: #3eaf7c;--search-text-color: #2c3e50;--search-border-color: #eaecef;--search-item-text-color: #5d81a5;--search-item-focus-bg-color: #f3f4f5;--search-input-width: 8rem;--search-result-width: 20rem}.search-box{display:inline-block;position:relative;margin-left:1rem}@media print{.search-box{display:none}}.search-box input{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:text;width:var(--search-input-width);height:2rem;color:var(--search-text-color);display:inline-block;border:1px solid var(--search-border-color);border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all ease .3s;background:var(--search-bg-color) url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='13'%3e%3cg%20stroke-width='2'%20stroke='%23aaa'%20fill='none'%3e%3cpath%20d='M11.29%2011.71l-4-4'/%3e%3ccircle%20cx='5'%20cy='5'%20r='4'/%3e%3c/g%3e%3c/svg%3e") .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:var(--search-accent-color)}.search-box .suggestions{background:var(--search-bg-color);width:var(--search-result-width);position:absolute;top:2rem;right:0;border:1px solid var(--search-border-color);border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion.focus{background-color:var(--search-item-focus-bg-color)}.search-box .suggestion.focus a{color:var(--search-accent-color)}.search-box .suggestion a{white-space:normal;color:var(--search-item-text-color)}.search-box .suggestion .page-title{font-weight:600}.search-box .suggestion .page-header{font-size:.9em;margin-left:.25em}@media (max-width: 719px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (max-width: 419px){.search-box input:focus{width:8rem}.search-box .suggestions{width:calc(100vw - 4rem);right:-.5rem}} diff --git a/en/about/about.html b/en/about/about.html new file mode 100644 index 0000000..346b7b1 --- /dev/null +++ b/en/about/about.html @@ -0,0 +1,49 @@ + + + + + + + + +
Gropify无法生成settings.gradle.kts中的扩展方法,因为这属于Gropify的上游。About This Document | Gropify + + + + + ++ + + diff --git a/en/about/changelog.html b/en/about/changelog.html new file mode 100644 index 0000000..023fdab --- /dev/null +++ b/en/about/changelog.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
About This Document
This document is powered by VuePress.
License
Apache License Version 2.0 + +Copyright (C) 2019 HighCapable + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +Copyright © 2019 HighCapable
Changelog | Gropify + + + + + ++ + + diff --git a/en/about/contacts.html b/en/about/contacts.html new file mode 100644 index 0000000..1ad0154 --- /dev/null +++ b/en/about/contacts.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
Changelog
The version update history of
Gropifyis recorded here.Pay Attention
We will only maintain the latest API version. If you are using an outdated API version, you voluntarily renounce any possibility of maintenance.
Notice
To avoid translation time consumption, Changelog will use Google Translation from Chinese to English, please refer to the original text for actual reference.
Time zone of version release date: UTC+8
1.0.1 | 2025.11.16 latest
- Fixed the issue where
permanentKeyValueswas incorrectly configured toreplacementKeyValues- Optimized the automatic type conversion function for property key-values, fixed the problem of negative long integers being converted to integers
- Optimized log output function, added tags and text colors for each type of log
- Added
keyValueRulesto manually specify the type of property key-values, effective whenuseTypeAutoConversionis enabled- Enhanced debugging function, added detailed log output in debug mode
- Fixed the issue where
extensionNamewas judged as empty and illegal under default settings- Added judgment content for default extension method names that may cause conflicts
- Added
manifestPlaceholdersproperty key-value synchronization function toandroidconfiguration method block- Fixed the problem of Javapoet and Kotlinpoet processing special escape characters in source code generation
- Fixed other issues that may cause build script compilation failure
1.0.0 | 2025.11.11 stale
- The first version is submitted to Maven
Contact Us | Gropify + + + + + ++ + + diff --git a/en/about/future.html b/en/about/future.html new file mode 100644 index 0000000..43bec51 --- /dev/null +++ b/en/about/future.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
Contact Us
If you have any questions during usage, or have any constructive suggestions, you can contact us.
Join our developers group.
Find me on Twitter @fankesyooni.
Help with Maintenance
Thank you for choosing and using
Gropify.If you have code-related suggestions and requests, you can submit a Pull Request on GitHub.
Looking Toward the Future | Gropify + + + + + ++ + + diff --git a/en/guide/home.html b/en/guide/home.html new file mode 100644 index 0000000..28c7935 --- /dev/null +++ b/en/guide/home.html @@ -0,0 +1,44 @@ + + + + + + + + +Gropify
Looking Toward the Future
The future is bright and uncertain, let us look forward to the future development potential of
Gropify.Future Plans
Features that
Gropifymay add later are included here.Support More Project Types
Gropifycurrently supports generating properties into the source code of Kotlin, Java, and Android projects. In the future, it may support more projects that can participate in Gradle builds, such as C/C++ (Android JNI), Swift, etc., to meet the needs of more developers.Introduction | Gropify + + + + + ++ + + diff --git a/en/guide/quick-start.html b/en/guide/quick-start.html new file mode 100644 index 0000000..23790ad --- /dev/null +++ b/en/guide/quick-start.html @@ -0,0 +1,526 @@ + + + + + + + + +Gropify
Introduction
Gropifyis a type-safe and modern properties plugin for Gradle.Background
This plugin is designed for Gradle build scripts. It aims to bring properties similar to those in the
gradle.propertiesfile into build scripts in a type-safe way, avoiding problems that hard-coded strings might cause.The project icon was designed by MaiTungTM. The name comes from GradlePropify, meaning a plugin for Gradle properties.
It is a brand-new project rebuilt from SweetProperty, borrowing previous design ideas and making it more polished and easier to use.
The configuration plan format of
Gropifyis similar toSweetProperty. If you are usingSweetProperty, you can consider migrating toGropify.Usage
Gropifyis mainly designed for Kotlin DSL build scripts. Groovy can directly use properties from thegradle.propertiesfile as variables, but you can still useGropifyto achieve type-safe property access.
Gropifyalso supports generating properties (similar to those defined in agradle.propertiesfile) in a type-safe way into the source code of Kotlin, Java, and Android projects for use at application runtime—similar to Android'sBuildConfig'sbuildConfigFieldfeature.Suppose we have the following
gradle.propertiesfile.The following example
project.app.name=Gropify-Demo +project.app.version=1.0.0 +Here is an example of calling the code automatically generated by
Gropify.Build Script (Kotlin DSL, Groovy DSL)
val appName = gropify.project.app.name +val appVersion = gropify.project.app.version +def appName = gropify.project.app.name +def appVersion = gropify.project.app.version +Source Code (Kotlin, Java)
val appName = MyAppProperties.PROJECT_APP_NAME +val appVersion = MyAppProperties.PROJECT_APP_VERSION +var appName = MyAppProperties.PROJECT_APP_NAME; +var appVersion = MyAppProperties.PROJECT_APP_VERSION; +
Gropifyalso supports Kotlin Multiplatform projects, and you can use the generated property classes in thecommonMainsource set.Language Requirement
It's recommended to use Kotlin DSL to configure your project's build scripts. Groovy is also supported, but in pure Groovy projects some configuration syntax may have compatibility issues.
In Groovy DSL, we will no longer be responsible for troubleshooting and fixing any issues that arise from using this plugin, and it may be completely unsupported in future versions.
Contribution
The maintenance of this project is inseparable from the support and contributions of all developers.
This project is currently in its early stages, and there may still be some problems or lack of functions you need.
If possible, feel free to submit a PR to contribute features you think are needed to this project or go to GitHub Issues to make suggestions to us.
Quick Start | Gropify + + + + + ++ + + diff --git a/en/index.html b/en/index.html new file mode 100644 index 0000000..2c172a5 --- /dev/null +++ b/en/index.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
Quick Start
Integrate
Gropifyinto your project.Deploy Plugin
Gropifydependencies are published on Maven Central and our public repository. You can configure the repository as follows.We recommend using Gradle version
7.x.xor higher, and recommend using Kotlin DSL as the Gradle build script language. This documentation will no longer detail how to use it in Groovy DSL.We recommend using the new
pluginManagementmethod for deployment, which is a feature added since Gradle version7.x.x.If your project is still using
buildscriptfor management, we recommend migrating to the new method. Instructions for the old version will no longer be provided here.First, configure the plugin repository in your project's
settings.gradle.kts.The following example
pluginManagement { + repositories { + gradlePluginPortal() // Optional + google() // Optional + mavenCentral() // Required + // (Optional) You can add this URL to use our public repository + // This repository is added as an alternative when Sonatype-OSS fails to publish dependencies + // For details, please visit: https://github.com/HighCapable/maven-repository + maven("https://raw.githubusercontent.com/HighCapable/maven-repository/main/repository/releases") + } +} +Then add the
Gropifyplugin dependency inplugininsettings.gradle.kts. Please note do not addapply falseafter it.The following example
plugins { + id("com.highcapable.gropify") version "<version>" +} +Please replace
<version>with the version shown at the top of this section.After completing the above configuration, run Gradle sync once.
Gropifywill automatically search forgradle.propertiesfiles in the root project and each subproject, read the property key-values in them, and generate corresponding code for each project.Notice
Gropifycan only be applied tosettings.gradle.kts, configuring it once will take effect globally. Please do not apply it tobuild.gradle.kts, otherwise the functionality will be invalid.Feature Configuration
You can configure
Gropifyto implement customization and personalized features.
Gropifyprovides relatively rich customizable features. Below are the descriptions and configuration methods for these features.Please add the
gropifymethod block in yoursettings.gradle.ktsto start configuringGropify.To use in Groovy DSL, please change all variable
=to spaces, removeisbeforeEnabled.If you encounter a
Gradle DSL method not founderror, the solution is to migrate to Kotlin DSL.If you don't want to use Kotlin DSL entirely, you can also migrate only
settings.gradletosettings.gradle.kts.The following example
gropify { + // Enable Gropify, setting it to `false` will disable all features. + isEnabled = true + + // Whether to enable debug mode. + // + // You can help us identify the problem by enabling this option + // to print more debugging information in the logs. + // + // - Note: THIS IS ONLY FOR DEBUGGING! + // The debug log will contain your local environment, + // which may contain sensitive information. + // Please be sure to protect this information. + debugMode = false +} +
Gropify's configuration mode is divided into three types:globalglobal configuration, androotProject,projectsroot project and subproject configuration.You can continue to configure and integrate the configuration of the parent project in the child code blocks.
All configurations below are performed in the
gropifymethod block.The following example
// Global configuration. +// +// You can modify configurations in all projects in the global configuration. +// Configurations not declared in each project will use the global configuration. +// The functions in each configuration method block are exactly the same. +// +// You can refer to the configuration methods of root project and subprojects below. +global { + // Common configuration. + common { + // Configure "common". + } + + // Build script configuration. + buildscript { + // Configure "buildscript". + } + + // Android project configuration. + android { + // Configure "android". + } + + // JVM project configuration. + jvm { + // Configure "jvm". + } + + // Kotlin Multiplatform project configuration. + kmp { + // Configure "kmp". + } +} + +// Root project configuration. +// +// This is a special configuration method block that can only be used for the root project. +rootProject { + common { + // Configure "common". + } + buildscript { + // Configure "buildscript". + } + android { + // Configure "android". + } + jvm { + // Configure "jvm". + } + kmp { + // Configure "kmp". + } +} + +// Other projects and subprojects configuration. +// +// Fill in the full name of the project you need to configure in the +// method parameters to configure the corresponding project. +// +// If the current project is a subproject, you must include the ":" before +// the subproject name, such as ":app". +// +// If the current project is a nested subproject, such as app → sub, +// you need to use ":" to separate multiple subprojects, such as ":app:sub". +// +// The name of the root project cannot be used directly to configure subprojects, +// please use "rootProject". +// +// You can configure multiple projects and subprojects at the same time by filling +// in an array of full project names in the method parameters to +// configure each corresponding project. +projects(":app", ":modules:library1", ":modules:library2") { + common { + // Configure "common". + } + buildscript { + // Configure "buildscript". + } + android { + // Configure "android". + } + jvm { + // Configure "jvm". + } + kmp { + // Configure "kmp". + } +} +You can continue below to learn how to configure the features in each method block.
Common Configuration
Here you can configure related features for all configuration types at the same time. The configurations here will be applied down to Build Script Configuration, Android Project Configuration, JVM Project Configuration, Kotlin Multiplatform Project Configuration.
The following example
common { + // Enable feature. + // + // You can set [buildscript], [android], [jvm], [kmp] separately. + isEnabled = true + + // Whether to exclude the non-string type key-values content. + // + // Enabled by default, when enabled, key-values and content that are not + // string types will be excluded from properties' key-values. + excludeNonStringValue = true + + // Whether to use type auto conversion. + // + // Enabled by default, when enabled, the type in the properties' key-values will be + // automatically identified and converted to the corresponding type. + // + // After enabling, if you want to force the content of a key-values to be a string type, + // you can use single quotes or double quotes to wrap the entire string. + // + // - Note: After disabled this function, the functions mentioned above will also be invalid. + useTypeAutoConversion = true + + // Whether to use key-values content interpolation. + // + // Enabled by default, after enabling it will automatically identify + // the `${...}` content in the properties' key-values content and replace it. + // + // Note: The interpolated content will only be looked up from the + // current (current configuration file) properties' key-values list. + useValueInterpolation = true + + // Set exists property files. + // + // The property files will be automatically obtained from the root directory + // of the current root project, + // subproject and user directory according to the file name you set. + // + // By default, will add "gradle.properties" if [addDefault] is `true`. + // + // You can add multiple sets of property files name, they will be read in order. + // + // - Note: Generally there is no need to modify this setting, + // an incorrect file name will result in obtaining empty key-values content. + existsPropertyFiles( + "some-other-1.properties", + "some-other-2.properties", + addDefault = true + ) + + // Set a permanent list of properties' key-values. + // + // Here you can set some key-values that must exist, these key-values will be + // generated regardless of whether they can be obtained from the properties' key-values. + // + // These keys use the content of the properties' key if it exists, + // use the content set here if it does not exist. + // + // - Note: Special symbols and spaces cannot exist in properties' key names, + // otherwise the generation may fail. + permanentKeyValues( + "permanent.some.key1" to "some_value_1", + "permanent.some.key2" to "some_value_2" + ) + + // Set a replacement list of properties' key-values. + // + // Here you can set some key-values that need to be replaced, these key-values + // will be replaced the existing properties' key-values, if not exist, they will be ignored. + // + // The key-values set here will also overwrite the key-values set in [permanentKeyValues]. + replacementKeyValues( + "some.key1" to "new.value1", + "some.key2" to "new.value2" + ) + + // Set a key list of properties' key-values name that need to be excluded. + // + // Here you can set some key names that you want to exclude from + // known properties' key-values. + // + // These keys are excluded if they are present in the properties' key, + // will not appear in the generated code. + // + // - Note: If you exclude key-values set in [permanentKeyValues], then they will + // only change to the initial key-values content you set and continue to exist. + excludeKeys( + "exclude.some.key1", + "exclude.some.key2" + ) + + // Set a key list of properties' key-values name that need to be included. + // + // Here you can set some key value names that you want to include from + // known properties' key-values. + // + // These keys are included if the properties' key exists, + // unincluded keys will not appear in the generated code. + includeKeys( + "include.some.key1", + "include.some.key2" + ) + + // Set properties' key-values rules. + // + // You can set up a set of key-values rules, + // use [ValueRule] to create new rule for parsing the obtained key-values content. + // + // These key-values rules are applied when properties' keys exist. + keyValuesRules( + "some.key1" to ValueRule { if (it.contains("_")) it.replace("_", "-") else it }, + "some.key2" to ValueRule { "$it-value" }, + // You can also specify the expected type class, + // the type you specify will be used during generation, + // and an exception will be thrown if the type cannot be converted correctly. + // If the [useTypeAutoConversion] is not enabled, this parameter will be ignored. + "some.key3" to ValueRule(Int::class) + ) + + // Set where to find properties' key-values. + // + // Defaults are [GropifyLocation.CurrentProject], [GropifyLocation.RootProject]. + // + // You can set this up using the following types. + // + // - [GropifyLocation.CurrentProject] + // - [GropifyLocation.RootProject] + // - [GropifyLocation.Global] + // - [GropifyLocation.System] + // - [GropifyLocation.SystemEnv] + // + // We will generate properties' key-values in sequence from the locations you set, + // the order of the generation locations follows the order you set. + // + // - Risk warning: [GropifyLocation.Global], [GropifyLocation.System], + // [GropifyLocation.SystemEnv] may have keys and certificates, + // please manage the generated code carefully. + locations(GropifyLocation.CurrentProject, GropifyLocation.RootProject) +} +Tips
When referencing
GropifyLocation, the build script may generate the following at the top of the build script when used with IDE auto-import.import com.highcapable.gropify.plugin.config.type.GropifyLocation +
Gropifydoes alias processing for this, you can directly delete this import statement.Build Script Configuration
The code generated in the build script can be directly used by the current
build.gradle.kts,build.gradle.The configuration here includes the configuration in
common, and you can override it.The following example
buildscript { + // Custom buildscript extension name. + // + // Default is "gropify". + extensionName = "gropify" +} +Notice
Gradle also has a
buildscriptmethod block, please be careful to use the correct DSL level.Android Project Configuration
The content in this configuration block only takes effect for projects with AGP.
The configuration here includes the configuration in
common, and you can override it.The following example
android { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment `sourceSet` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "main". + sourceSetName = "main" + + // Custom generated package name. + // + // Android projects use the `namespace` in the `android` configuration method block + // by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to use Kotlin language generation. + // + // Enabled by default, when enabled will generate Kotlin code, + // disabled will generate Java code. + // + // - Note: This option will be disabled when this project is a pure Java project. + useKotlin = true + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the `internal` modifier to + // generated Kotlin classes or remove the `public` modifier to generated Java classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true + + // Whether to use manifest placeholders' generation. + // + // Disabled by default, when enabled will synchronize the properties' key-values + // to the `manifestPlaceholders` in the `android` configuration method block. + manifestPlaceholders = false +} +JVM Project Configuration
The content in this configuration block only takes effect for pure JVM projects (including Kotlin and Java projects). For Android projects, please refer to Android Project Configuration for configuration.
The configuration here includes the configuration in
common, and you can override it.The following example
jvm { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment `sourceSet` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "main". + sourceSetName = "main" + + // Custom generated package name. + // + // Java, Kotlin projects use the `project.group` of the project settings by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to use Kotlin language generation. + // + // Enabled by default, when enabled will generate Kotlin code, + // disabled will generate Java code. + // + // - Note: This option will be disabled when this project is a pure Java project. + useKotlin = true + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the `internal` modifier to + // generated Kotlin classes or remove the `public` modifier to generated Java classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true +} +Kotlin Multiplatform Project Configuration
The content in this configuration block only takes effect for projects with the Kotlin Multiplatform plugin.
The configuration here includes the configuration in
common, and you can override it.The following example
kmp { + // Custom generated directory path. + // + // You can fill in the path relative to the current project. + // + // Format example: "path/to/your/src/main", the "src/main" is a fixed suffix. + // + // Default is "build/generated/gropify/src/main". + // + // We recommend that you set the generated path under the "build" directory, + // which is ignored by version control systems by default. + generateDirPath = "build/generated/gropify" + + // Custom deployment `sourceSet` name. + // + // If your project source code deployment name is not default, you can customize it here. + // + // Default is "commonMain". + sourceSetName = "commonMain" + + // Custom generated package name. + // + // Kotlin Multiplatform projects use the `project.group` of the project settings + // by default. + // + // In a Kotlin Multiplatform project, if the AGP plugin is also applied, + // the `namespace` will still be used as the package name by default. + // + // The "generated" is a fixed suffix that avoids conflicts with your own namespaces, + // if you don't want this suffix, you can refer to [isIsolationEnabled]. + packageName = "com.example.mydemo" + + // Custom generated class name. + // + // Default is use the name of the current project. + // + // The "Properties" is a fixed suffix to distinguish it from your own class names. + className = "MyDemo" + + // Whether to enable restricted access. + // + // Disabled by default, when enabled will add the `internal` modifier to + // generated Kotlin classes. + isRestrictedAccessEnabled = false + + // Whether to enable code isolation. + // + // Enabled by default, when enabled will generate code in an + // isolated package suffix "generated" to avoid conflicts with other projects that + // also use or not only Gropify to generate code. + // + // - Note: If you disable this option, please make sure that there are no other projects + // that also use or not only Gropify to generate code to avoid conflicts. + isIsolationEnabled = true +} +Usage Examples
Below is a project's
gradle.propertiesconfiguration file.The following example
project.groupName=com.highcapable.gropifydemo +project.description=Hello Gropify Demo! +project.version=1.0.0 +In the build script
build.gradle.kts, we can directly use these key-values as shown below.Here is an example of the Maven publish configuration section.
The following example
publications { + create<MavenPublication>("maven") { + groupId = gropify.project.groupName + version = gropify.project.version + pom.description.set(gropify.project.description) + + from(components["java"]) + } +} +Similarly, you can also call the generated key-values in the current project.
Kotlin
val groupName = GropifyDemoProperties.PROJECT_GROUP_NAME +val description = GropifyDemoProperties.PROJECT_DESCRIPTION +val version = GropifyDemoProperties.PROJECT_VERSION +Java
var groupName = GropifyDemoProperties.PROJECT_GROUP_NAME; +var description = GropifyDemoProperties.PROJECT_DESCRIPTION; +var version = GropifyDemoProperties.PROJECT_VERSION; +Let's take another example with an Android project.
In Android projects, many repetitive and fixed properties usually need to be configured, such as
targetSdk.The following example
project.namespace=com.highcapable.gropifydemo +project.appName=Gropify Demo +project.compileSdk=36 +project.targetSdk=36 +project.minSdk=26 +When you set
useTypeAutoConversion = true,Gropifywill try to convert it to the corresponding type during the entity class generation process under the default configuration.For example, the key-values used below can be identified as string and integer types, which can be directly used by the project configuration.
The following example
android { + namespace = gropify.project.namespace + compileSdk = gropify.project.compileSdk + + defaultConfig { + minSdk = gropify.project.minSdk + targetSdk = gropify.project.targetSdk + } +} +When you set
manifestPlaceholders = true, Gropify will automatically synchronize these properties' key-values tomanifestPlaceholdersin the android configuration method block.You can then use these placeholders directly in
AndroidManifest.xml.The following example
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application + android:label="${project.appName}" + android:icon="@mipmap/ic_launcher"> + + ... + </application> +</manifest> +You no longer need to use
buildConfigFieldto add code toBuildConfig. With the property key-value code generated byGropify, you can manage your project more flexibly.You can also use interpolation
${...}in property key-values to reference each other's content, but recursive references are not allowed.When you set
useValueInterpolation = true,Gropifywill automatically merge these referenced contents to the corresponding positions.The following example
project.name=MyDemo +project.developer.name=myname +project.url=https://github.com/${project.developer.name}/${project.name} +If you add
GropifyLocation.SystemEnvtolocations, you can also directly reference system environment variables.The following example
# Use the $USER environment variable in Linux or macOS systems to get the current username. +project.developer.name=${USER} +# Assume you have a system environment variable called SECRET_KEY (PLEASE BE SURE TO BE SAFE). +project.secretKey=${SECRET_KEY} +Notice
This feature is provided by
Gropify. Nativegradle.propertiesdoes not support this feature.The interpolated content is searched and replaced from top to bottom through the
locationshierarchy. If there are duplicate key names, the last found content will be used for replacement.Possible Issues
If your project only has a root project and no subprojects are imported, and the extension method cannot be generated normally at this time, you can migrate your root project to a subproject and import this subproject in
settings.gradle.kts, which can solve this problem.We generally recommend categorizing the functions of the project, with the root project only used to manage plugins and some configurations.
Limitations
Gropifycannot generate extension methods insettings.gradle.ktsbecause it is upstream ofGropify.Home | Gropify + + + + + ++ + + diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..46f117a --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,16 @@ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..8c44e9a --- /dev/null +++ b/index.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify + + + + + ++ + + diff --git a/zh-cn/about/about.html b/zh-cn/about/about.html new file mode 100644 index 0000000..b57046e --- /dev/null +++ b/zh-cn/about/about.html @@ -0,0 +1,49 @@ + + + + + + + + +关于此文档 | Gropify + + + + + ++ + + diff --git a/zh-cn/about/changelog.html b/zh-cn/about/changelog.html new file mode 100644 index 0000000..df71d42 --- /dev/null +++ b/zh-cn/about/changelog.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
关于此文档
此文档由 VuePress 强力驱动。
许可证
Apache License Version 2.0 + +Copyright (C) 2019 HighCapable + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +版权所有 © 2019 HighCapable
更新日志 | Gropify + + + + + ++ + + diff --git a/zh-cn/about/contacts.html b/zh-cn/about/contacts.html new file mode 100644 index 0000000..8a2a76b --- /dev/null +++ b/zh-cn/about/contacts.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
更新日志
这里记录了
Gropify的版本更新历史。特别注意
我们只会对最新的 API 版本进行维护,若你正在使用过时的 API 版本则代表你自愿放弃一切维护的可能性。
1.0.1 | 2025.11.16 最新
- 修复
permanentKeyValues被错误地配置到replacementKeyValues的问题- 优化属性键值的类型自动转换功能,修复负数长整型被转换为整型的问题
- 优化日志输出功能,加入每种日志的标签和文字颜色
- 新增
keyValueRules可手动指定属性键值的类型,在启用了useTypeAutoConversion时生效- 增强调试功能,加入了调试模式下的详细日志输出
- 修复
extensionName在默认设置情况下被判断为空格式非法的问题- 增加了可能造成冲突的默认扩展方法名称判断内容
android配置方法块新增manifestPlaceholders属性键值同步功能- 修复源代码生成 Javapoet 和 Kotlinpoet 处理特殊转义字符的问题
- 修复其它可能导致构建脚本编译失败的问题
1.0.0 | 2025.11.11 过旧
- 首个版本提交至 Maven
联系我们 | Gropify + + + + + ++ + + diff --git a/zh-cn/about/future.html b/zh-cn/about/future.html new file mode 100644 index 0000000..c45f1aa --- /dev/null +++ b/zh-cn/about/future.html @@ -0,0 +1,34 @@ + + + + + + + + +展望未来 | Gropify + + + + + ++ + + diff --git a/zh-cn/guide/home.html b/zh-cn/guide/home.html new file mode 100644 index 0000000..1abf4e7 --- /dev/null +++ b/zh-cn/guide/home.html @@ -0,0 +1,44 @@ + + + + + + + + +Gropify
展望未来
未来是美好的,也是不确定的,让我们共同期待
Gropify在未来的发展空间。未来的计划
这里收录了
Gropify可能会在后期添加的功能。支持更多项目类型
Gropify目前支持将属性生成到 Kotlin、Java 和 Android 项目的源代码中,在未来可能会支持更多能够参与 Gradle 构建的项目,例如 C/C++ (Android JNI)、Swift 等,以满足更多开发者的需求。介绍 | Gropify + + + + + ++ + + diff --git a/zh-cn/guide/quick-start.html b/zh-cn/guide/quick-start.html new file mode 100644 index 0000000..771541d --- /dev/null +++ b/zh-cn/guide/quick-start.html @@ -0,0 +1,494 @@ + + + + + + + + +Gropify
介绍
Gropify是一个类型安全且现代化的 Gradle 属性插件。背景
这是一个为 Gradle 构建脚本设计的插件,旨在将类似
gradle.properties文件中的属性以类型安全的方式引入到构建脚本中,从而避免硬编码字符串可能带来的问题。项目图标由 MaiTungTM 设计,名称取自 GradlePropify,意为针对 Gradle 属性的插件。
它是基于 SweetProperty 重构的全新项目,借鉴了以往的设计方案,使得其在原有基础上更加完善和易用。
Gropify的配置方案与SweetProperty类似,如果你正在使用SweetProperty,你可以考虑将其迁移到Gropify。用途
Gropify主要针对 Kotlin DSL 构建脚本设计,Groovy 语言可以直接将gradle.properties文件中的属性作为变量使用,但是你也可以通过Gropify来实现类型安全的属性访问。
Gropify同时支持将类似gradle.properties文件中的属性以类型安全的方式生成到 Kotlin、Java、Android 项目的源码中以供应用程序运行时使用,功能类似 Android 的BuildConfig中的buildConfigField功能。假设我们有以下
gradle.properties文件。示例如下
project.app.name=Gropify-Demo +project.app.version=1.0.0 +这是
Gropify自动生成的代码调用示例。构建脚本 (Kotlin DSL、Groovy DSL)
val appName = gropify.project.app.name +val appVersion = gropify.project.app.version +def appName = gropify.project.app.name +def appVersion = gropify.project.app.version +源代码 (Kotlin、Java)
val appName = MyAppProperties.PROJECT_APP_NAME +val appVersion = MyAppProperties.PROJECT_APP_VERSION +var appName = MyAppProperties.PROJECT_APP_NAME; +var appVersion = MyAppProperties.PROJECT_APP_VERSION; +
Gropify同样支持 Kotlin Multiplatform 项目,你可以在commonMain源集中使用生成的属性类。语言要求
推荐使用 Kotlin DSL 来配置项目的构建脚本,Groovy 语言同样受支持,但在纯 Groovy 项目中部分配置语法可能存在兼容性问题。
在 Groovy DSL 中使用此插件发生的任何问题,我们都将不再负责排查和修复,并且在后期版本可能会完全不再支持 Groovy DSL。
功能贡献
本项目的维护离不开各位开发者的支持和贡献,目前这个项目处于初期阶段,可能依然存在一些问题或者缺少你需要的功能, 如果可能,欢迎提交 PR 为此项目贡献你认为需要的功能或前往 GitHub Issues 向我们提出建议。
快速开始 | Gropify + + + + + ++ + + diff --git a/zh-cn/index.html b/zh-cn/index.html new file mode 100644 index 0000000..f042833 --- /dev/null +++ b/zh-cn/index.html @@ -0,0 +1,34 @@ + + + + + + + + +Gropify
快速开始
集成
Gropify到你的项目中。部署插件
Gropify的依赖发布在 Maven Central 和我们的公共存储库中,你可以使用如下方式配置存储库。我们建议使用不低于
7.x.x版本的 Gradle,并推荐使用 Kotlin DSL 作为 Gradle 构建脚本语言,文档中将不再详细介绍在 Groovy DSL 中的使用方法。我们推荐使用
pluginManagement新方式进行部署,它是自 Gradle7.x.x版本开始添加的功能。如果你的项目依然在使用
buildscript的方式进行管理,推荐迁移到新方式,这里将不再提供旧版本的使用方式说明。首先,在你的项目
settings.gradle.kts中配置插件的存储库。示例如下
pluginManagement { + repositories { + gradlePluginPortal() // 可选 + google() // 可选 + mavenCentral() // 必须 + // (可选) 你可以添加此 URL 以使用我们的公共存储库 + // 当 Sonatype-OSS 发生故障无法发布依赖时,此存储库作为备选进行添加 + // 详情请前往:https://github.com/HighCapable/maven-repository + maven("https://raw.githubusercontent.com/HighCapable/maven-repository/main/repository/releases") + } +} +然后在
settings.gradle.kts中plugin添加Gropify插件依赖,请注意不要在后方加入apply false。示例如下
plugins { + id("com.highcapable.gropify") version "<version>" +} +请将
<version>修改为此小结顶部显示的版本。上述配置完成后,运行一次 Gradle Sync。
Gropify将会自动搜索根项目和每个子项目中的gradle.properties文件,并读取其中的属性键值,为每个项目生成对应的代码。注意
Gropify只能被应用到settings.gradle.kts中,配置一次即可全局生效,请勿将其应用到build.gradle.kts中,否则功能将会无效。功能配置
你可以对
Gropify进行配置来实现自定义和个性化功能。
Gropify为你提供了相对丰富的可自定义功能,下面是这些功能的说明与配置方法。请在你的
settings.gradle.kts中添加gropify方法块以开始配置Gropify。如需在 Groovy DSL 中使用,请将所有变量的
=改为空格,并删除Enabled前方的is即可。如果你遇到了
Gradle DSL method not found错误,解决方案为迁移到 Kotlin DSL。如果你不想全部使用 Kotlin DSL,你也可以仅将
settings.gradle迁移到settings.gradle.kts。示例如下
gropify { + // 启用 Gropify,设置为 `false` 将禁用所有功能 + isEnabled = true + + // 是否启用调试模式 + // + // 你可以通过启用此选项在日志中打印更多调试信息帮助我们定位问题 + // + // - 注意: 此功能仅用于调试! + // 调试日志将包含你的本地环境,其中可能包含敏感信息,请务必保护好这些信息 + debugMode = false +} +
Gropify的配置模式分为global全局配置和rootProject、projects根项目和子项目配置三种。你可以在子项的代码块中继续配置和集成顶层项目的配置。
以下配置均在
gropify方法块中进行。示例如下
// 全局配置 +// +// 你可以在全局配置中修改所有项目中的配置 +// 每个项目中未进行声明的配置将使用全局配置 +// 每个配置方法块中的功能完全一致 +// +// 你可以参考下方根项目、子项目的配置方法 +global { + // 通用配置 + common { + // 配置 "common" + } + + // 构建脚本配置 + buildscript { + // 配置 "buildscript" + } + + // Android 项目配置 + android { + // 配置 "android" + } + + // JVM 项目配置 + jvm { + // 配置 "jvm" + } + + // Kotlin 多平台项目配置 + kmp { + // 配置 "kmp" + } +} + +// 根项目 (Root Project) 配置 +// +// 这是一个特殊的配置方法块,只能用于根项目 +rootProject { + common { + // 配置 "common" + } + buildscript { + // 配置 "buildscript" + } + android { + // 配置 "android" + } + jvm { + // 配置 "jvm" + } + kmp { + // 配置 "kmp" + } +} + +// 其它项目与子项目配置 +// +// 在方法参数中填入需要配置的项目完整名称来配置对应的项目 +// +// 如果当前项目是子项目,你必须填写子项目前面的 ":",例如 ":app" +// +// 如果当前项目为嵌套型子项目,例如 app → sub +// 此时你需要使用 ":" 来分隔多个子项目,例如 ":app:sub" +// +// 根项目的名称不能直接用来配置子项目,请使用 "rootProject" +// 你可以同时进行多个项目与子项目配置,在方法参数中填入需要配置的项目完整名称数组来配置每个对应的项目 +projects(":app", ":modules:library1", ":modules:library2") { + common { + // 配置 "common" + } + buildscript { + // 配置 "buildscript" + } + android { + // 配置 "android" + } + jvm { + // 配置 "jvm" + } + kmp { + // 配置 "kmp" + } +} +你可以继续在下方了解如何配置每个方法块中的功能。
通用配置
在这里你可以同时配置所有配置类型的相关功能,这里的配置会向下应用到 构建脚本配置、Android 项目配置、JVM 项目配置、Kotlin 多平台项目配置 中。
示例如下
common { + // 启用功能 + // + // 你可以分别对 [buildscript]、[android]、[jvm]、[kmp] 进行设置 + isEnabled = true + + // 是否排除非字符串类型的键值内容 + // + // 默认启用,启用后将排除非字符串类型的键值和内容 + excludeNonStringValue = true + + // 是否使用类型自动转换 + // + // 默认启用,启用后将自动识别属性键值中的类型并转换为对应类型 + // + // 启用后,如果你想强制将键值内容设为字符串类型, + // 可以使用单引号或双引号包裹整个字符串 + // + // - 注意: 禁用此功能后,上述功能也将失效 + useTypeAutoConversion = true + + // 是否使用键值内容插值 + // + // 默认启用,启用后将自动识别属性键值内容中的 `${...}` 并进行替换 + // + // 注意: 插值内容仅会从当前 (当前配置文件) 属性键值列表中查找 + useValueInterpolation = true + + // 设置已存在的属性文件 + // + // 属性文件将根据你设置的文件名自动从当前根项目、 + // 子项目和用户目录的根目录获取 + // + // 默认情况下,如果 [addDefault] 为 `true`,将添加 "gradle.properties" + // + // 你可以添加多组属性文件名,它们将按顺序读取 + // + // - 注意: 通常无需修改此设置,错误的文件名将导致获取空键值内容 + existsPropertyFiles( + "some-other-1.properties", + "some-other-2.properties", + addDefault = true + ) + + // 设置永久属性键值列表 + // + // 在这里你可以设置一些必须存在的键值,无论是否能从属性键值中获取, + // 这些键值都将被生成 + // + // 这些键如果存在于属性键中则使用属性键的内容, + // 如果不存在则使用这里设置的内容 + // + // - 注意: 属性键名称中不能存在特殊符号和空格,否则可能导致生成失败 + permanentKeyValues( + "permanent.some.key1" to "some_value_1", + "permanent.some.key2" to "some_value_2" + ) + + // 设置替换属性键值列表 + // + // 在这里你可以设置一些需要替换的键值,这些键值 + // 将替换现有的属性键值,如果不存在则忽略 + // + // 这里设置的键值也会覆盖 [permanentKeyValues] 中设置的键值 + replacementKeyValues( + "some.key1" to "new.value1", + "some.key2" to "new.value2" + ) + + // 设置需要排除的属性键值名称列表 + // + // 在这里你可以设置一些要从已知属性键值中排除的键名称 + // + // 如果这些键存在于属性键中则排除它们, + // 不会出现在生成的代码中 + // + // - 注意: 如果你排除了 [permanentKeyValues] 中设置的键值,那么它们将 + // 仅更改为你设置的初始键值内容并继续存在 + excludeKeys( + "exclude.some.key1", + "exclude.some.key2" + ) + + // 设置需要包含的属性键值名称列表 + // + // 在这里你可以设置一些要从已知属性键值中包含的键名称 + // + // 如果属性键存在则包含这些键,未包含的键不会出现在生成的代码中 + includeKeys( + "include.some.key1", + "include.some.key2" + ) + + // 设置属性键值规则 + // + // 你可以设置一组键值规则, + // 使用 [ValueRule] 创建新规则来解析获取的键值内容 + // + // 当属性键存在时应用这些键值规则 + keyValuesRules( + "some.key1" to ValueRule { if (it.contains("_")) it.replace("_", "-") else it }, + "some.key2" to ValueRule { "$it-value" }, + // 你还可以指定期望的类型类,生成时将使用你指定的类型, + // 如果类型无法正确转换,将抛出异常 + // 如果未启用 [useTypeAutoConversion],此参数将被忽略 + "some.key3" to ValueRule(Int::class) + ) + + // 设置查找属性键值的位置 + // + // 默认为 [GropifyLocation.CurrentProject]、[GropifyLocation.RootProject] + // + // 你可以使用以下类型进行设置 + // + // - [GropifyLocation.CurrentProject] + // - [GropifyLocation.RootProject] + // - [GropifyLocation.Global] + // - [GropifyLocation.System] + // - [GropifyLocation.SystemEnv] + // + // 我们将按顺序从你设置的位置生成属性键值,生成位置的顺序遵循你设置的顺序 + // + // - 风险警告: [GropifyLocation.Global]、[GropifyLocation.System]、 + // [GropifyLocation.SystemEnv] 可能包含密钥和证书,请谨慎管理生成的代码 + locations(GropifyLocation.CurrentProject, GropifyLocation.RootProject) +} +小提示
在引用
GropifyLocation时,构建脚本在配合 IDE 自动导入时可能会在构建脚本顶部生成以下内容。import com.highcapable.gropify.plugin.config.type.GropifyLocation +
Gropify对此做了 alias 处理,你可以直接删除此 import 语句。构建脚本配置
在构建脚本中生成的代码可直接被当前
build.gradle.kts、build.gradle使用。这里的配置包括
common中的配置,你可以对其进行复写。示例如下
buildscript { + // 自定义构建脚本扩展名称 + // + // 默认为 "gropify" + extensionName = "gropify" +} +注意
Gradle 中也有一个
buildscript方法块,请注意使用正确的 DSL 层级。Android 项目配置
此配置块中的内容仅对存在 AGP 的项目生效。
这里的配置包括
common中的配置,你可以对其进行复写。示例如下
android { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 `sourceSet` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义 + // + // 默认为 "main" + sourceSetName = "main" + + // 自定义生成的包名 + // + // Android 项目默认使用 `android` 配置方法块中的 `namespace` + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否使用 Kotlin 语言生成 + // + // 默认启用,启用后将生成 Kotlin 代码, + // 禁用后将生成 Java 代码 + // + // - 注意: 当此项目为纯 Java 项目时,此选项将被禁用 + useKotlin = true + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 `internal` 修饰符, + // 或为生成的 Java 类移除 `public` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true + + // 是否使用清单占位符的生成。 + // + // 默认禁用,启用后将同步属性的键值到 `android` 配置方法块中的 `manifestPlaceholders` + manifestPlaceholders = false +} +JVM 项目配置
此配置块中的内容仅对纯 JVM 项目生效 (包括 Kotlin、Java 项目),如果是 Android 项目请参考 Android 项目配置 进行配置。
这里的配置包括
common中的配置,你可以对其进行复写。示例如下
jvm { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 `sourceSet` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义 + // + // 默认为 "main" + sourceSetName = "main" + + // 自定义生成的包名 + // + // Java、Kotlin 项目默认使用项目设置的 `project.group` + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否使用 Kotlin 语言生成 + // + // 默认启用,启用后将生成 Kotlin 代码, + // 禁用后将生成 Java 代码 + // + // - 注意: 当此项目为纯 Java 项目时,此选项将被禁用 + useKotlin = true + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 `internal` 修饰符, + // 或为生成的 Java 类移除 `public` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true +} +Kotlin 多平台项目配置
此配置块中的内容仅对含有 Kotlin Multiplatform 插件的项目生效。
这里的配置包括
common中的配置,你可以对其进行复写。kmp { + // 自定义生成的目录路径 + // + // 你可以填写相对于当前项目的路径 + // + // 格式示例: "path/to/your/src/main","src/main" 是固定后缀 + // + // 默认为 "build/generated/gropify/src/main" + // + // 我们建议你将生成路径设置在 "build" 目录下,该目录默认被版本控制系统忽略 + generateDirPath = "build/generated/gropify" + + // 自定义部署 `sourceSet` 名称 + // + // 如果你的项目源代码部署名称不是默认的,可以在此处自定义。 + // + // 默认为 "commonMain" + sourceSetName = "commonMain" + + // 自定义生成的包名 + // + // Kotlin 多平台项目默认使用项目设置的 `project.group` + // + // 在 Kotlin 多平台项目中,如果同时应用了 AGP 插件, + // 仍将默认使用 `namespace` 作为包名 + // + // "generated" 是固定后缀,用于避免与你自己的命名空间冲突, + // 如果你不想要此后缀,可以参考 [isIsolationEnabled] + packageName = "com.example.mydemo" + + // 自定义生成的类名 + // + // 默认使用当前项目的名称 + // + // "Properties" 是固定后缀,用于与你自己的类名区分 + className = "MyDemo" + + // 是否启用受限访问 + // + // 默认禁用,启用后将为生成的 Kotlin 类添加 `internal` 修饰符 + isRestrictedAccessEnabled = false + + // 是否启用代码隔离 + // + // 默认启用,启用后将在隔离的包后缀 "generated" 中生成代码, + // 以避免与其他同样使用或不仅使用 Gropify 生成代码的项目冲突 + // + // - 注意: 如果你禁用此选项,请确保没有其他同样使用或不仅使用 + // Gropify 生成代码的项目,以避免冲突 + isIsolationEnabled = true +} +使用示例
下面是一个项目的
gradle.properties配置文件。示例如下
project.groupName=com.highcapable.gropifydemo +project.description=Hello Gropify Demo! +project.version=1.0.0 +在构建脚本
build.gradle.kts中,我们就可以如下所示这样直接去使用这些键值。这里以 Maven 发布的配置部分举例。
示例如下
publications { + create<MavenPublication>("maven") { + groupId = gropify.project.groupName + version = gropify.project.version + pom.description.set(gropify.project.description) + + from(components["java"]) + } +} +同样地,你也可以在当前项目中调用生成的键值。
Kotlin
val groupName = GropifyDemoProperties.PROJECT_GROUP_NAME +val description = GropifyDemoProperties.PROJECT_DESCRIPTION +val version = GropifyDemoProperties.PROJECT_VERSION +Java
var groupName = GropifyDemoProperties.PROJECT_GROUP_NAME; +var description = GropifyDemoProperties.PROJECT_DESCRIPTION; +var version = GropifyDemoProperties.PROJECT_VERSION; +下面再以 Android 项目举例。
在 Android 项目中通常需要配置很多重复、固定的属性,例如
targetSdk。示例如下
project.namespace=com.highcapable.gropifydemo +project.appName=Gropify Demo +project.compileSdk=36 +project.targetSdk=36 +project.minSdk=26 +当你设置了
useTypeAutoConversion = true时,Gropify在生成实体类过程在默认配置下将尝试将其转换为对应的类型。例如下方所使用的键值,其类型可被识别为字符串和整型,可被项目配置直接使用。
示例如下
android { + namespace = gropify.project.namespace + compileSdk = gropify.project.compileSdk + + defaultConfig { + minSdk = gropify.project.minSdk + targetSdk = gropify.project.targetSdk + } +} +当你设置了
manifestPlaceholders = true时,Gropify将自动将这些属性键值同步到android配置方法块中的manifestPlaceholders。此时你可以直接在
AndroidManifest.xml中使用这些占位符。示例如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application + android:label="${project.appName}" + android:icon="@mipmap/ic_launcher"> + + ... + </application> +</manifest> +你可以无需再使用
buildConfigField向BuildConfig添加代码,有了Gropify生成的属性键值代码,你可以更加灵活地管理你的项目。你还可以在属性键值中使用插值
${...}互相引用其中的内容,但不允许递归引用。当你设置了
useValueInterpolation = true时,Gropify将自动合并这些引用的内容到对应位置。示例如下
project.name=MyDemo +project.developer.name=myname +project.url=https://github.com/${project.developer.name}/${project.name} +如果你在
locations中添加了GropifyLocation.SystemEnv,你还可以直接引用系统环境变量。示例如下
# Linux 或 macOS 系统中使用 $USER 环境变量可以获取当前用户名 +project.developer.name=${USER} +# 假设你有一个名为 SECRET_KEY 的系统环境变量 (请确保安全) +project.secretKey=${SECRET_KEY} +注意
这个特性是
Gropify提供的,原生的gradle.properties并不支持此功能。插值内容通过
locations的层级自上而下进行查找替换,如果存在重复的键值名称,将使用最后查找到的内容进行替换。可能遇到的问题
如果你的项目仅存在一个根项目,且没有导入任何子项目,此时如果扩展方法不能正常生成, 你可以将你的根项目迁移至子项目并在
settings.gradle.kts中导入这个子项目,这样即可解决此问题。我们一般推荐将项目的功能进行分类,根项目仅用来管理插件和一些配置。
局限性说明
Gropify无法生成settings.gradle.kts中的扩展方法,因为这属于Gropify的上游。首页 | Gropify + + + + + ++ + +