diff --git a/.nojekyll b/.nojekyll
new file mode 100644
index 00000000..e69de29b
diff --git a/404.html b/404.html
new file mode 100644
index 00000000..ab8f5943
--- /dev/null
+++ b/404.html
@@ -0,0 +1,40 @@
+
+
+
+ {h.value=[...h.value.slice(0,e),...h.value.slice(e+1)]}}})(),{enabled:R,resultHistory:Q,addResultHistory:_,removeResultHistory:b}=(()=>{const e=(0,i.tv)(),l=p>0,t=l=>e.resolve({name:l.key,..."anchor"in l?{hash:`#${l.anchor}`}:{}}).fullPath;return{enabled:l,resultHistory:y,addResultHistory:e=>{if(l){const l={link:t(e),display:e.display};"header"in e&&(l.header=e.header),y.value.length{y.value=[...y.value.slice(0,e),...y.value.slice(e+1)]}}})(),w=H||R,x=(0,r.Vh)(e,"query"),{results:C,searching:q}=(e=>{const l=(0,v.u)(),t=(0,n.I)(),{search:s,terminate:i}=(0,v.c)(),o=(0,r.iH)(!1),c=(0,r.XI)([]);return(0,u.bv)((()=>{const r=()=>{c.value=[],o.value=!1},n=(0,a.DI)((e=>{o.value=!0,e?s({type:"search",query:e,locale:t.value,options:l}).then((e=>{c.value=e,o.value=!1})).catch((e=>{console.error(e),r()})):r()}),v.s.searchDelay);(0,u.YP)([e,t],(()=>n(e.value)),{immediate:!0}),(0,u.Ah)((()=>{i()}))})),{searching:o,results:c}})(x),S=(0,r.qj)({isQuery:!0,index:0}),A=(0,r.iH)(0),P=(0,r.iH)(0),D=(0,u.Fl)((()=>w&&(g.value.length>0||Q.value.length>0))),T=(0,u.Fl)((()=>C.value.length>0)),I=(0,u.Fl)((()=>C.value[A.value]||null)),E=e=>t.resolve({name:e.key,..."anchor"in e?{hash:`#${e.anchor}`}:{}}).fullPath,F=e=>e.map((e=>(0,o.HD)(e)?e:(0,u.h)(e[0],e[1]))),O=e=>{if("customField"===e.type){const l=v.b[e.index]||"$content",[t,s=""]=(0,o.PO)(l)?l[d.value].split("$content"):l.split("$content");return e.display.map((e=>(0,u.h)("div",F([t,...e,s]))))}return e.display.map((e=>(0,u.h)("div",F(e))))},Y=()=>{A.value=0,P.value=0,l("updateQuery",""),l("close")};return(0,s.ORN)("keydown",(s=>{if(e.isFocusing)if(T.value){if("ArrowUp"===s.key)P.value>0?P.value=P.value-1:(A.value=A.value>0?A.value-1:C.value.length-1,P.value=I.value.contents.length-1);else if("ArrowDown"===s.key)P.value{const{isQuery:e,index:l}=S;0===l?(S.isQuery=!e,S.index=e?Q.value.length-1:g.value.length-1):S.index=l-1})();else if("ArrowDown"===s.key)(()=>{const{isQuery:e,index:l}=S;l===(e?g.value.length-1:Q.value.length-1)?(S.isQuery=!e,S.index=0):S.index=l+1})();else if("Enter"===s.key){const{index:e}=S;S.isQuery?(l("updateQuery",g.value[e]),s.preventDefault()):(t.push(Q.value[e].link),Y())}})),(0,u.YP)([A,P],(()=>{document.querySelector(".search-pro-result-list-item.active .search-pro-result-item.active")?.scrollIntoView(!1)}),{flush:"post"}),()=>(0,u.h)("div",{class:["search-pro-result-wrapper",{empty:x.value?!T.value:!D.value}],id:"search-pro-results"},""===x.value?w?D.value?[H?(0,u.h)("ul",{class:"search-pro-result-list"},(0,u.h)("li",{class:"search-pro-result-list-item"},[(0,u.h)("div",{class:"search-pro-result-title"},m.value.queryHistory),g.value.map(((e,t)=>(0,u.h)("div",{class:["search-pro-result-item",{active:S.isQuery&&S.index===t}],onClick:()=>{l("updateQuery",e)}},[(0,u.h)(c.H,{class:"search-pro-result-type"}),(0,u.h)("div",{class:"search-pro-result-content"},e),(0,u.h)("button",{class:"search-pro-remove-icon",innerHTML:c.C,onClick:e=>{e.preventDefault(),e.stopPropagation(),k(t)}})])))])):null,R?(0,u.h)("ul",{class:"search-pro-result-list"},(0,u.h)("li",{class:"search-pro-result-list-item"},[(0,u.h)("div",{class:"search-pro-result-title"},m.value.resultHistory),Q.value.map(((e,l)=>(0,u.h)(o.RG,{to:e.link,class:["search-pro-result-item",{active:!S.isQuery&&S.index===l}],onClick:()=>{Y()}},(()=>[(0,u.h)(c.H,{class:"search-pro-result-type"}),(0,u.h)("div",{class:"search-pro-result-content"},[e.header?(0,u.h)("div",{class:"content-header"},e.header):null,(0,u.h)("div",e.display.map((e=>F(e))).flat())]),(0,u.h)("button",{class:"search-pro-remove-icon",innerHTML:c.C,onClick:e=>{e.preventDefault(),e.stopPropagation(),b(l)}})]))))])):null]:m.value.emptyHistory:m.value.emptyResult:q.value?(0,u.h)(c.S,{hint:m.value.searching}):T.value?(0,u.h)("ul",{class:"search-pro-result-list"},C.value.map((({title:l,contents:t},s)=>{const a=A.value===s;return(0,u.h)("li",{class:["search-pro-result-list-item",{active:a}]},[(0,u.h)("div",{class:"search-pro-result-title"},l||m.value.defaultTitle),t.map(((l,t)=>{const s=a&&P.value===t;return(0,u.h)(o.RG,{to:E(l),class:["search-pro-result-item",{active:s,"aria-selected":s}],onClick:()=>{f(e.query),_(l),Y()}},(()=>["text"===l.type?null:(0,u.h)("title"===l.type?c.T:"heading"===l.type?c.a:c.b,{class:"search-pro-result-type"}),(0,u.h)("div",{class:"search-pro-result-content"},["text"===l.type&&l.header?(0,u.h)("div",{class:"content-header"},l.header):null,(0,u.h)("div",O(l))])]))}))])}))):m.value.emptyResult)}})}}]);
\ No newline at end of file
diff --git a/assets/js/5826.60cb8e45.js b/assets/js/5826.60cb8e45.js
new file mode 100644
index 00000000..b376aa5d
--- /dev/null
+++ b/assets/js/5826.60cb8e45.js
@@ -0,0 +1,2 @@
+/*! For license information please see 5826.60cb8e45.js.LICENSE.txt */
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5826],{5826:(t,i,e)=>{function s(t,i,e){const s=document.createElement(i);return t&&(s.className=t),e&&e.appendChild(s),s}function n(t,i){return t.x=i.x,t.y=i.y,void 0!==i.id&&(t.id=i.id),t}function o(t){t.x=Math.round(t.x),t.y=Math.round(t.y)}function a(t,i){const e=Math.abs(t.x-i.x),s=Math.abs(t.y-i.y);return Math.sqrt(e*e+s*s)}function h(t,i){return t.x===i.x&&t.y===i.y}function r(t,i,e){return Math.min(Math.max(t,i),e)}function l(t,i,e){let s=`translate3d(${t}px,${i||0}px,0)`;return void 0!==e&&(s+=` scale3d(${e},${e},1)`),s}function p(t,i,e,s){t.style.transform=l(i,e,s)}e.r(i),e.d(i,{default:()=>ht});function d(t,i,e,s){t.style.transition=i?`${i} ${e}ms ${s||"cubic-bezier(.4,0,.22,1)"}`:"none"}function c(t,i,e){t.style.width="number"==typeof i?`${i}px`:i,t.style.height="number"==typeof e?`${e}px`:e}const m="loading",u="loaded",v="error";function _(){return!(!navigator.vendor||!navigator.vendor.match(/apple/i))}let g=!1;try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:()=>{g=!0}}))}catch(t){}class y{constructor(){this._pool=[]}add(t,i,e,s){this._toggleListener(t,i,e,s)}remove(t,i,e,s){this._toggleListener(t,i,e,s,!0)}removeAll(){this._pool.forEach((t=>{this._toggleListener(t.target,t.type,t.listener,t.passive,!0,!0)})),this._pool=[]}_toggleListener(t,i,e,s,n,o){if(!t)return;const a=n?"removeEventListener":"addEventListener";i.split(" ").forEach((i=>{if(i){o||(n?this._pool=this._pool.filter((s=>s.type!==i||s.listener!==e||s.target!==t)):this._pool.push({target:t,type:i,listener:e,passive:s}));const h=!!g&&{passive:s||!1};t[a](i,e,h)}}))}}function w(t,i){if(t.getViewportSizeFn){const e=t.getViewportSizeFn(t,i);if(e)return e}return{x:document.documentElement.clientWidth,y:window.innerHeight}}function f(t,i,e,s,n){let o=0;if(i.paddingFn)o=i.paddingFn(e,s,n)[t];else if(i.padding)o=i.padding[t];else{const e="padding"+t[0].toUpperCase()+t.slice(1);i[e]&&(o=i[e])}return Number(o)||0}function x(t,i,e,s){return{x:i.x-f("left",t,i,e,s)-f("right",t,i,e,s),y:i.y-f("top",t,i,e,s)-f("bottom",t,i,e,s)}}class P{constructor(t){this.slide=t,this.currZoomLevel=1,this.center={x:0,y:0},this.max={x:0,y:0},this.min={x:0,y:0}}update(t){this.currZoomLevel=t,this.slide.width?(this._updateAxis("x"),this._updateAxis("y"),this.slide.pswp.dispatch("calcBounds",{slide:this.slide})):this.reset()}_updateAxis(t){const{pswp:i}=this.slide,e=this.slide["x"===t?"width":"height"]*this.currZoomLevel,s=f("x"===t?"left":"top",i.options,i.viewportSize,this.slide.data,this.slide.index),n=this.slide.panAreaSize[t];this.center[t]=Math.round((n-e)/2)+s,this.max[t]=e>n?Math.round(n-e)+s:this.center[t],this.min[t]=e>n?s:this.center[t]}reset(){this.center.x=0,this.center.y=0,this.max.x=0,this.max.y=0,this.min.x=0,this.min.y=0}correctPan(t,i){return r(i,this.max[t],this.min[t])}}class S{constructor(t,i,e,s){this.pswp=s,this.options=t,this.itemData=i,this.index=e,this.panAreaSize=null,this.elementSize=null,this.fit=1,this.fill=1,this.vFill=1,this.initial=1,this.secondary=1,this.max=1,this.min=1}update(t,i,e){const s={x:t,y:i};this.elementSize=s,this.panAreaSize=e;const n=e.x/s.x,o=e.y/s.y;this.fit=Math.min(1,no?n:o),this.vFill=Math.min(1,o),this.initial=this._getInitial(),this.secondary=this._getSecondary(),this.max=Math.max(this.initial,this.secondary,this._getMax()),this.min=Math.min(this.fit,this.initial,this.secondary),this.pswp&&this.pswp.dispatch("zoomLevelsUpdate",{zoomLevels:this,slideData:this.itemData})}_parseZoomLevelOption(t){const i=t+"ZoomLevel",e=this.options[i];if(e)return"function"==typeof e?e(this):"fill"===e?this.fill:"fit"===e?this.fit:Number(e)}_getSecondary(){let t=this._parseZoomLevelOption("secondary");return t||(t=Math.min(1,3*this.fit),this.elementSize&&t*this.elementSize.x>4e3&&(t=4e3/this.elementSize.x),t)}_getInitial(){return this._parseZoomLevelOption("initial")||this.fit}_getMax(){return this._parseZoomLevelOption("max")||Math.max(1,4*this.fit)}}class b{constructor(t,i,e){this.data=t,this.index=i,this.pswp=e,this.isActive=i===e.currIndex,this.currentResolution=0,this.panAreaSize={x:0,y:0},this.pan={x:0,y:0},this.isFirstSlide=this.isActive&&!e.opener.isOpen,this.zoomLevels=new S(e.options,t,i,e),this.pswp.dispatch("gettingData",{slide:this,data:this.data,index:i}),this.content=this.pswp.contentLoader.getContentBySlide(this),this.container=s("pswp__zoom-wrap","div"),this.holderElement=null,this.currZoomLevel=1,this.width=this.content.width,this.height=this.content.height,this.heavyAppended=!1,this.bounds=new P(this),this.prevDisplayedWidth=-1,this.prevDisplayedHeight=-1,this.pswp.dispatch("slideInit",{slide:this})}setIsActive(t){t&&!this.isActive?this.activate():!t&&this.isActive&&this.deactivate()}append(t){this.holderElement=t,this.container.style.transformOrigin="0 0",this.data&&(this.calculateSize(),this.load(),this.updateContentSize(),this.appendHeavy(),this.holderElement.appendChild(this.container),this.zoomAndPanToInitial(),this.pswp.dispatch("firstZoomPan",{slide:this}),this.applyCurrentZoomPan(),this.pswp.dispatch("afterSetContent",{slide:this}),this.isActive&&this.activate())}load(){this.content.load(!1),this.pswp.dispatch("slideLoad",{slide:this})}appendHeavy(){const{pswp:t}=this;!this.heavyAppended&&t.opener.isOpen&&!t.mainScroll.isShifted()&&(this.isActive,1)&&(this.pswp.dispatch("appendHeavy",{slide:this}).defaultPrevented||(this.heavyAppended=!0,this.content.append(),this.pswp.dispatch("appendHeavyContent",{slide:this})))}activate(){this.isActive=!0,this.appendHeavy(),this.content.activate(),this.pswp.dispatch("slideActivate",{slide:this})}deactivate(){this.isActive=!1,this.content.deactivate(),this.currZoomLevel!==this.zoomLevels.initial&&this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize(),this.pswp.dispatch("slideDeactivate",{slide:this})}destroy(){this.content.hasSlide=!1,this.content.remove(),this.container.remove(),this.pswp.dispatch("slideDestroy",{slide:this})}resize(){this.currZoomLevel!==this.zoomLevels.initial&&this.isActive?(this.calculateSize(),this.bounds.update(this.currZoomLevel),this.panTo(this.pan.x,this.pan.y)):(this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize())}updateContentSize(t){const i=this.currentResolution||this.zoomLevels.initial;if(!i)return;const e=Math.round(this.width*i)||this.pswp.viewportSize.x,s=Math.round(this.height*i)||this.pswp.viewportSize.y;(this.sizeChanged(e,s)||t)&&this.content.setDisplayedSize(e,s)}sizeChanged(t,i){return(t!==this.prevDisplayedWidth||i!==this.prevDisplayedHeight)&&(this.prevDisplayedWidth=t,this.prevDisplayedHeight=i,!0)}getPlaceholderElement(){var t;return null===(t=this.content.placeholder)||void 0===t?void 0:t.element}zoomTo(t,i,e,s){const{pswp:n}=this;if(!this.isZoomable()||n.mainScroll.isShifted())return;n.dispatch("beforeZoomTo",{destZoomLevel:t,centerPoint:i,transitionDuration:e}),n.animations.stopAllPan();const a=this.currZoomLevel;s||(t=r(t,this.zoomLevels.min,this.zoomLevels.max)),this.setZoomLevel(t),this.pan.x=this.calculateZoomToPanOffset("x",i,a),this.pan.y=this.calculateZoomToPanOffset("y",i,a),o(this.pan);const h=()=>{this._setResolution(t),this.applyCurrentZoomPan()};e?n.animations.startTransition({isPan:!0,name:"zoomTo",target:this.container,transform:this.getCurrentTransform(),onComplete:h,duration:e,easing:n.options.easing}):h()}toggleZoom(t){this.zoomTo(this.currZoomLevel===this.zoomLevels.initial?this.zoomLevels.secondary:this.zoomLevels.initial,t,this.pswp.options.zoomAnimationDuration)}setZoomLevel(t){this.currZoomLevel=t,this.bounds.update(this.currZoomLevel)}calculateZoomToPanOffset(t,i,e){if(0==this.bounds.max[t]-this.bounds.min[t])return this.bounds.center[t];i||(i=this.pswp.getViewportCenterPoint()),e||(e=this.zoomLevels.initial);const s=this.currZoomLevel/e;return this.bounds.correctPan(t,(this.pan[t]-i[t])*s+i[t])}panTo(t,i){this.pan.x=this.bounds.correctPan("x",t),this.pan.y=this.bounds.correctPan("y",i),this.applyCurrentZoomPan()}isPannable(){return Boolean(this.width)&&this.currZoomLevel>this.zoomLevels.fit}isZoomable(){return Boolean(this.width)&&this.content.isZoomable()}applyCurrentZoomPan(){this._applyZoomTransform(this.pan.x,this.pan.y,this.currZoomLevel),this===this.pswp.currSlide&&this.pswp.dispatch("zoomPanUpdate",{slide:this})}zoomAndPanToInitial(){this.currZoomLevel=this.zoomLevels.initial,this.bounds.update(this.currZoomLevel),n(this.pan,this.bounds.center),this.pswp.dispatch("initialZoomPan",{slide:this})}_applyZoomTransform(t,i,e){e/=this.currentResolution||this.zoomLevels.initial,p(this.container,t,i,e)}calculateSize(){const{pswp:t}=this;n(this.panAreaSize,x(t.options,t.viewportSize,this.data,this.index)),this.zoomLevels.update(this.width,this.height,this.panAreaSize),t.dispatch("calcSlideSize",{slide:this})}getCurrentTransform(){const t=this.currZoomLevel/(this.currentResolution||this.zoomLevels.initial);return l(this.pan.x,this.pan.y,t)}_setResolution(t){t!==this.currentResolution&&(this.currentResolution=t,this.updateContentSize(),this.pswp.dispatch("resolutionChanged"))}}class z{constructor(t){this.gestures=t,this.pswp=t.pswp,this.startPan={x:0,y:0}}start(){this.pswp.currSlide&&n(this.startPan,this.pswp.currSlide.pan),this.pswp.animations.stopAll()}change(){const{p1:t,prevP1:i,dragAxis:e}=this.gestures,{currSlide:s}=this.pswp;if("y"===e&&this.pswp.options.closeOnVerticalDrag&&s&&s.currZoomLevel<=s.zoomLevels.fit&&!this.gestures.isMultitouch){const e=s.pan.y+(t.y-i.y);if(!this.pswp.dispatch("verticalDrag",{panY:e}).defaultPrevented){this._setPanWithFriction("y",e,.6);const t=1-Math.abs(this._getVerticalDragRatio(s.pan.y));this.pswp.applyBgOpacity(t),s.applyCurrentZoomPan()}}else this._panOrMoveMainScroll("x")||(this._panOrMoveMainScroll("y"),s&&(o(s.pan),s.applyCurrentZoomPan()))}end(){const{velocity:t}=this.gestures,{mainScroll:i,currSlide:e}=this.pswp;let s=0;if(this.pswp.animations.stopAll(),i.isShifted()){const e=(i.x-i.getCurrSlideX())/this.pswp.viewportSize.x;t.x<-.5&&e<0||t.x<.1&&e<-.5?(s=1,t.x=Math.min(t.x,0)):(t.x>.5&&e>0||t.x>-.1&&e>.5)&&(s=-1,t.x=Math.max(t.x,0)),i.moveIndexBy(s,!0,t.x)}e&&e.currZoomLevel>e.zoomLevels.max||this.gestures.isMultitouch?this.gestures.zoomLevels.correctZoomPan(!0):(this._finishPanGestureForAxis("x"),this._finishPanGestureForAxis("y"))}_finishPanGestureForAxis(t){const{velocity:i}=this.gestures,{currSlide:e}=this.pswp;if(!e)return;const{pan:s,bounds:n}=e,o=s[t],a=this.pswp.bgOpacity<1&&"y"===t,h=o+.995*i[t]/(1-.995);if(a){const t=this._getVerticalDragRatio(o),i=this._getVerticalDragRatio(h);if(t<0&&i<-.4||t>0&&i>.4)return void this.pswp.close()}const l=n.correctPan(t,h);if(o===l)return;const p=l===h?1:.82,d=this.pswp.bgOpacity,c=l-o;this.pswp.animations.startSpring({name:"panGesture"+t,isPan:!0,start:o,end:l,velocity:i[t],dampingRatio:p,onUpdate:i=>{if(a&&this.pswp.bgOpacity<1){const t=1-(l-i)/c;this.pswp.applyBgOpacity(r(d+(1-d)*t,0,1))}s[t]=Math.floor(i),e.applyCurrentZoomPan()}})}_panOrMoveMainScroll(t){const{p1:i,dragAxis:e,prevP1:s,isMultitouch:n}=this.gestures,{currSlide:o,mainScroll:a}=this.pswp,h=i[t]-s[t],r=a.x+h;if(!h||!o)return!1;if("x"===t&&!o.isPannable()&&!n)return a.moveTo(r,!0),!0;const{bounds:l}=o,p=o.pan[t]+h;if(this.pswp.options.allowPanToNext&&"x"===e&&"x"===t&&!n){const i=a.getCurrSlideX(),e=a.x-i,s=h>0,n=!s;if(p>l.min[t]&&s){if(l.min[t]<=this.startPan[t])return a.moveTo(r,!0),!0;this._setPanWithFriction(t,p)}else if(p0)return a.moveTo(Math.max(r,i),!0),!0;if(e<0)return a.moveTo(Math.min(r,i),!0),!0}else this._setPanWithFriction(t,p)}else"y"===t&&(a.isShifted()||l.min.y===l.max.y)||this._setPanWithFriction(t,p);return!1}_getVerticalDragRatio(t){var i,e;return(t-(null!==(i=null===(e=this.pswp.currSlide)||void 0===e?void 0:e.bounds.center.y)&&void 0!==i?i:0))/(this.pswp.viewportSize.y/3)}_setPanWithFriction(t,i,e){const{currSlide:s}=this.pswp;if(!s)return;const{pan:n,bounds:o}=s;if(o.correctPan(t,i)!==i||e){const s=Math.round(i-n[t]);n[t]+=s*(e||.35)}else n[t]=i}}function C(t,i,e){return t.x=(i.x+e.x)/2,t.y=(i.y+e.y)/2,t}class I{constructor(t){this.gestures=t,this._startPan={x:0,y:0},this._startZoomPoint={x:0,y:0},this._zoomPoint={x:0,y:0},this._wasOverFitZoomLevel=!1,this._startZoomLevel=1}start(){const{currSlide:t}=this.gestures.pswp;t&&(this._startZoomLevel=t.currZoomLevel,n(this._startPan,t.pan)),this.gestures.pswp.animations.stopAllPan(),this._wasOverFitZoomLevel=!1}change(){const{p1:t,startP1:i,p2:e,startP2:s,pswp:n}=this.gestures,{currSlide:o}=n;if(!o)return;const h=o.zoomLevels.min,r=o.zoomLevels.max;if(!o.isZoomable()||n.mainScroll.isShifted())return;C(this._startZoomPoint,i,s),C(this._zoomPoint,t,e);let l=1/a(i,s)*a(t,e)*this._startZoomLevel;if(l>o.zoomLevels.initial+o.zoomLevels.initial/15&&(this._wasOverFitZoomLevel=!0),lr&&(l=r+.05*(l-r));o.pan.x=this._calculatePanForZoomLevel("x",l),o.pan.y=this._calculatePanForZoomLevel("y",l),o.setZoomLevel(l),o.applyCurrentZoomPan()}end(){const{pswp:t}=this.gestures,{currSlide:i}=t;(!i||i.currZoomLevele.zoomLevels.max?o=e.zoomLevels.max:(a=!1,o=s);const l=i.bgOpacity,p=i.bgOpacity<1,d=n({x:0,y:0},e.pan);let c=n({x:0,y:0},d);t&&(this._zoomPoint.x=0,this._zoomPoint.y=0,this._startZoomPoint.x=0,this._startZoomPoint.y=0,this._startZoomLevel=s,n(this._startPan,d)),a&&(c={x:this._calculatePanForZoomLevel("x",o),y:this._calculatePanForZoomLevel("y",o)}),e.setZoomLevel(o),c={x:e.bounds.correctPan("x",c.x),y:e.bounds.correctPan("y",c.y)},e.setZoomLevel(s);const m=!h(c,d);if(!m&&!a&&!p)return e._setResolution(o),void e.applyCurrentZoomPan();i.animations.stopAllPan(),i.animations.startSpring({isPan:!0,start:0,end:1e3,velocity:0,dampingRatio:1,naturalFrequency:40,onUpdate:t=>{if(t/=1e3,m||a){if(m&&(e.pan.x=d.x+(c.x-d.x)*t,e.pan.y=d.y+(c.y-d.y)*t),a){const i=s+(o-s)*t;e.setZoomLevel(i)}e.applyCurrentZoomPan()}p&&i.bgOpacity<1&&i.applyBgOpacity(r(l+(1-l)*t,0,1))},onComplete:()=>{e._setResolution(o),e.applyCurrentZoomPan()}})}}function L(t){return!!t.target.closest(".pswp__container")}class A{constructor(t){this.gestures=t}click(t,i){const e=i.target.classList,s=e.contains("pswp__img"),n=e.contains("pswp__item")||e.contains("pswp__zoom-wrap");s?this._doClickOrTapAction("imageClick",t,i):n&&this._doClickOrTapAction("bgClick",t,i)}tap(t,i){L(i)&&this._doClickOrTapAction("tap",t,i)}doubleTap(t,i){L(i)&&this._doClickOrTapAction("doubleTap",t,i)}_doClickOrTapAction(t,i,e){var s;const{pswp:n}=this.gestures,{currSlide:o}=n,a=t+"Action",h=n.options[a];if(!n.dispatch(a,{point:i,originalEvent:e}).defaultPrevented)if("function"!=typeof h)switch(h){case"close":case"next":n[h]();break;case"zoom":null==o||o.toggleZoom(i);break;case"zoom-or-close":null!=o&&o.isZoomable()&&o.zoomLevels.secondary!==o.zoomLevels.initial?o.toggleZoom(i):n.options.clickToCloseNonZoomable&&n.close();break;case"toggle-controls":null===(s=this.gestures.pswp.element)||void 0===s||s.classList.toggle("pswp--ui-visible")}else h.call(n,i,e)}}class T{constructor(t){this.pswp=t,this.dragAxis=null,this.p1={x:0,y:0},this.p2={x:0,y:0},this.prevP1={x:0,y:0},this.prevP2={x:0,y:0},this.startP1={x:0,y:0},this.startP2={x:0,y:0},this.velocity={x:0,y:0},this._lastStartP1={x:0,y:0},this._intervalP1={x:0,y:0},this._numActivePoints=0,this._ongoingPointers=[],this._touchEventEnabled="ontouchstart"in window,this._pointerEventEnabled=!!window.PointerEvent,this.supportsTouch=this._touchEventEnabled||this._pointerEventEnabled&&navigator.maxTouchPoints>1,this._numActivePoints=0,this._intervalTime=0,this._velocityCalculated=!1,this.isMultitouch=!1,this.isDragging=!1,this.isZooming=!1,this.raf=null,this._tapTimer=null,this.supportsTouch||(t.options.allowPanToNext=!1),this.drag=new z(this),this.zoomLevels=new I(this),this.tapHandler=new A(this),t.on("bindEvents",(()=>{t.events.add(t.scrollWrap,"click",this._onClick.bind(this)),this._pointerEventEnabled?this._bindEvents("pointer","down","up","cancel"):this._touchEventEnabled?(this._bindEvents("touch","start","end","cancel"),t.scrollWrap&&(t.scrollWrap.ontouchmove=()=>{},t.scrollWrap.ontouchend=()=>{})):this._bindEvents("mouse","down","up")}))}_bindEvents(t,i,e,s){const{pswp:n}=this,{events:o}=n,a=s?t+s:"";o.add(n.scrollWrap,t+i,this.onPointerDown.bind(this)),o.add(window,t+"move",this.onPointerMove.bind(this)),o.add(window,t+e,this.onPointerUp.bind(this)),a&&o.add(n.scrollWrap,a,this.onPointerUp.bind(this))}onPointerDown(t){const i="mousedown"===t.type||"mouse"===t.pointerType;if(i&&t.button>0)return;const{pswp:e}=this;e.opener.isOpen?e.dispatch("pointerDown",{originalEvent:t}).defaultPrevented||(i&&(e.mouseDetected(),this._preventPointerEventBehaviour(t,"down")),e.animations.stopAll(),this._updatePoints(t,"down"),1===this._numActivePoints&&(this.dragAxis=null,n(this.startP1,this.p1)),this._numActivePoints>1?(this._clearTapTimer(),this.isMultitouch=!0):this.isMultitouch=!1):t.preventDefault()}onPointerMove(t){this._preventPointerEventBehaviour(t,"move"),this._numActivePoints&&(this._updatePoints(t,"move"),this.pswp.dispatch("pointerMove",{originalEvent:t}).defaultPrevented||(1!==this._numActivePoints||this.isDragging?this._numActivePoints>1&&!this.isZooming&&(this._finishDrag(),this.isZooming=!0,this._updateStartPoints(),this.zoomLevels.start(),this._rafStopLoop(),this._rafRenderLoop()):(this.dragAxis||this._calculateDragDirection(),this.dragAxis&&!this.isDragging&&(this.isZooming&&(this.isZooming=!1,this.zoomLevels.end()),this.isDragging=!0,this._clearTapTimer(),this._updateStartPoints(),this._intervalTime=Date.now(),this._velocityCalculated=!1,n(this._intervalP1,this.p1),this.velocity.x=0,this.velocity.y=0,this.drag.start(),this._rafStopLoop(),this._rafRenderLoop()))))}_finishDrag(){this.isDragging&&(this.isDragging=!1,this._velocityCalculated||this._updateVelocity(!0),this.drag.end(),this.dragAxis=null)}onPointerUp(t){this._numActivePoints&&(this._updatePoints(t,"up"),this.pswp.dispatch("pointerUp",{originalEvent:t}).defaultPrevented||(0===this._numActivePoints&&(this._rafStopLoop(),this.isDragging?this._finishDrag():this.isZooming||this.isMultitouch||this._finishTap(t)),this._numActivePoints<2&&this.isZooming&&(this.isZooming=!1,this.zoomLevels.end(),1===this._numActivePoints&&(this.dragAxis=null,this._updateStartPoints()))))}_rafRenderLoop(){(this.isDragging||this.isZooming)&&(this._updateVelocity(),this.isDragging?h(this.p1,this.prevP1)||this.drag.change():h(this.p1,this.prevP1)&&h(this.p2,this.prevP2)||this.zoomLevels.change(),this._updatePrevPoints(),this.raf=requestAnimationFrame(this._rafRenderLoop.bind(this)))}_updateVelocity(t){const i=Date.now(),e=i-this._intervalTime;e<50&&!t||(this.velocity.x=this._getVelocity("x",e),this.velocity.y=this._getVelocity("y",e),this._intervalTime=i,n(this._intervalP1,this.p1),this._velocityCalculated=!0)}_finishTap(t){const{mainScroll:i}=this.pswp;if(i.isShifted())return void i.moveIndexBy(0,!0);if(t.type.indexOf("cancel")>0)return;if("mouseup"===t.type||"mouse"===t.pointerType)return void this.tapHandler.click(this.startP1,t);const e=this.pswp.options.doubleTapAction?300:0;this._tapTimer?(this._clearTapTimer(),a(this._lastStartP1,this.startP1)<25&&this.tapHandler.doubleTap(this.startP1,t)):(n(this._lastStartP1,this.startP1),this._tapTimer=setTimeout((()=>{this.tapHandler.tap(this.startP1,t),this._clearTapTimer()}),e))}_clearTapTimer(){this._tapTimer&&(clearTimeout(this._tapTimer),this._tapTimer=null)}_getVelocity(t,i){const e=this.p1[t]-this._intervalP1[t];return Math.abs(e)>1&&i>5?e/i:0}_rafStopLoop(){this.raf&&(cancelAnimationFrame(this.raf),this.raf=null)}_preventPointerEventBehaviour(t,i){this.pswp.applyFilters("preventPointerEvent",!0,t,i)&&t.preventDefault()}_updatePoints(t,i){if(this._pointerEventEnabled){const e=t,s=this._ongoingPointers.findIndex((t=>t.id===e.pointerId));"up"===i&&s>-1?this._ongoingPointers.splice(s,1):"down"===i&&-1===s?this._ongoingPointers.push(this._convertEventPosToPoint(e,{x:0,y:0})):s>-1&&this._convertEventPosToPoint(e,this._ongoingPointers[s]),this._numActivePoints=this._ongoingPointers.length,this._numActivePoints>0&&n(this.p1,this._ongoingPointers[0]),this._numActivePoints>1&&n(this.p2,this._ongoingPointers[1])}else{const e=t;this._numActivePoints=0,e.type.indexOf("touch")>-1?e.touches&&e.touches.length>0&&(this._convertEventPosToPoint(e.touches[0],this.p1),this._numActivePoints++,e.touches.length>1&&(this._convertEventPosToPoint(e.touches[1],this.p2),this._numActivePoints++)):(this._convertEventPosToPoint(t,this.p1),"up"===i?this._numActivePoints=0:this._numActivePoints++)}}_updatePrevPoints(){n(this.prevP1,this.p1),n(this.prevP2,this.p2)}_updateStartPoints(){n(this.startP1,this.p1),n(this.startP2,this.p2),this._updatePrevPoints()}_calculateDragDirection(){if(this.pswp.mainScroll.isShifted())this.dragAxis="x";else{const t=Math.abs(this.p1.x-this.startP1.x)-Math.abs(this.p1.y-this.startP1.y);if(0!==t){const i=t>0?"x":"y";Math.abs(this.p1[i]-this.startP1[i])>=10&&(this.dragAxis=i)}}}_convertEventPosToPoint(t,i){return i.x=t.pageX-this.pswp.offset.x,i.y=t.pageY-this.pswp.offset.y,"pointerId"in t?i.id=t.pointerId:void 0!==t.identifier&&(i.id=t.identifier),i}_onClick(t){this.pswp.mainScroll.isShifted()&&(t.preventDefault(),t.stopPropagation())}}class Z{constructor(t){this.pswp=t,this.x=0,this.slideWidth=0,this._currPositionIndex=0,this._prevPositionIndex=0,this._containerShiftIndex=-1,this.itemHolders=[]}resize(t){const{pswp:i}=this,e=Math.round(i.viewportSize.x+i.viewportSize.x*i.options.spacing),s=e!==this.slideWidth;s&&(this.slideWidth=e,this.moveTo(this.getCurrSlideX())),this.itemHolders.forEach(((i,e)=>{s&&p(i.el,(e+this._containerShiftIndex)*this.slideWidth),t&&i.slide&&i.slide.resize()}))}resetPosition(){this._currPositionIndex=0,this._prevPositionIndex=0,this.slideWidth=0,this._containerShiftIndex=-1}appendHolders(){this.itemHolders=[];for(let t=0;t<3;t++){const i=s("pswp__item","div",this.pswp.container);i.setAttribute("role","group"),i.setAttribute("aria-roledescription","slide"),i.setAttribute("aria-hidden","true"),i.style.display=1===t?"block":"none",this.itemHolders.push({el:i})}}canBeSwiped(){return this.pswp.getNumItems()>1}moveIndexBy(t,i,e){const{pswp:s}=this;let n=s.potentialIndex+t;const o=s.getNumItems();if(s.canLoop()){n=s.getLoopedIndex(n);const i=(t+o)%o;t=i<=o/2?i:i-o}else n<0?n=0:n>=o&&(n=o-1),t=n-s.potentialIndex;s.potentialIndex=n,this._currPositionIndex-=t,s.animations.stopMainScroll();const a=this.getCurrSlideX();if(i){s.animations.startSpring({isMainScroll:!0,start:this.x,end:a,velocity:e||0,naturalFrequency:30,dampingRatio:1,onUpdate:t=>{this.moveTo(t)},onComplete:()=>{this.updateCurrItem(),s.appendHeavy()}});let t=s.potentialIndex-s.currIndex;if(s.canLoop()){const i=(t+o)%o;t=i<=o/2?i:i-o}Math.abs(t)>1&&this.updateCurrItem()}else this.moveTo(a),this.updateCurrItem();return Boolean(t)}getCurrSlideX(){return this.slideWidth*this._currPositionIndex}isShifted(){return this.x!==this.getCurrSlideX()}updateCurrItem(){var t;const{pswp:i}=this,e=this._prevPositionIndex-this._currPositionIndex;if(!e)return;this._prevPositionIndex=this._currPositionIndex,i.currIndex=i.potentialIndex;let s,n=Math.abs(e);n>=3&&(this._containerShiftIndex+=e+(e>0?-3:3),n=3);for(let t=0;t0?(s=this.itemHolders.shift(),s&&(this.itemHolders[2]=s,this._containerShiftIndex++,p(s.el,(this._containerShiftIndex+2)*this.slideWidth),i.setContent(s,i.currIndex-n+t+2))):(s=this.itemHolders.pop(),s&&(this.itemHolders.unshift(s),this._containerShiftIndex--,p(s.el,this._containerShiftIndex*this.slideWidth),i.setContent(s,i.currIndex+n-t-2)));Math.abs(this._containerShiftIndex)>50&&!this.isShifted()&&(this.resetPosition(),this.resize()),i.animations.stopAllPan(),this.itemHolders.forEach(((t,i)=>{t.slide&&t.slide.setIsActive(1===i)})),i.currSlide=null===(t=this.itemHolders[1])||void 0===t?void 0:t.slide,i.contentLoader.updateLazy(e),i.currSlide&&i.currSlide.applyCurrentZoomPan(),i.dispatch("change")}moveTo(t,i){if(!this.pswp.canLoop()&&i){let i=(this.slideWidth*this._currPositionIndex-t)/this.slideWidth;i+=this.pswp.currIndex;const e=Math.round(t-this.x);(i<0&&e>0||i>=this.pswp.getNumItems()-1&&e<0)&&(t=this.x+.35*e)}this.x=t,this.pswp.container&&p(this.pswp.container,t),this.pswp.dispatch("moveMainScroll",{x:t,dragging:null!=i&&i})}}const O={Escape:27,z:90,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Tab:9},D=(t,i)=>i?t:O[t];class E{constructor(t){this.pswp=t,this._wasFocused=!1,t.on("bindEvents",(()=>{t.options.trapFocus&&(t.options.initialPointerPos||this._focusRoot(),t.events.add(document,"focusin",this._onFocusIn.bind(this))),t.events.add(document,"keydown",this._onKeyDown.bind(this))}));const i=document.activeElement;t.on("destroy",(()=>{t.options.returnFocus&&i&&this._wasFocused&&i.focus()}))}_focusRoot(){!this._wasFocused&&this.pswp.element&&(this.pswp.element.focus(),this._wasFocused=!0)}_onKeyDown(t){const{pswp:i}=this;if(i.dispatch("keydown",{originalEvent:t}).defaultPrevented)return;if(function(t){return"button"in t&&1===t.button||t.ctrlKey||t.metaKey||t.altKey||t.shiftKey}(t))return;let e,s,n=!1;const o="key"in t;switch(o?t.key:t.keyCode){case D("Escape",o):i.options.escKey&&(e="close");break;case D("z",o):e="toggleZoom";break;case D("ArrowLeft",o):s="x";break;case D("ArrowUp",o):s="y";break;case D("ArrowRight",o):s="x",n=!0;break;case D("ArrowDown",o):n=!0,s="y";break;case D("Tab",o):this._focusRoot()}if(s){t.preventDefault();const{currSlide:o}=i;i.options.arrowKeys&&"x"===s&&i.getNumItems()>1?e=n?"next":"prev":o&&o.currZoomLevel>o.zoomLevels.fit&&(o.pan[s]+=n?-80:80,o.panTo(o.pan.x,o.pan.y))}e&&(t.preventDefault(),i[e]())}_onFocusIn(t){const{template:i}=this.pswp;i&&document!==t.target&&i!==t.target&&!i.contains(t.target)&&i.focus()}}const M="cubic-bezier(.4,0,.22,1)";class F{constructor(t){var i;this.props=t;const{target:e,onComplete:s,transform:n,onFinish:o=(()=>{}),duration:a=333,easing:h=M}=t;this.onFinish=o;const r=n?"transform":"opacity",l=null!==(i=t[r])&&void 0!==i?i:"";this._target=e,this._onComplete=s,this._finished=!1,this._onTransitionEnd=this._onTransitionEnd.bind(this),this._helperTimeout=setTimeout((()=>{d(e,r,a,h),this._helperTimeout=setTimeout((()=>{e.addEventListener("transitionend",this._onTransitionEnd,!1),e.addEventListener("transitioncancel",this._onTransitionEnd,!1),this._helperTimeout=setTimeout((()=>{this._finalizeAnimation()}),a+500),e.style[r]=l}),30)}),0)}_onTransitionEnd(t){t.target===this._target&&this._finalizeAnimation()}_finalizeAnimation(){this._finished||(this._finished=!0,this.onFinish(),this._onComplete&&this._onComplete())}destroy(){this._helperTimeout&&clearTimeout(this._helperTimeout),d(this._target),this._target.removeEventListener("transitionend",this._onTransitionEnd,!1),this._target.removeEventListener("transitioncancel",this._onTransitionEnd,!1),this._finished||this._finalizeAnimation()}}class B{constructor(t,i,e){this.velocity=1e3*t,this._dampingRatio=i||.75,this._naturalFrequency=e||12,this._dampedFrequency=this._naturalFrequency,this._dampingRatio<1&&(this._dampedFrequency*=Math.sqrt(1-this._dampingRatio*this._dampingRatio))}easeFrame(t,i){let e,s=0;i/=1e3;const n=Math.E**(-this._dampingRatio*this._naturalFrequency*i);if(1===this._dampingRatio)e=this.velocity+this._naturalFrequency*t,s=(t+e*i)*n,this.velocity=s*-this._naturalFrequency+e*n;else if(this._dampingRatio<1){e=1/this._dampedFrequency*(this._dampingRatio*this._naturalFrequency*t+this.velocity);const o=Math.cos(this._dampedFrequency*i),a=Math.sin(this._dampedFrequency*i);s=n*(t*o+e*a),this.velocity=s*-this._naturalFrequency*this._dampingRatio+n*(-this._dampedFrequency*t*a+this._dampedFrequency*e*o)}return s}}class R{constructor(t){this.props=t,this._raf=0;const{start:i,end:e,velocity:s,onUpdate:n,onComplete:o,onFinish:a=(()=>{}),dampingRatio:h,naturalFrequency:r}=t;this.onFinish=a;const l=new B(s,h,r);let p=Date.now(),d=i-e;const c=()=>{this._raf&&(d=l.easeFrame(d,Date.now()-p),Math.abs(d)<1&&Math.abs(l.velocity)<50?(n(e),o&&o(),this.onFinish()):(p=Date.now(),n(d+e),this._raf=requestAnimationFrame(c)))};this._raf=requestAnimationFrame(c)}destroy(){this._raf>=0&&cancelAnimationFrame(this._raf),this._raf=0}}class k{constructor(){this.activeAnimations=[]}startSpring(t){this._start(t,!0)}startTransition(t){this._start(t)}_start(t,i){const e=i?new R(t):new F(t);return this.activeAnimations.push(e),e.onFinish=()=>this.stop(e),e}stop(t){t.destroy();const i=this.activeAnimations.indexOf(t);i>-1&&this.activeAnimations.splice(i,1)}stopAll(){this.activeAnimations.forEach((t=>{t.destroy()})),this.activeAnimations=[]}stopAllPan(){this.activeAnimations=this.activeAnimations.filter((t=>!t.props.isPan||(t.destroy(),!1)))}stopMainScroll(){this.activeAnimations=this.activeAnimations.filter((t=>!t.props.isMainScroll||(t.destroy(),!1)))}isPanRunning(){return this.activeAnimations.some((t=>t.props.isPan))}}class H{constructor(t){this.pswp=t,t.events.add(t.element,"wheel",this._onWheel.bind(this))}_onWheel(t){t.preventDefault();const{currSlide:i}=this.pswp;let{deltaX:e,deltaY:s}=t;if(i&&!this.pswp.dispatch("wheel",{originalEvent:t}).defaultPrevented)if(t.ctrlKey||this.pswp.options.wheelToZoom){if(i.isZoomable()){let e=-s;1===t.deltaMode?e*=.05:e*=t.deltaMode?1:.002,e=2**e;const n=i.currZoomLevel*e;i.zoomTo(n,{x:t.clientX,y:t.clientY})}}else i.isPannable()&&(1===t.deltaMode&&(e*=18,s*=18),i.panTo(i.pan.x-e,i.pan.y-s))}}class W{constructor(t,i){var e;const n=i.name||i.className;let o=i.html;if(!1===t.options[n])return;"string"==typeof t.options[n+"SVG"]&&(o=t.options[n+"SVG"]),t.dispatch("uiElementCreate",{data:i});let a="";i.isButton?(a+="pswp__button ",a+=i.className||`pswp__button--${i.name}`):a+=i.className||`pswp__${i.name}`;let h=i.isButton?i.tagName||"button":i.tagName||"div";h=h.toLowerCase();const r=s(a,h);if(i.isButton){"button"===h&&(r.type="button");let{title:e}=i;const{ariaLabel:s}=i;"string"==typeof t.options[n+"Title"]&&(e=t.options[n+"Title"]),e&&(r.title=e);const o=s||e;o&&r.setAttribute("aria-label",o)}r.innerHTML=function(t){if("string"==typeof t)return t;if(!t||!t.isCustomSVG)return"";const i=t;let e='';return e=e.split("%d").join(i.size||32),i.outlineID&&(e+=' '),e+=i.inner,e+=" ",e}(o),i.onInit&&i.onInit(r,t),i.onClick&&(r.onclick=e=>{"string"==typeof i.onClick?t[i.onClick]():"function"==typeof i.onClick&&i.onClick(e,r,t)});const l=i.appendTo||"bar";let p=t.element;"bar"===l?(t.topBar||(t.topBar=s("pswp__top-bar pswp__hide-on-close","div",t.scrollWrap)),p=t.topBar):(r.classList.add("pswp__hide-on-close"),"wrapper"===l&&(p=t.scrollWrap)),null===(e=p)||void 0===e||e.appendChild(t.applyFilters("uiElement",r,i))}}function N(t,i,e){t.classList.add("pswp__button--arrow"),t.setAttribute("aria-controls","pswp__items"),i.on("change",(()=>{i.options.loop||(t.disabled=e?!(i.currIndex0))}))}const V={name:"arrowPrev",className:"pswp__button--arrow--prev",title:"Previous",order:10,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:' ',outlineID:"pswp__icn-arrow"},onClick:"prev",onInit:N},q={name:"arrowNext",className:"pswp__button--arrow--next",title:"Next",order:11,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:' ',outlineID:"pswp__icn-arrow"},onClick:"next",onInit:(t,i)=>{N(t,i,!0)}},U={name:"close",title:"Close",order:20,isButton:!0,html:{isCustomSVG:!0,inner:' ',outlineID:"pswp__icn-close"},onClick:"close"},G={name:"zoom",title:"Zoom",order:10,isButton:!0,html:{isCustomSVG:!0,inner:' ',outlineID:"pswp__icn-zoom"},onClick:"toggleZoom"},K={name:"preloader",appendTo:"bar",order:7,html:{isCustomSVG:!0,inner:' ',outlineID:"pswp__icn-loading"},onInit:(t,i)=>{let e,s=null;const n=i=>{var s;e!==i&&(e=i,"active",s=i,t.classList.toggle("pswp__preloader--active",s))},o=()=>{var t;if(null===(t=i.currSlide)||void 0===t||!t.content.isLoading())return n(!1),void(s&&(clearTimeout(s),s=null));s||(s=setTimeout((()=>{var t;n(Boolean(null===(t=i.currSlide)||void 0===t?void 0:t.content.isLoading())),s=null}),i.options.preloaderDelay))};i.on("change",o),i.on("loadComplete",(t=>{i.currSlide===t.slide&&o()})),i.ui&&(i.ui.updatePreloaderVisibility=o)}},$={name:"counter",order:5,onInit:(t,i)=>{i.on("change",(()=>{t.innerText=i.currIndex+1+i.options.indexIndicatorSep+i.getNumItems()}))}};function X(t,i){t.classList.toggle("pswp--zoomed-in",i)}class Y{constructor(t){this.pswp=t,this.isRegistered=!1,this.uiElementsData=[],this.items=[],this.updatePreloaderVisibility=()=>{},this._lastUpdatedZoomLevel=void 0}init(){const{pswp:t}=this;this.isRegistered=!1,this.uiElementsData=[U,V,q,G,K,$],t.dispatch("uiRegister"),this.uiElementsData.sort(((t,i)=>(t.order||0)-(i.order||0))),this.items=[],this.isRegistered=!0,this.uiElementsData.forEach((t=>{this.registerElement(t)})),t.on("change",(()=>{var i;null===(i=t.element)||void 0===i||i.classList.toggle("pswp--one-slide",1===t.getNumItems())})),t.on("zoomPanUpdate",(()=>this._onZoomPanUpdate()))}registerElement(t){this.isRegistered?this.items.push(new W(this.pswp,t)):this.uiElementsData.push(t)}_onZoomPanUpdate(){const{template:t,currSlide:i,options:e}=this.pswp;if(this.pswp.opener.isClosing||!t||!i)return;let{currZoomLevel:s}=i;if(this.pswp.opener.isOpen||(s=i.zoomLevels.initial),s===this._lastUpdatedZoomLevel)return;this._lastUpdatedZoomLevel=s;const n=i.zoomLevels.initial-i.zoomLevels.secondary;if(Math.abs(n)<.01||!i.isZoomable())return X(t,!1),void t.classList.remove("pswp--zoom-allowed");t.classList.add("pswp--zoom-allowed"),X(t,(s===i.zoomLevels.initial?i.zoomLevels.secondary:i.zoomLevels.initial)<=s),"zoom"!==e.imageClickAction&&"zoom-or-close"!==e.imageClickAction||t.classList.add("pswp--click-to-zoom")}}class j{constructor(t,i){this.type=t,this.defaultPrevented=!1,i&&Object.assign(this,i)}preventDefault(){this.defaultPrevented=!0}}class J{constructor(){this._listeners={},this._filters={},this.pswp=void 0,this.options=void 0}addFilter(t,i,e=100){var s,n,o;this._filters[t]||(this._filters[t]=[]),null===(s=this._filters[t])||void 0===s||s.push({fn:i,priority:e}),null===(n=this._filters[t])||void 0===n||n.sort(((t,i)=>t.priority-i.priority)),null===(o=this.pswp)||void 0===o||o.addFilter(t,i,e)}removeFilter(t,i){this._filters[t]&&(this._filters[t]=this._filters[t].filter((t=>t.fn!==i))),this.pswp&&this.pswp.removeFilter(t,i)}applyFilters(t,...i){var e;return null===(e=this._filters[t])||void 0===e||e.forEach((t=>{i[0]=t.fn.apply(this,i)})),i[0]}on(t,i){var e,s;this._listeners[t]||(this._listeners[t]=[]),null===(e=this._listeners[t])||void 0===e||e.push(i),null===(s=this.pswp)||void 0===s||s.on(t,i)}off(t,i){var e;this._listeners[t]&&(this._listeners[t]=this._listeners[t].filter((t=>i!==t))),null===(e=this.pswp)||void 0===e||e.off(t,i)}dispatch(t,i){var e;if(this.pswp)return this.pswp.dispatch(t,i);const s=new j(t,i);return null===(e=this._listeners[t])||void 0===e||e.forEach((t=>{t.call(this,s)})),s}}class Q{constructor(t,i){if(this.element=s("pswp__img pswp__img--placeholder",t?"img":"div",i),t){const i=this.element;i.decoding="async",i.alt="",i.src=t,i.setAttribute("role","presentation")}this.element.setAttribute("aria-hidden","true")}setDisplayedSize(t,i){this.element&&("IMG"===this.element.tagName?(c(this.element,250,"auto"),this.element.style.transformOrigin="0 0",this.element.style.transform=l(0,0,t/250)):c(this.element,t,i))}destroy(){var t;null!==(t=this.element)&&void 0!==t&&t.parentNode&&this.element.remove(),this.element=null}}class tt{constructor(t,i,e){this.instance=i,this.data=t,this.index=e,this.element=void 0,this.placeholder=void 0,this.slide=void 0,this.displayedImageWidth=0,this.displayedImageHeight=0,this.width=Number(this.data.w)||Number(this.data.width)||0,this.height=Number(this.data.h)||Number(this.data.height)||0,this.isAttached=!1,this.hasSlide=!1,this.isDecoding=!1,this.state="idle",this.data.type?this.type=this.data.type:this.data.src?this.type="image":this.type="html",this.instance.dispatch("contentInit",{content:this})}removePlaceholder(){this.placeholder&&!this.keepPlaceholder()&&setTimeout((()=>{this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0)}),1e3)}load(t,i){if(this.slide&&this.usePlaceholder())if(this.placeholder){const t=this.placeholder.element;t&&!t.parentElement&&this.slide.container.prepend(t)}else{const t=this.instance.applyFilters("placeholderSrc",!(!this.data.msrc||!this.slide.isFirstSlide)&&this.data.msrc,this);this.placeholder=new Q(t,this.slide.container)}this.element&&!i||this.instance.dispatch("contentLoad",{content:this,isLazy:t}).defaultPrevented||(this.isImageContent()?(this.element=s("pswp__img","img"),this.displayedImageWidth&&this.loadImage(t)):(this.element=s("pswp__content","div"),this.element.innerHTML=this.data.html||""),i&&this.slide&&this.slide.updateContentSize(!0))}loadImage(t){var i,e;if(!this.isImageContent()||!this.element||this.instance.dispatch("contentLoadImage",{content:this,isLazy:t}).defaultPrevented)return;const s=this.element;this.updateSrcsetSizes(),this.data.srcset&&(s.srcset=this.data.srcset),s.src=null!==(i=this.data.src)&&void 0!==i?i:"",s.alt=null!==(e=this.data.alt)&&void 0!==e?e:"",this.state=m,s.complete?this.onLoaded():(s.onload=()=>{this.onLoaded()},s.onerror=()=>{this.onError()})}setSlide(t){this.slide=t,this.hasSlide=!0,this.instance=t.pswp}onLoaded(){this.state=u,this.slide&&this.element&&(this.instance.dispatch("loadComplete",{slide:this.slide,content:this}),this.slide.isActive&&this.slide.heavyAppended&&!this.element.parentNode&&(this.append(),this.slide.updateContentSize(!0)),this.state!==u&&this.state!==v||this.removePlaceholder())}onError(){this.state=v,this.slide&&(this.displayError(),this.instance.dispatch("loadComplete",{slide:this.slide,isError:!0,content:this}),this.instance.dispatch("loadError",{slide:this.slide,content:this}))}isLoading(){return this.instance.applyFilters("isContentLoading",this.state===m,this)}isError(){return this.state===v}isImageContent(){return"image"===this.type}setDisplayedSize(t,i){if(this.element&&(this.placeholder&&this.placeholder.setDisplayedSize(t,i),!this.instance.dispatch("contentResize",{content:this,width:t,height:i}).defaultPrevented&&(c(this.element,t,i),this.isImageContent()&&!this.isError()))){const e=!this.displayedImageWidth&&t;this.displayedImageWidth=t,this.displayedImageHeight=i,e?this.loadImage(!1):this.updateSrcsetSizes(),this.slide&&this.instance.dispatch("imageSizeChange",{slide:this.slide,width:t,height:i,content:this})}}isZoomable(){return this.instance.applyFilters("isContentZoomable",this.isImageContent()&&this.state!==v,this)}updateSrcsetSizes(){if(!this.isImageContent()||!this.element||!this.data.srcset)return;const t=this.element,i=this.instance.applyFilters("srcsetSizesWidth",this.displayedImageWidth,this);(!t.dataset.largestUsedSize||i>parseInt(t.dataset.largestUsedSize,10))&&(t.sizes=i+"px",t.dataset.largestUsedSize=String(i))}usePlaceholder(){return this.instance.applyFilters("useContentPlaceholder",this.isImageContent(),this)}lazyLoad(){this.instance.dispatch("contentLazyLoad",{content:this}).defaultPrevented||this.load(!0)}keepPlaceholder(){return this.instance.applyFilters("isKeepingPlaceholder",this.isLoading(),this)}destroy(){this.hasSlide=!1,this.slide=void 0,this.instance.dispatch("contentDestroy",{content:this}).defaultPrevented||(this.remove(),this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0),this.isImageContent()&&this.element&&(this.element.onload=null,this.element.onerror=null,this.element=void 0))}displayError(){if(this.slide){var t,i;let e=s("pswp__error-msg","div");e.innerText=null!==(t=null===(i=this.instance.options)||void 0===i?void 0:i.errorMsg)&&void 0!==t?t:"",e=this.instance.applyFilters("contentErrorElement",e,this),this.element=s("pswp__content pswp__error-msg-container","div"),this.element.appendChild(e),this.slide.container.innerText="",this.slide.container.appendChild(this.element),this.slide.updateContentSize(!0),this.removePlaceholder()}}append(){if(this.isAttached||!this.element)return;if(this.isAttached=!0,this.state===v)return void this.displayError();if(this.instance.dispatch("contentAppend",{content:this}).defaultPrevented)return;const t="decode"in this.element;this.isImageContent()?t&&this.slide&&(!this.slide.isActive||_())?(this.isDecoding=!0,this.element.decode().catch((()=>{})).finally((()=>{this.isDecoding=!1,this.appendImage()}))):this.appendImage():this.slide&&!this.element.parentNode&&this.slide.container.appendChild(this.element)}activate(){!this.instance.dispatch("contentActivate",{content:this}).defaultPrevented&&this.slide&&(this.isImageContent()&&this.isDecoding&&!_()?this.appendImage():this.isError()&&this.load(!1,!0),this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","false"))}deactivate(){this.instance.dispatch("contentDeactivate",{content:this}),this.slide&&this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","true")}remove(){this.isAttached=!1,this.instance.dispatch("contentRemove",{content:this}).defaultPrevented||(this.element&&this.element.parentNode&&this.element.remove(),this.placeholder&&this.placeholder.element&&this.placeholder.element.remove())}appendImage(){this.isAttached&&(this.instance.dispatch("contentAppendImage",{content:this}).defaultPrevented||(this.slide&&this.element&&!this.element.parentNode&&this.slide.container.appendChild(this.element),this.state!==u&&this.state!==v||this.removePlaceholder()))}}function it(t,i,e){const s=i.createContentFromData(t,e);let n;const{options:o}=i;if(o){let a;n=new S(o,t,-1),a=i.pswp?i.pswp.viewportSize:w(o,i);const h=x(o,a,t,e);n.update(s.width,s.height,h)}return s.lazyLoad(),n&&s.setDisplayedSize(Math.ceil(s.width*n.initial),Math.ceil(s.height*n.initial)),s}class et{constructor(t){this.pswp=t,this.limit=Math.max(t.options.preload[0]+t.options.preload[1]+1,5),this._cachedItems=[]}updateLazy(t){const{pswp:i}=this;if(i.dispatch("lazyLoad").defaultPrevented)return;const{preload:e}=i.options,s=void 0===t||t>=0;let n;for(n=0;n<=e[1];n++)this.loadSlideByIndex(i.currIndex+(s?n:-n));for(n=1;n<=e[0];n++)this.loadSlideByIndex(i.currIndex+(s?-n:n))}loadSlideByIndex(t){const i=this.pswp.getLoopedIndex(t);let e=this.getContentByIndex(i);e||(e=function(t,i){const e=i.getItemData(t);if(!i.dispatch("lazyLoadSlide",{index:t,itemData:e}).defaultPrevented)return it(e,i,t)}(i,this.pswp),e&&this.addToCache(e))}getContentBySlide(t){let i=this.getContentByIndex(t.index);return i||(i=this.pswp.createContentFromData(t.data,t.index),this.addToCache(i)),i.setSlide(t),i}addToCache(t){if(this.removeByIndex(t.index),this._cachedItems.push(t),this._cachedItems.length>this.limit){const t=this._cachedItems.findIndex((t=>!t.isAttached&&!t.hasSlide));-1!==t&&this._cachedItems.splice(t,1)[0].destroy()}}removeByIndex(t){const i=this._cachedItems.findIndex((i=>i.index===t));-1!==i&&this._cachedItems.splice(i,1)}getContentByIndex(t){return this._cachedItems.find((i=>i.index===t))}destroy(){this._cachedItems.forEach((t=>t.destroy())),this._cachedItems=[]}}class st extends J{getNumItems(){var t;let i=0;const e=null===(t=this.options)||void 0===t?void 0:t.dataSource;e&&"length"in e?i=e.length:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),e.items&&(i=e.items.length));const s=this.dispatch("numItems",{dataSource:e,numItems:i});return this.applyFilters("numItems",s.numItems,e)}createContentFromData(t,i){return new tt(t,this,i)}getItemData(t){var i;const e=null===(i=this.options)||void 0===i?void 0:i.dataSource;let s={};Array.isArray(e)?s=e[t]:e&&"gallery"in e&&(e.items||(e.items=this._getGalleryDOMElements(e.gallery)),s=e.items[t]);let n=s;n instanceof Element&&(n=this._domElementToItemData(n));const o=this.dispatch("itemData",{itemData:n||{},index:t});return this.applyFilters("itemData",o.itemData,t)}_getGalleryDOMElements(t){var i,e;return null!==(i=this.options)&&void 0!==i&&i.children||null!==(e=this.options)&&void 0!==e&&e.childSelector?function(t,i,e=document){let s=[];if(t instanceof Element)s=[t];else if(t instanceof NodeList||Array.isArray(t))s=Array.from(t);else{const n="string"==typeof t?t:i;n&&(s=Array.from(e.querySelectorAll(n)))}return s}(this.options.children,this.options.childSelector,t)||[]:[t]}_domElementToItemData(t){const i={element:t},e="A"===t.tagName?t:t.querySelector("a");if(e){i.src=e.dataset.pswpSrc||e.href,e.dataset.pswpSrcset&&(i.srcset=e.dataset.pswpSrcset),i.width=e.dataset.pswpWidth?parseInt(e.dataset.pswpWidth,10):0,i.height=e.dataset.pswpHeight?parseInt(e.dataset.pswpHeight,10):0,i.w=i.width,i.h=i.height,e.dataset.pswpType&&(i.type=e.dataset.pswpType);const n=t.querySelector("img");var s;n&&(i.msrc=n.currentSrc||n.src,i.alt=null!==(s=n.getAttribute("alt"))&&void 0!==s?s:""),(e.dataset.pswpCropped||e.dataset.cropped)&&(i.thumbCropped=!0)}return this.applyFilters("domItemData",i,t,e)}lazyLoadData(t,i){return it(t,this,i)}}const nt=.003;class ot{constructor(t){this.pswp=t,this.isClosed=!0,this.isOpen=!1,this.isClosing=!1,this.isOpening=!1,this._duration=void 0,this._useAnimation=!1,this._croppedZoom=!1,this._animateRootOpacity=!1,this._animateBgOpacity=!1,this._placeholder=void 0,this._opacityElement=void 0,this._cropContainer1=void 0,this._cropContainer2=void 0,this._thumbBounds=void 0,this._prepareOpen=this._prepareOpen.bind(this),t.on("firstZoomPan",this._prepareOpen)}open(){this._prepareOpen(),this._start()}close(){if(this.isClosed||this.isClosing||this.isOpening)return;const t=this.pswp.currSlide;this.isOpen=!1,this.isOpening=!1,this.isClosing=!0,this._duration=this.pswp.options.hideAnimationDuration,t&&t.currZoomLevel*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps(),setTimeout((()=>{this._start()}),this._croppedZoom?30:0)}_prepareOpen(){if(this.pswp.off("firstZoomPan",this._prepareOpen),!this.isOpening){const t=this.pswp.currSlide;this.isOpening=!0,this.isClosing=!1,this._duration=this.pswp.options.showAnimationDuration,t&&t.zoomLevels.initial*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps()}}_applyStartProps(){const{pswp:t}=this,i=this.pswp.currSlide,{options:e}=t;var s,n;if("fade"===e.showHideAnimationType?(e.showHideOpacity=!0,this._thumbBounds=void 0):"none"===e.showHideAnimationType?(e.showHideOpacity=!1,this._duration=0,this._thumbBounds=void 0):this.isOpening&&t._initialThumbBounds?this._thumbBounds=t._initialThumbBounds:this._thumbBounds=this.pswp.getThumbBounds(),this._placeholder=null==i?void 0:i.getPlaceholderElement(),t.animations.stopAll(),this._useAnimation=Boolean(this._duration&&this._duration>50),this._animateZoom=Boolean(this._thumbBounds)&&(null==i?void 0:i.content.usePlaceholder())&&(!this.isClosing||!t.mainScroll.isShifted()),this._animateZoom?this._animateRootOpacity=null!==(s=e.showHideOpacity)&&void 0!==s&&s:(this._animateRootOpacity=!0,this.isOpening&&i&&(i.zoomAndPanToInitial(),i.applyCurrentZoomPan())),this._animateBgOpacity=!this._animateRootOpacity&&this.pswp.options.bgOpacity>nt,this._opacityElement=this._animateRootOpacity?t.element:t.bg,!this._useAnimation)return this._duration=0,this._animateZoom=!1,this._animateBgOpacity=!1,this._animateRootOpacity=!0,void(this.isOpening&&(t.element&&(t.element.style.opacity=String(nt)),t.applyBgOpacity(1)));this._animateZoom&&this._thumbBounds&&this._thumbBounds.innerRect?(this._croppedZoom=!0,this._cropContainer1=this.pswp.container,this._cropContainer2=null===(n=this.pswp.currSlide)||void 0===n?void 0:n.holderElement,t.container&&(t.container.style.overflow="hidden",t.container.style.width=t.viewportSize.x+"px")):this._croppedZoom=!1,this.isOpening?(this._animateRootOpacity?(t.element&&(t.element.style.opacity=String(nt)),t.applyBgOpacity(1)):(this._animateBgOpacity&&t.bg&&(t.bg.style.opacity=String(nt)),t.element&&(t.element.style.opacity="1")),this._animateZoom&&(this._setClosedStateZoomPan(),this._placeholder&&(this._placeholder.style.willChange="transform",this._placeholder.style.opacity=String(nt)))):this.isClosing&&(t.mainScroll.itemHolders[0]&&(t.mainScroll.itemHolders[0].el.style.display="none"),t.mainScroll.itemHolders[2]&&(t.mainScroll.itemHolders[2].el.style.display="none"),this._croppedZoom&&0!==t.mainScroll.x&&(t.mainScroll.resetPosition(),t.mainScroll.resize()))}_start(){this.isOpening&&this._useAnimation&&this._placeholder&&"IMG"===this._placeholder.tagName?new Promise((t=>{let i=!1,e=!0;var s;(s=this._placeholder,"decode"in s?s.decode().catch((()=>{})):s.complete?Promise.resolve(s):new Promise(((t,i)=>{s.onload=()=>t(s),s.onerror=i}))).finally((()=>{i=!0,e||t(!0)})),setTimeout((()=>{e=!1,i&&t(!0)}),50),setTimeout(t,250)})).finally((()=>this._initiate())):this._initiate()}_initiate(){var t,i;null===(t=this.pswp.element)||void 0===t||t.style.setProperty("--pswp-transition-duration",this._duration+"ms"),this.pswp.dispatch(this.isOpening?"openingAnimationStart":"closingAnimationStart"),this.pswp.dispatch("initialZoom"+(this.isOpening?"In":"Out")),null===(i=this.pswp.element)||void 0===i||i.classList.toggle("pswp--ui-visible",this.isOpening),this.isOpening?(this._placeholder&&(this._placeholder.style.opacity="1"),this._animateToOpenState()):this.isClosing&&this._animateToClosedState(),this._useAnimation||this._onAnimationComplete()}_onAnimationComplete(){const{pswp:t}=this;if(this.isOpen=this.isOpening,this.isClosed=this.isClosing,this.isOpening=!1,this.isClosing=!1,t.dispatch(this.isOpen?"openingAnimationEnd":"closingAnimationEnd"),t.dispatch("initialZoom"+(this.isOpen?"InEnd":"OutEnd")),this.isClosed)t.destroy();else if(this.isOpen){var i;this._animateZoom&&t.container&&(t.container.style.overflow="visible",t.container.style.width="100%"),null===(i=t.currSlide)||void 0===i||i.applyCurrentZoomPan()}}_animateToOpenState(){const{pswp:t}=this;this._animateZoom&&(this._croppedZoom&&this._cropContainer1&&this._cropContainer2&&(this._animateTo(this._cropContainer1,"transform","translate3d(0,0,0)"),this._animateTo(this._cropContainer2,"transform","none")),t.currSlide&&(t.currSlide.zoomAndPanToInitial(),this._animateTo(t.currSlide.container,"transform",t.currSlide.getCurrentTransform()))),this._animateBgOpacity&&t.bg&&this._animateTo(t.bg,"opacity",String(t.options.bgOpacity)),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","1")}_animateToClosedState(){const{pswp:t}=this;this._animateZoom&&this._setClosedStateZoomPan(!0),this._animateBgOpacity&&t.bgOpacity>.01&&t.bg&&this._animateTo(t.bg,"opacity","0"),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","0")}_setClosedStateZoomPan(t){if(!this._thumbBounds)return;const{pswp:i}=this,{innerRect:e}=this._thumbBounds,{currSlide:s,viewportSize:o}=i;if(this._croppedZoom&&e&&this._cropContainer1&&this._cropContainer2){const i=-o.x+(this._thumbBounds.x-e.x)+e.w,s=-o.y+(this._thumbBounds.y-e.y)+e.h,n=o.x-e.w,a=o.y-e.h;t?(this._animateTo(this._cropContainer1,"transform",l(i,s)),this._animateTo(this._cropContainer2,"transform",l(n,a))):(p(this._cropContainer1,i,s),p(this._cropContainer2,n,a))}s&&(n(s.pan,e||this._thumbBounds),s.currZoomLevel=this._thumbBounds.w/s.width,t?this._animateTo(s.container,"transform",s.getCurrentTransform()):s.applyCurrentZoomPan())}_animateTo(t,i,e){if(!this._duration)return void(t.style[i]=e);const{animations:s}=this.pswp,n={duration:this._duration,easing:this.pswp.options.easing,onComplete:()=>{s.activeAnimations.length||this._onAnimationComplete()},target:t};n[i]=e,s.startTransition(n)}}const at={allowPanToNext:!0,spacing:.1,loop:!0,pinchToClose:!0,closeOnVerticalDrag:!0,hideAnimationDuration:333,showAnimationDuration:333,zoomAnimationDuration:333,escKey:!0,arrowKeys:!0,trapFocus:!0,returnFocus:!0,maxWidthToAnimate:4e3,clickToCloseNonZoomable:!0,imageClickAction:"zoom-or-close",bgClickAction:"close",tapAction:"toggle-controls",doubleTapAction:"zoom",indexIndicatorSep:" / ",preloaderDelay:2e3,bgOpacity:.8,index:0,errorMsg:"The image cannot be loaded",preload:[1,2],easing:"cubic-bezier(.4,0,.22,1)"};class ht extends st{constructor(t){super(),this.options=this._prepareOptions(t||{}),this.offset={x:0,y:0},this._prevViewportSize={x:0,y:0},this.viewportSize={x:0,y:0},this.bgOpacity=1,this.currIndex=0,this.potentialIndex=0,this.isOpen=!1,this.isDestroying=!1,this.hasMouse=!1,this._initialItemData={},this._initialThumbBounds=void 0,this.topBar=void 0,this.element=void 0,this.template=void 0,this.container=void 0,this.scrollWrap=void 0,this.currSlide=void 0,this.events=new y,this.animations=new k,this.mainScroll=new Z(this),this.gestures=new T(this),this.opener=new ot(this),this.keyboard=new E(this),this.contentLoader=new et(this)}init(){if(this.isOpen||this.isDestroying)return!1;this.isOpen=!0,this.dispatch("init"),this.dispatch("beforeOpen"),this._createMainStructure();let t="pswp--open";return this.gestures.supportsTouch&&(t+=" pswp--touch"),this.options.mainClass&&(t+=" "+this.options.mainClass),this.element&&(this.element.className+=" "+t),this.currIndex=this.options.index||0,this.potentialIndex=this.currIndex,this.dispatch("firstUpdate"),this.scrollWheel=new H(this),(Number.isNaN(this.currIndex)||this.currIndex<0||this.currIndex>=this.getNumItems())&&(this.currIndex=0),this.gestures.supportsTouch||this.mouseDetected(),this.updateSize(),this.offset.y=window.pageYOffset,this._initialItemData=this.getItemData(this.currIndex),this.dispatch("gettingData",{index:this.currIndex,data:this._initialItemData,slide:void 0}),this._initialThumbBounds=this.getThumbBounds(),this.dispatch("initialLayout"),this.on("openingAnimationEnd",(()=>{const{itemHolders:t}=this.mainScroll;t[0]&&(t[0].el.style.display="block",this.setContent(t[0],this.currIndex-1)),t[2]&&(t[2].el.style.display="block",this.setContent(t[2],this.currIndex+1)),this.appendHeavy(),this.contentLoader.updateLazy(),this.events.add(window,"resize",this._handlePageResize.bind(this)),this.events.add(window,"scroll",this._updatePageScrollOffset.bind(this)),this.dispatch("bindEvents")})),this.mainScroll.itemHolders[1]&&this.setContent(this.mainScroll.itemHolders[1],this.currIndex),this.dispatch("change"),this.opener.open(),this.dispatch("afterInit"),!0}getLoopedIndex(t){const i=this.getNumItems();return this.options.loop&&(t>i-1&&(t-=i),t<0&&(t+=i)),r(t,0,i-1)}appendHeavy(){this.mainScroll.itemHolders.forEach((t=>{var i;null===(i=t.slide)||void 0===i||i.appendHeavy()}))}goTo(t){this.mainScroll.moveIndexBy(this.getLoopedIndex(t)-this.potentialIndex)}next(){this.goTo(this.potentialIndex+1)}prev(){this.goTo(this.potentialIndex-1)}zoomTo(...t){var i;null===(i=this.currSlide)||void 0===i||i.zoomTo(...t)}toggleZoom(){var t;null===(t=this.currSlide)||void 0===t||t.toggleZoom()}close(){this.opener.isOpen&&!this.isDestroying&&(this.isDestroying=!0,this.dispatch("close"),this.events.removeAll(),this.opener.close())}destroy(){var t;if(!this.isDestroying)return this.options.showHideAnimationType="none",void this.close();this.dispatch("destroy"),this._listeners={},this.scrollWrap&&(this.scrollWrap.ontouchmove=null,this.scrollWrap.ontouchend=null),null===(t=this.element)||void 0===t||t.remove(),this.mainScroll.itemHolders.forEach((t=>{var i;null===(i=t.slide)||void 0===i||i.destroy()})),this.contentLoader.destroy(),this.events.removeAll()}refreshSlideContent(t){this.contentLoader.removeByIndex(t),this.mainScroll.itemHolders.forEach(((i,e)=>{var s,n;let o=(null!==(s=null===(n=this.currSlide)||void 0===n?void 0:n.index)&&void 0!==s?s:0)-1+e;var a;this.canLoop()&&(o=this.getLoopedIndex(o)),o===t&&(this.setContent(i,t,!0),1===e&&(this.currSlide=i.slide,null===(a=i.slide)||void 0===a||a.setIsActive(!0)))})),this.dispatch("change")}setContent(t,i,e){if(this.canLoop()&&(i=this.getLoopedIndex(i)),t.slide){if(t.slide.index===i&&!e)return;t.slide.destroy(),t.slide=void 0}if(!this.canLoop()&&(i<0||i>=this.getNumItems()))return;const s=this.getItemData(i);t.slide=new b(s,i,this),i===this.currIndex&&(this.currSlide=t.slide),t.slide.append(t.el)}getViewportCenterPoint(){return{x:this.viewportSize.x/2,y:this.viewportSize.y/2}}updateSize(t){if(this.isDestroying)return;const i=w(this.options,this);!t&&h(i,this._prevViewportSize)||(n(this._prevViewportSize,i),this.dispatch("beforeResize"),n(this.viewportSize,this._prevViewportSize),this._updatePageScrollOffset(),this.dispatch("viewportSize"),this.mainScroll.resize(this.opener.isOpen),!this.hasMouse&&window.matchMedia("(any-hover: hover)").matches&&this.mouseDetected(),this.dispatch("resize"))}applyBgOpacity(t){this.bgOpacity=Math.max(t,0),this.bg&&(this.bg.style.opacity=String(this.bgOpacity*this.options.bgOpacity))}mouseDetected(){var t;this.hasMouse||(this.hasMouse=!0,null===(t=this.element)||void 0===t||t.classList.add("pswp--has_mouse"))}_handlePageResize(){this.updateSize(),/iPhone|iPad|iPod/i.test(window.navigator.userAgent)&&setTimeout((()=>{this.updateSize()}),500)}_updatePageScrollOffset(){this.setScrollOffset(0,window.pageYOffset)}setScrollOffset(t,i){this.offset.x=t,this.offset.y=i,this.dispatch("updateScrollOffset")}_createMainStructure(){this.element=s("pswp","div"),this.element.setAttribute("tabindex","-1"),this.element.setAttribute("role","dialog"),this.template=this.element,this.bg=s("pswp__bg","div",this.element),this.scrollWrap=s("pswp__scroll-wrap","section",this.element),this.container=s("pswp__container","div",this.scrollWrap),this.scrollWrap.setAttribute("aria-roledescription","carousel"),this.container.setAttribute("aria-live","off"),this.container.setAttribute("id","pswp__items"),this.mainScroll.appendHolders(),this.ui=new Y(this),this.ui.init(),(this.options.appendToEl||document.body).appendChild(this.element)}getThumbBounds(){return function(t,i,e){const s=e.dispatch("thumbBounds",{index:t,itemData:i,instance:e});if(s.thumbBounds)return s.thumbBounds;const{element:n}=i;let o,a;if(n&&!1!==e.options.thumbSelector){const t=e.options.thumbSelector||"img";a=n.matches(t)?n:n.querySelector(t)}return a=e.applyFilters("thumbEl",a,i,t),a&&(o=i.thumbCropped?function(t,i,e){const s=t.getBoundingClientRect(),n=s.width/i,o=s.height/e,a=n>o?n:o,h=(s.width-i*a)/2,r=(s.height-e*a)/2,l={x:s.left+h,y:s.top+r,w:i*a};return l.innerRect={w:s.width,h:s.height,x:h,y:r},l}(a,i.width||i.w||0,i.height||i.h||0):function(t){const i=t.getBoundingClientRect();return{x:i.left,y:i.top,w:i.width}}(a)),e.applyFilters("thumbBounds",o,i,t)}(this.currIndex,this.currSlide?this.currSlide.data:this._initialItemData,this)}canLoop(){return this.options.loop&&this.getNumItems()>2}_prepareOptions(t){return window.matchMedia("(prefers-reduced-motion), (update: slow)").matches&&(t.showHideAnimationType="none",t.zoomAnimationDuration=0),{...at,...t}}}}}]);
\ No newline at end of file
diff --git a/assets/js/5826.60cb8e45.js.LICENSE.txt b/assets/js/5826.60cb8e45.js.LICENSE.txt
new file mode 100644
index 00000000..1c06b786
--- /dev/null
+++ b/assets/js/5826.60cb8e45.js.LICENSE.txt
@@ -0,0 +1,4 @@
+/*!
+ * PhotoSwipe 5.4.3 - https://photoswipe.com
+ * (c) 2023 Dmytro Semenov
+ */
diff --git a/assets/js/883.e417b611.js b/assets/js/883.e417b611.js
new file mode 100644
index 00000000..99766710
--- /dev/null
+++ b/assets/js/883.e417b611.js
@@ -0,0 +1,2 @@
+/*! For license information please see 883.e417b611.js.LICENSE.txt */
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[883],{2262:(e,t,n)=>{n.d(t,{Bj:()=>a,EB:()=>i,Fl:()=>Te,IU:()=>ke,Jd:()=>g,OT:()=>ve,PG:()=>ge,SU:()=>Pe,Um:()=>fe,Vh:()=>Ve,WL:()=>He,X$:()=>F,X3:()=>we,XI:()=>Le,Xl:()=>_e,ZM:()=>Ne,dq:()=>Ae,iH:()=>Fe,j:()=>A,lk:()=>y,nZ:()=>s,qj:()=>he,qq:()=>c,yT:()=>be});var o=n(3577);let r,l;class a{constructor(e=!1){this.detached=e,this._active=!0,this.effects=[],this.cleanups=[],this.parent=r,!e&&r&&(this.index=(r.scopes||(r.scopes=[])).push(this)-1)}get active(){return this._active}run(e){if(this._active){const t=r;try{return r=this,e()}finally{r=t}}}on(){r=this}off(){r=this.parent}stop(e){if(this._active){let t,n;for(t=0,n=this.effects.length;t=2))break}this._dirtyLevel<2&&(this._dirtyLevel=0),y()}return this._dirtyLevel>=2}set dirty(e){this._dirtyLevel=e?2:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let e=f,t=l;try{return f=!0,l=this,this._runnings++,p(this),this.fn()}finally{d(this),this._runnings--,l=t,f=e}}stop(){var e;this.active&&(p(this),d(this),null==(e=this.onStop)||e.call(this),this.active=!1)}}function u(e){return e.value}function p(e){e._trackId++,e._depsLength=0}function d(e){if(e.deps&&e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},T=new WeakMap,I=Symbol(""),E=Symbol("");function A(e,t,n){if(f&&l){let t=T.get(e);t||T.set(e,t=new Map);let o=t.get(n);o||t.set(n,o=x((()=>t.delete(n)))),k(l,o)}}function F(e,t,n,r,l,a){const s=T.get(e);if(!s)return;let i=[];if("clear"===t)i=[...s.values()];else if("length"===n&&(0,o.kJ)(e)){const e=Number(r);s.forEach(((t,n)=>{("length"===n||!(0,o.yk)(n)&&n>=e)&&i.push(t)}))}else switch(void 0!==n&&i.push(s.get(n)),t){case"add":(0,o.kJ)(e)?(0,o.S0)(n)&&i.push(s.get("length")):(i.push(s.get(I)),(0,o._N)(e)&&i.push(s.get(E)));break;case"delete":(0,o.kJ)(e)||(i.push(s.get(I)),(0,o._N)(e)&&i.push(s.get(E)));break;case"set":(0,o._N)(e)&&i.push(s.get(I))}b();for(const e of i)e&&S(e,2);w()}const L=(0,o.fY)("__proto__,__v_isRef,__isVue"),O=new Set(Object.getOwnPropertyNames(Symbol).filter((e=>"arguments"!==e&&"caller"!==e)).map((e=>Symbol[e])).filter(o.yk)),M=P();function P(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=ke(this);for(let e=0,t=this.length;e{e[t]=function(...e){g(),b();const n=ke(this)[t].apply(this,e);return w(),y(),n}})),e}function R(e){const t=ke(this);return A(t,0,e),t.hasOwnProperty(e)}class H{constructor(e=!1,t=!1){this._isReadonly=e,this._shallow=t}get(e,t,n){const r=this._isReadonly,l=this._shallow;if("__v_isReactive"===t)return!r;if("__v_isReadonly"===t)return r;if("__v_isShallow"===t)return l;if("__v_raw"===t)return n===(r?l?de:pe:l?ue:ce).get(e)||Object.getPrototypeOf(e)===Object.getPrototypeOf(n)?e:void 0;const a=(0,o.kJ)(e);if(!r){if(a&&(0,o.RI)(M,t))return Reflect.get(M,t,n);if("hasOwnProperty"===t)return R}const s=Reflect.get(e,t,n);return((0,o.yk)(t)?O.has(t):L(t))?s:(r||A(e,0,t),l?s:Ae(s)?a&&(0,o.S0)(t)?s:s.value:(0,o.Kn)(s)?r?ve(s):he(s):s)}}class $ extends H{constructor(e=!1){super(!1,e)}set(e,t,n,r){let l=e[t];if(!this._shallow){const t=ye(l);if(be(n)||ye(n)||(l=ke(l),n=ke(n)),!(0,o.kJ)(e)&&Ae(l)&&!Ae(n))return!t&&(l.value=n,!0)}const a=(0,o.kJ)(e)&&(0,o.S0)(t)?Number(t)e,z=e=>Reflect.getPrototypeOf(e);function U(e,t,n=!1,r=!1){const l=ke(e=e.__v_raw),a=ke(t);n||((0,o.aU)(t,a)&&A(l,0,t),A(l,0,a));const{has:s}=z(l),i=r?B:n?Ce:Se;return s.call(l,t)?i(e.get(t)):s.call(l,a)?i(e.get(a)):void(e!==l&&e.get(t))}function q(e,t=!1){const n=this.__v_raw,r=ke(n),l=ke(e);return t||((0,o.aU)(e,l)&&A(r,0,e),A(r,0,l)),e===l?n.has(e):n.has(e)||n.has(l)}function Z(e,t=!1){return e=e.__v_raw,!t&&A(ke(e),0,I),Reflect.get(e,"size",e)}function J(e){e=ke(e);const t=ke(this);return z(t).has.call(t,e)||(t.add(e),F(t,"add",e,e)),this}function Y(e,t){t=ke(t);const n=ke(this),{has:r,get:l}=z(n);let a=r.call(n,e);a||(e=ke(e),a=r.call(n,e));const s=l.call(n,e);return n.set(e,t),a?(0,o.aU)(t,s)&&F(n,"set",e,t):F(n,"add",e,t),this}function W(e){const t=ke(this),{has:n,get:o}=z(t);let r=n.call(t,e);r||(e=ke(e),r=n.call(t,e)),o&&o.call(t,e);const l=t.delete(e);return r&&F(t,"delete",e,void 0),l}function G(){const e=ke(this),t=0!==e.size,n=e.clear();return t&&F(e,"clear",void 0,void 0),n}function K(e,t){return function(n,o){const r=this,l=r.__v_raw,a=ke(l),s=t?B:e?Ce:Se;return!e&&A(a,0,I),l.forEach(((e,t)=>n.call(o,s(e),s(t),r)))}}function X(e,t,n){return function(...r){const l=this.__v_raw,a=ke(l),s=(0,o._N)(a),i="entries"===e||e===Symbol.iterator&&s,c="keys"===e&&s,u=l[e](...r),p=n?B:t?Ce:Se;return!t&&A(a,0,c?E:I),{next(){const{value:e,done:t}=u.next();return t?{value:e,done:t}:{value:i?[p(e[0]),p(e[1])]:p(e),done:t}},[Symbol.iterator](){return this}}}}function Q(e){return function(...t){return"delete"!==e&&("clear"===e?void 0:this)}}function ee(){const e={get(e){return U(this,e)},get size(){return Z(this)},has:q,add:J,set:Y,delete:W,clear:G,forEach:K(!1,!1)},t={get(e){return U(this,e,!1,!0)},get size(){return Z(this)},has:q,add:J,set:Y,delete:W,clear:G,forEach:K(!1,!0)},n={get(e){return U(this,e,!0)},get size(){return Z(this,!0)},has(e){return q.call(this,e,!0)},add:Q("add"),set:Q("set"),delete:Q("delete"),clear:Q("clear"),forEach:K(!0,!1)},o={get(e){return U(this,e,!0,!0)},get size(){return Z(this,!0)},has(e){return q.call(this,e,!0)},add:Q("add"),set:Q("set"),delete:Q("delete"),clear:Q("clear"),forEach:K(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach((r=>{e[r]=X(r,!1,!1),n[r]=X(r,!0,!1),t[r]=X(r,!1,!0),o[r]=X(r,!0,!0)})),[e,n,t,o]}const[te,ne,oe,re]=ee();function le(e,t){const n=t?e?re:oe:e?ne:te;return(t,r,l)=>"__v_isReactive"===r?!e:"__v_isReadonly"===r?e:"__v_raw"===r?t:Reflect.get((0,o.RI)(n,r)&&r in t?n:t,r,l)}const ae={get:le(!1,!1)},se={get:le(!1,!0)},ie={get:le(!0,!1)},ce=new WeakMap,ue=new WeakMap,pe=new WeakMap,de=new WeakMap;function he(e){return ye(e)?e:me(e,!1,D,ae,ce)}function fe(e){return me(e,!1,V,se,ue)}function ve(e){return me(e,!0,j,ie,pe)}function me(e,t,n,r,l){if(!(0,o.Kn)(e))return e;if(e.__v_raw&&(!t||!e.__v_isReactive))return e;const a=l.get(e);if(a)return a;const s=(i=e).__v_skip||!Object.isExtensible(i)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((0,o.W7)(i));var i;if(0===s)return e;const c=new Proxy(e,2===s?r:n);return l.set(e,c),c}function ge(e){return ye(e)?ge(e.__v_raw):!(!e||!e.__v_isReactive)}function ye(e){return!(!e||!e.__v_isReadonly)}function be(e){return!(!e||!e.__v_isShallow)}function we(e){return ge(e)||ye(e)}function ke(e){const t=e&&e.__v_raw;return t?ke(t):e}function _e(e){return(0,o.Nj)(e,"__v_skip",!0),e}const Se=e=>(0,o.Kn)(e)?he(e):e,Ce=e=>(0,o.Kn)(e)?ve(e):e;class xe{constructor(e,t,n,o){this._setter=t,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new c((()=>e(this._value)),(()=>Ee(this,1)),(()=>this.dep&&C(this.dep))),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=n}get value(){const e=ke(this);return e._cacheable&&!e.effect.dirty||(0,o.aU)(e._value,e._value=e.effect.run())&&Ee(e,2),Ie(e),e.effect._dirtyLevel>=1&&Ee(e,1),e._value}set value(e){this._setter(e)}get _dirty(){return this.effect.dirty}set _dirty(e){this.effect.dirty=e}}function Te(e,t,n=!1){let r,l;const a=(0,o.mf)(e);return a?(r=e,l=o.dG):(r=e.get,l=e.set),new xe(r,l,a||!l,n)}function Ie(e){f&&l&&(e=ke(e),k(l,e.dep||(e.dep=x((()=>e.dep=void 0),e instanceof xe?e:void 0))))}function Ee(e,t=2,n){const o=(e=ke(e)).dep;o&&S(o,t)}function Ae(e){return!(!e||!0!==e.__v_isRef)}function Fe(e){return Oe(e,!1)}function Le(e){return Oe(e,!0)}function Oe(e,t){return Ae(e)?e:new Me(e,t)}class Me{constructor(e,t){this.__v_isShallow=t,this.dep=void 0,this.__v_isRef=!0,this._rawValue=t?e:ke(e),this._value=t?e:Se(e)}get value(){return Ie(this),this._value}set value(e){const t=this.__v_isShallow||be(e)||ye(e);e=t?e:ke(e),(0,o.aU)(e,this._rawValue)&&(this._rawValue=e,this._value=t?e:Se(e),Ee(this,2))}}function Pe(e){return Ae(e)?e.value:e}const Re={get:(e,t,n)=>Pe(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const r=e[t];return Ae(r)&&!Ae(n)?(r.value=n,!0):Reflect.set(e,t,n,o)}};function He(e){return ge(e)?e:new Proxy(e,Re)}class $e{constructor(e){this.dep=void 0,this.__v_isRef=!0;const{get:t,set:n}=e((()=>Ie(this)),(()=>Ee(this)));this._get=t,this._set=n}get value(){return this._get()}set value(e){this._set(e)}}function Ne(e){return new $e(e)}class De{constructor(e,t,n){this._object=e,this._key=t,this._defaultValue=n,this.__v_isRef=!0}get value(){const e=this._object[this._key];return void 0===e?this._defaultValue:e}set value(e){this._object[this._key]=e}get dep(){return e=ke(this._object),t=this._key,null==(n=T.get(e))?void 0:n.get(t);var e,t,n}}class je{constructor(e){this._getter=e,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Ve(e,t,n){return Ae(e)?e:(0,o.mf)(e)?new je(e):(0,o.Kn)(e)&&arguments.length>1?function(e,t,n){const o=e[t];return Ae(o)?o:new De(e,t,n)}(e,t,n):Fe(e)}},6252:(e,t,n)=>{n.d(t,{$d:()=>u,Ah:()=>Ae,Eo:()=>St,FN:()=>rn,Fl:()=>kn,HY:()=>Ft,JJ:()=>et,Jd:()=>Ee,P$:()=>ae,Q6:()=>de,RC:()=>ve,U2:()=>ie,Uk:()=>Wt,Us:()=>_t,Wm:()=>Jt,Y3:()=>k,Y8:()=>oe,YP:()=>W,_:()=>Zt,aZ:()=>he,bv:()=>xe,f3:()=>tt,h:()=>_n,iD:()=>jt,ic:()=>Ie,m0:()=>J,nJ:()=>le,nK:()=>pe,uE:()=>Gt,up:()=>V,w5:()=>R,wg:()=>Ht});var o=n(2262),r=n(3577);const l=[];function a(e,...t){(0,o.Jd)();const n=l.length?l[l.length-1].component:null,r=n&&n.appContext.config.warnHandler,a=function(){let e=l[l.length-1];if(!e)return[];const t=[];for(;e;){const n=t[0];n&&n.vnode===e?n.recurseCount++:t.push({vnode:e,recurseCount:0});const o=e.component&&e.component.parent;e=o&&o.vnode}return t}();if(r)c(r,n,11,[e+t.join(""),n&&n.proxy,a.map((({vnode:e})=>`at <${wn(n,e.type)}>`)).join("\n"),a]);else{const n=[`[Vue warn]: ${e}`,...t];a.length&&n.push("\n",...function(e){const t=[];return e.forEach(((e,n)=>{t.push(...0===n?[]:["\n"],...function({vnode:e,recurseCount:t}){const n=t>0?`... (${t} recursive calls)`:"",o=!!e.component&&null==e.component.parent,r=` at <${wn(e.component,e.type,o)}`,l=">"+n;return e.props?[r,...s(e.props),l]:[r+l]}(e))})),t}(a)),console.warn(...n)}(0,o.lk)()}function s(e){const t=[],n=Object.keys(e);return n.slice(0,3).forEach((n=>{t.push(...i(n,e[n]))})),n.length>3&&t.push(" ..."),t}function i(e,t,n){return(0,r.HD)(t)?(t=JSON.stringify(t),n?t:[`${e}=${t}`]):"number"==typeof t||"boolean"==typeof t||null==t?n?t:[`${e}=${t}`]:(0,o.dq)(t)?(t=i(e,(0,o.IU)(t.value),!0),n?t:[`${e}=Ref<`,t,">"]):(0,r.mf)(t)?[`${e}=fn${t.name?`<${t.name}>`:""}`]:(t=(0,o.IU)(t),n?t:[`${e}=`,t])}function c(e,t,n,o){let r;try{r=o?e(...o):e()}catch(e){p(e,t,n)}return r}function u(e,t,n,o){if((0,r.mf)(e)){const l=c(e,t,n,o);return l&&(0,r.tI)(l)&&l.catch((e=>{p(e,t,n)})),l}const l=[];for(let r=0;r>>1,r=f[o],l=T(r);lT(e)-T(t)));if(m.length=0,g)return void g.push(...e);for(g=e,y=0;ynull==e.id?1/0:e.id,I=(e,t)=>{const n=T(e)-T(t);if(0===n){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function E(e){h=!1,d=!0,f.sort(I),r.dG;try{for(v=0;v(0,r.HD)(e)?e.trim():e))),t&&(l=n.map(r.h5))}let i,c=o[i=(0,r.hR)(t)]||o[i=(0,r.hR)((0,r._A)(t))];!c&&a&&(c=o[i=(0,r.hR)((0,r.rs)(t))]),c&&u(c,e,6,l);const p=o[i+"Once"];if(p){if(e.emitted){if(e.emitted[i])return}else e.emitted={};e.emitted[i]=!0,u(p,e,6,l)}}function F(e,t,n=!1){const o=t.emitsCache,l=o.get(e);if(void 0!==l)return l;const a=e.emits;let s={},i=!1;if(!(0,r.mf)(e)){const o=e=>{const n=F(e,t,!0);n&&(i=!0,(0,r.l7)(s,n))};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}return a||i?((0,r.kJ)(a)?a.forEach((e=>s[e]=null)):(0,r.l7)(s,a),(0,r.Kn)(e)&&o.set(e,s),s):((0,r.Kn)(e)&&o.set(e,null),null)}function L(e,t){return!(!e||!(0,r.F7)(t))&&(t=t.slice(2).replace(/Once$/,""),(0,r.RI)(e,t[0].toLowerCase()+t.slice(1))||(0,r.RI)(e,(0,r.rs)(t))||(0,r.RI)(e,t))}let O=null,M=null;function P(e){const t=O;return O=e,M=e&&e.type.__scopeId||null,t}function R(e,t=O,n){if(!t)return e;if(e._n)return e;const o=(...n)=>{o._d&&Nt(-1);const r=P(t);let l;try{l=e(...n)}finally{P(r),o._d&&Nt(1)}return l};return o._n=!0,o._c=!0,o._d=!0,o}function H(e){const{type:t,vnode:n,proxy:o,withProxy:l,props:a,propsOptions:[s],slots:i,attrs:c,emit:u,render:d,renderCache:h,data:f,setupState:v,ctx:m,inheritAttrs:g}=e;let y,b;const w=P(e);try{if(4&n.shapeFlag){const e=l||o,t=e;y=Kt(d.call(t,e,h,a,v,f,m)),b=c}else{const e=t;y=Kt(e.length>1?e(a,{attrs:c,slots:i,emit:u}):e(a,null)),b=t.props?c:$(c)}}catch(t){Pt.length=0,p(t,e,1),y=Jt(Ot)}let k=y;if(b&&!1!==g){const e=Object.keys(b),{shapeFlag:t}=k;e.length&&7&t&&(s&&e.some(r.tR)&&(b=N(b,s)),k=Yt(k,b))}return n.dirs&&(k=Yt(k),k.dirs=k.dirs?k.dirs.concat(n.dirs):n.dirs),n.transition&&(k.transition=n.transition),y=k,P(w),y}const $=e=>{let t;for(const n in e)("class"===n||"style"===n||(0,r.F7)(n))&&((t||(t={}))[n]=e[n]);return t},N=(e,t)=>{const n={};for(const o in e)(0,r.tR)(o)&&o.slice(9)in t||(n[o]=e[o]);return n};function D(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let r=0;rtt(q);function J(e,t){return G(e,null,t)}const Y={};function W(e,t,n){return G(e,t,n)}function G(e,t,{immediate:n,deep:l,flush:a,once:s,onTrack:i,onTrigger:p}=r.kT){if(t&&s){const e=t;t=(...t)=>{e(...t),T()}}const d=on,h=e=>!0===l?e:Q(e,!1===l?1:void 0);let f,v,m=!1,g=!1;if((0,o.dq)(e)?(f=()=>e.value,m=(0,o.yT)(e)):(0,o.PG)(e)?(f=()=>h(e),m=!0):(0,r.kJ)(e)?(g=!0,m=e.some((e=>(0,o.PG)(e)||(0,o.yT)(e))),f=()=>e.map((e=>(0,o.dq)(e)?e.value:(0,o.PG)(e)?h(e):(0,r.mf)(e)?c(e,d,2):void 0))):f=(0,r.mf)(e)?t?()=>c(e,d,2):()=>(v&&v(),u(e,d,3,[b])):r.dG,t&&l){const e=f;f=()=>Q(e())}let y,b=e=>{v=C.onStop=()=>{c(e,d,4),v=C.onStop=void 0}};if(hn){if(b=r.dG,t?n&&u(t,d,3,[f(),g?[]:void 0,b]):f(),"sync"!==a)return r.dG;{const e=Z();y=e.__watcherHandles||(e.__watcherHandles=[])}}let w=g?new Array(e.length).fill(Y):Y;const k=()=>{if(C.active&&C.dirty)if(t){const e=C.run();(l||m||(g?e.some(((e,t)=>(0,r.aU)(e,w[t]))):(0,r.aU)(e,w)))&&(v&&v(),u(t,d,3,[e,w===Y?void 0:g&&w[0]===Y?[]:w,b]),w=e)}else C.run()};let S;k.allowRecurse=!!t,"sync"===a?S=k:"post"===a?S=()=>kt(k,d&&d.suspense):(k.pre=!0,d&&(k.id=d.uid),S=()=>_(k));const C=new o.qq(f,r.dG,S),x=(0,o.nZ)(),T=()=>{C.stop(),x&&(0,r.Od)(x.effects,C)};return t?n?k():w=C.run():"post"===a?kt(C.run.bind(C),d&&d.suspense):C.run(),y&&y.push(T),T}function K(e,t,n){const o=this.proxy,l=(0,r.HD)(e)?e.includes(".")?X(o,e):()=>o[e]:e.bind(o,o);let a;(0,r.mf)(t)?a=t:(a=t.handler,n=t);const s=sn(this),i=G(l,a.bind(o),n);return s(),i}function X(e,t){const n=t.split(".");return()=>{let t=e;for(let e=0;e0){if(n>=t)return e;n++}if((l=l||new Set).has(e))return e;if(l.add(e),(0,o.dq)(e))Q(e.value,t,n,l);else if((0,r.kJ)(e))for(let o=0;o{Q(e,t,n,l)}));else if((0,r.PO)(e))for(const o in e)Q(e[o],t,n,l);return e}function ee(e,t,n,r){const l=e.dirs,a=t&&t.dirs;for(let s=0;s{e.isMounted=!0})),Ee((()=>{e.isUnmounting=!0})),e}const re=[Function,Array],le={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:re,onEnter:re,onAfterEnter:re,onEnterCancelled:re,onBeforeLeave:re,onLeave:re,onAfterLeave:re,onLeaveCancelled:re,onBeforeAppear:re,onAppear:re,onAfterAppear:re,onAppearCancelled:re},ae={name:"BaseTransition",props:le,setup(e,{slots:t}){const n=rn(),r=oe();let l;return()=>{const a=t.default&&de(t.default(),!0);if(!a||!a.length)return;let s=a[0];if(a.length>1){let e=!1;for(const t of a)if(t.type!==Ot){s=t,e=!0;break}}const i=(0,o.IU)(e),{mode:c}=i;if(r.isLeaving)return ce(s);const u=ue(s);if(!u)return ce(s);const p=ie(u,i,r,n);pe(u,p);const d=n.subTree,h=d&&ue(d);let f=!1;const{getTransitionKey:v}=u.type;if(v){const e=v();void 0===l?l=e:e!==l&&(l=e,f=!0)}if(h&&h.type!==Ot&&(!Bt(u,h)||f)){const e=ie(h,i,r,n);if(pe(h,e),"out-in"===c)return r.isLeaving=!0,e.afterLeave=()=>{r.isLeaving=!1,!1!==n.update.active&&(n.effect.dirty=!0,n.update())},ce(s);"in-out"===c&&u.type!==Ot&&(e.delayLeave=(e,t,n)=>{se(r,h)[String(h.key)]=h,e[te]=()=>{t(),e[te]=void 0,delete p.delayedLeave},p.delayedLeave=n})}return s}}};function se(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function ie(e,t,n,o){const{appear:l,mode:a,persisted:s=!1,onBeforeEnter:i,onEnter:c,onAfterEnter:p,onEnterCancelled:d,onBeforeLeave:h,onLeave:f,onAfterLeave:v,onLeaveCancelled:m,onBeforeAppear:g,onAppear:y,onAfterAppear:b,onAppearCancelled:w}=t,k=String(e.key),_=se(n,e),S=(e,t)=>{e&&u(e,o,9,t)},C=(e,t)=>{const n=t[1];S(e,t),(0,r.kJ)(e)?e.every((e=>e.length<=1))&&n():e.length<=1&&n()},x={mode:a,persisted:s,beforeEnter(t){let o=i;if(!n.isMounted){if(!l)return;o=g||i}t[te]&&t[te](!0);const r=_[k];r&&Bt(e,r)&&r.el[te]&&r.el[te](),S(o,[t])},enter(e){let t=c,o=p,r=d;if(!n.isMounted){if(!l)return;t=y||c,o=b||p,r=w||d}let a=!1;const s=e[ne]=t=>{a||(a=!0,S(t?r:o,[e]),x.delayedLeave&&x.delayedLeave(),e[ne]=void 0)};t?C(t,[e,s]):s()},leave(t,o){const r=String(e.key);if(t[ne]&&t[ne](!0),n.isUnmounting)return o();S(h,[t]);let l=!1;const a=t[te]=n=>{l||(l=!0,o(),S(n?m:v,[t]),t[te]=void 0,_[r]===e&&delete _[r])};_[r]=e,f?C(f,[t,a]):a()},clone:e=>ie(e,t,n,o)};return x}function ce(e){if(ge(e))return(e=Yt(e)).children=null,e}function ue(e){return ge(e)?e.children?e.children[0]:void 0:e}function pe(e,t){6&e.shapeFlag&&e.component?pe(e.component.subTree,t):128&e.shapeFlag?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function de(e,t=!1,n){let o=[],r=0;for(let l=0;l1)for(let e=0;e(0,r.l7)({name:e.name},t,{setup:e}))():e}const fe=e=>!!e.type.__asyncLoader;function ve(e){(0,r.mf)(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:l,delay:a=200,timeout:s,suspensible:i=!0,onError:c}=e;let u,d=null,h=0;const f=()=>{let e;return d||(e=d=t().catch((e=>{if(e=e instanceof Error?e:new Error(String(e)),c)return new Promise(((t,n)=>{c(e,(()=>t((h++,d=null,f()))),(()=>n(e)),h+1)}));throw e})).then((t=>e!==d&&d?d:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),u=t,t))))};return he({name:"AsyncComponentWrapper",__asyncLoader:f,get __asyncResolved(){return u},setup(){const e=on;if(u)return()=>me(u,e);const t=t=>{d=null,p(t,e,13,!l)};if(i&&e.suspense||hn)return f().then((t=>()=>me(t,e))).catch((e=>(t(e),()=>l?Jt(l,{error:e}):null)));const r=(0,o.iH)(!1),c=(0,o.iH)(),h=(0,o.iH)(!!a);return a&&setTimeout((()=>{h.value=!1}),a),null!=s&&setTimeout((()=>{if(!r.value&&!c.value){const e=new Error(`Async component timed out after ${s}ms.`);t(e),c.value=e}}),s),f().then((()=>{r.value=!0,e.parent&&ge(e.parent.vnode)&&(e.parent.effect.dirty=!0,_(e.parent.update))})).catch((e=>{t(e),c.value=e})),()=>r.value&&u?me(u,e):c.value&&l?Jt(l,{error:c.value}):n&&!h.value?Jt(n):void 0}})}function me(e,t){const{ref:n,props:o,children:r,ce:l}=t.vnode,a=Jt(e,o,r);return a.ref=n,a.ce=l,delete t.vnode.ce,a}const ge=e=>e.type.__isKeepAlive;function ye(e,t){we(e,"a",t)}function be(e,t){we(e,"da",t)}function we(e,t,n=on){const o=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()});if(_e(t,o,n),n){let e=n.parent;for(;e&&e.parent;)ge(e.parent.vnode)&&ke(o,t,n,e),e=e.parent}}function ke(e,t,n,o){const l=_e(t,e,o,!0);Ae((()=>{(0,r.Od)(o[t],l)}),n)}function _e(e,t,n=on,r=!1){if(n){const l=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...r)=>{if(n.isUnmounted)return;(0,o.Jd)();const l=sn(n),a=u(t,n,e,r);return l(),(0,o.lk)(),a});return r?l.unshift(a):l.push(a),a}}RegExp,RegExp;const Se=e=>(t,n=on)=>(!hn||"sp"===e)&&_e(e,((...e)=>t(...e)),n),Ce=Se("bm"),xe=Se("m"),Te=Se("bu"),Ie=Se("u"),Ee=Se("bum"),Ae=Se("um"),Fe=Se("sp"),Le=Se("rtg"),Oe=Se("rtc");function Me(e,t=on){_e("ec",e,t)}const Pe=e=>e?un(e)?mn(e)||e.proxy:Pe(e.parent):null,Re=(0,r.l7)(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Pe(e.parent),$root:e=>Pe(e.root),$emit:e=>e.emit,$options:e=>Be(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,_(e.update)}),$nextTick:e=>e.n||(e.n=k.bind(e.proxy)),$watch:e=>K.bind(e)}),He=(e,t)=>e!==r.kT&&!e.__isScriptSetup&&(0,r.RI)(e,t),$e={get({_:e},t){const{ctx:n,setupState:l,data:a,props:s,accessCache:i,type:c,appContext:u}=e;let p;if("$"!==t[0]){const o=i[t];if(void 0!==o)switch(o){case 1:return l[t];case 2:return a[t];case 4:return n[t];case 3:return s[t]}else{if(He(l,t))return i[t]=1,l[t];if(a!==r.kT&&(0,r.RI)(a,t))return i[t]=2,a[t];if((p=e.propsOptions[0])&&(0,r.RI)(p,t))return i[t]=3,s[t];if(n!==r.kT&&(0,r.RI)(n,t))return i[t]=4,n[t];De&&(i[t]=0)}}const d=Re[t];let h,f;return d?("$attrs"===t&&(0,o.j)(e,"get",t),d(e)):(h=c.__cssModules)&&(h=h[t])?h:n!==r.kT&&(0,r.RI)(n,t)?(i[t]=4,n[t]):(f=u.config.globalProperties,(0,r.RI)(f,t)?f[t]:void 0)},set({_:e},t,n){const{data:o,setupState:l,ctx:a}=e;return He(l,t)?(l[t]=n,!0):o!==r.kT&&(0,r.RI)(o,t)?(o[t]=n,!0):!((0,r.RI)(e.props,t)||"$"===t[0]&&t.slice(1)in e||(a[t]=n,0))},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:l,propsOptions:a}},s){let i;return!!n[s]||e!==r.kT&&(0,r.RI)(e,s)||He(t,s)||(i=a[0])&&(0,r.RI)(i,s)||(0,r.RI)(o,s)||(0,r.RI)(Re,s)||(0,r.RI)(l.config.globalProperties,s)},defineProperty(e,t,n){return null!=n.get?e._.accessCache[t]=0:(0,r.RI)(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Ne(e){return(0,r.kJ)(e)?e.reduce(((e,t)=>(e[t]=null,e)),{}):e}let De=!0;function je(e,t,n){u((0,r.kJ)(e)?e.map((e=>e.bind(t.proxy))):e.bind(t.proxy),t,n)}function Ve(e,t,n,o){const l=o.includes(".")?X(n,o):()=>n[o];if((0,r.HD)(e)){const n=t[e];(0,r.mf)(n)&&W(l,n)}else if((0,r.mf)(e))W(l,e.bind(n));else if((0,r.Kn)(e))if((0,r.kJ)(e))e.forEach((e=>Ve(e,t,n,o)));else{const o=(0,r.mf)(e.handler)?e.handler.bind(n):t[e.handler];(0,r.mf)(o)&&W(l,o,e)}}function Be(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:l,optionsCache:a,config:{optionMergeStrategies:s}}=e.appContext,i=a.get(t);let c;return i?c=i:l.length||n||o?(c={},l.length&&l.forEach((e=>ze(c,e,s,!0))),ze(c,t,s)):c=t,(0,r.Kn)(t)&&a.set(t,c),c}function ze(e,t,n,o=!1){const{mixins:r,extends:l}=t;l&&ze(e,l,n,!0),r&&r.forEach((t=>ze(e,t,n,!0)));for(const r in t)if(o&&"expose"===r);else{const o=Ue[r]||n&&n[r];e[r]=o?o(e[r],t[r]):t[r]}return e}const Ue={data:qe,props:We,emits:We,methods:Ye,computed:Ye,beforeCreate:Je,created:Je,beforeMount:Je,mounted:Je,beforeUpdate:Je,updated:Je,beforeDestroy:Je,beforeUnmount:Je,destroyed:Je,unmounted:Je,activated:Je,deactivated:Je,errorCaptured:Je,serverPrefetch:Je,components:Ye,directives:Ye,watch:function(e,t){if(!e)return t;if(!t)return e;const n=(0,r.l7)(Object.create(null),e);for(const o in t)n[o]=Je(e[o],t[o]);return n},provide:qe,inject:function(e,t){return Ye(Ze(e),Ze(t))}};function qe(e,t){return t?e?function(){return(0,r.l7)((0,r.mf)(e)?e.call(this,this):e,(0,r.mf)(t)?t.call(this,this):t)}:t:e}function Ze(e){if((0,r.kJ)(e)){const t={};for(let n=0;n(a.has(e)||(e&&(0,r.mf)(e.install)?(a.add(e),e.install(i,...t)):(0,r.mf)(e)&&(a.add(e),e(i,...t))),i),mixin:e=>(l.mixins.includes(e)||l.mixins.push(e),i),component:(e,t)=>t?(l.components[e]=t,i):l.components[e],directive:(e,t)=>t?(l.directives[e]=t,i):l.directives[e],mount(r,a,c){if(!s){const u=Jt(n,o);return u.appContext=l,!0===c?c="svg":!1===c&&(c=void 0),a&&t?t(u,r):e(u,r,c),s=!0,i._container=r,r.__vue_app__=i,mn(u.component)||u.component.proxy}},unmount(){s&&(e(null,i._container),delete i._container.__vue_app__)},provide:(e,t)=>(l.provides[e]=t,i),runWithContext(e){Qe=i;try{return e()}finally{Qe=null}}};return i}}let Qe=null;function et(e,t){if(on){let n=on.provides;const o=on.parent&&on.parent.provides;o===n&&(n=on.provides=Object.create(o)),n[e]=t}}function tt(e,t,n=!1){const o=on||O;if(o||Qe){const l=o?null==o.parent?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides:Qe._context.provides;if(l&&e in l)return l[e];if(arguments.length>1)return n&&(0,r.mf)(t)?t.call(o&&o.proxy):t}}function nt(e,t,n,l){const[a,s]=e.propsOptions;let i,c=!1;if(t)for(let o in t){if((0,r.Gg)(o))continue;const u=t[o];let p;a&&(0,r.RI)(a,p=(0,r._A)(o))?s&&s.includes(p)?(i||(i={}))[p]=u:n[p]=u:L(e.emitsOptions,o)||o in l&&u===l[o]||(l[o]=u,c=!0)}if(s){const t=(0,o.IU)(n),l=i||r.kT;for(let o=0;o{c=!0;const[n,o]=rt(e,t,!0);(0,r.l7)(s,n),o&&i.push(...o)};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}if(!a&&!c)return(0,r.Kn)(e)&&o.set(e,r.Z6),r.Z6;if((0,r.kJ)(a))for(let e=0;e-1,o[1]=n<0||e-1||(0,r.RI)(o,"default"))&&i.push(t)}}}const u=[s,i];return(0,r.Kn)(e)&&o.set(e,u),u}function lt(e){return"$"!==e[0]}function at(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:null===e?"null":""}function st(e,t){return at(e)===at(t)}function it(e,t){return(0,r.kJ)(t)?t.findIndex((t=>st(t,e))):(0,r.mf)(t)&&st(t,e)?0:-1}const ct=e=>"_"===e[0]||"$stable"===e,ut=e=>(0,r.kJ)(e)?e.map(Kt):[Kt(e)],pt=(e,t,n)=>{if(t._n)return t;const o=R(((...e)=>ut(t(...e))),n);return o._c=!1,o},dt=(e,t,n)=>{const o=e._ctx;for(const n in e){if(ct(n))continue;const l=e[n];if((0,r.mf)(l))t[n]=pt(0,l,o);else if(null!=l){const e=ut(l);t[n]=()=>e}}},ht=(e,t)=>{const n=ut(t);e.slots.default=()=>n},ft=(e,t)=>{if(32&e.vnode.shapeFlag){const n=t._;n?(e.slots=(0,o.IU)(t),(0,r.Nj)(t,"_",n)):dt(t,e.slots={})}else e.slots={},t&&ht(e,t);(0,r.Nj)(e.slots,zt,1)},vt=(e,t,n)=>{const{vnode:o,slots:l}=e;let a=!0,s=r.kT;if(32&o.shapeFlag){const e=t._;e?n&&1===e?a=!1:((0,r.l7)(l,t),n||1!==e||delete l._):(a=!t.$stable,dt(t,l)),s=t}else t&&(ht(e,t),s={default:1});if(a)for(const e in l)ct(e)||null!=s[e]||delete l[e]};function mt(e,t,n,l,a=!1){if((0,r.kJ)(e))return void e.forEach(((e,o)=>mt(e,t&&((0,r.kJ)(t)?t[o]:t),n,l,a)));if(fe(l)&&!a)return;const s=4&l.shapeFlag?mn(l.component)||l.component.proxy:l.el,i=a?null:s,{i:u,r:p}=e,d=t&&t.r,h=u.refs===r.kT?u.refs={}:u.refs,f=u.setupState;if(null!=d&&d!==p&&((0,r.HD)(d)?(h[d]=null,(0,r.RI)(f,d)&&(f[d]=null)):(0,o.dq)(d)&&(d.value=null)),(0,r.mf)(p))c(p,u,12,[i,h]);else{const t=(0,r.HD)(p),l=(0,o.dq)(p),c=e.f;if(t||l){const o=()=>{if(c){const n=t?(0,r.RI)(f,p)?f[p]:h[p]:p.value;a?(0,r.kJ)(n)&&(0,r.Od)(n,s):(0,r.kJ)(n)?n.includes(s)||n.push(s):t?(h[p]=[s],(0,r.RI)(f,p)&&(f[p]=h[p])):(p.value=[s],e.k&&(h[e.k]=p.value))}else t?(h[p]=i,(0,r.RI)(f,p)&&(f[p]=i)):l&&(p.value=i,e.k&&(h[e.k]=i))};a||c?o():(o.id=-1,kt(o,n))}}}let gt=!1;const yt=e=>(e=>e.namespaceURI.includes("svg")&&"foreignObject"!==e.tagName)(e)?"svg":(e=>e.namespaceURI.includes("MathML"))(e)?"mathml":void 0,bt=e=>8===e.nodeType;function wt(e){const{mt:t,p:n,o:{patchProp:o,createText:l,nextSibling:s,parentNode:i,remove:c,insert:u,createComment:p}}=e,d=(n,o,r,c,p,w=!1)=>{const k=bt(n)&&"["===n.data,_=()=>m(n,o,r,c,p,k),{type:S,ref:C,shapeFlag:x,patchFlag:T}=o;let I=n.nodeType;o.el=n,-2===T&&(w=!1,o.dynamicChildren=null);let E=null;switch(S){case Lt:3!==I?""===o.children?(u(o.el=l(""),i(n),n),E=n):E=_():(n.data!==o.children&&(gt=!0,__VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&a("Hydration text mismatch in",n.parentNode,`\n - rendered on server: ${JSON.stringify(n.data)}\n - expected on client: ${JSON.stringify(o.children)}`),n.data=o.children),E=s(n));break;case Ot:b(n)?(E=s(n),y(o.el=n.content.firstChild,n,r)):E=8!==I||k?_():s(n);break;case Mt:if(k&&(I=(n=s(n)).nodeType),1===I||3===I){E=n;const e=!o.children.length;for(let t=0;t{i=i||!!t.dynamicChildren;const{type:u,props:p,patchFlag:d,shapeFlag:h,dirs:v,transition:m}=t,g="input"===u||"option"===u;if(g||-1!==d){v&&ee(t,null,n,"created");let u,w=!1;if(b(e)){w=It(l,m)&&n&&n.vnode.props&&n.vnode.props.appear;const o=e.content.firstChild;w&&m.beforeEnter(o),y(o,e,n),t.el=e=o}if(16&h&&(!p||!p.innerHTML&&!p.textContent)){let o=f(e.firstChild,t,e,n,l,s,i),r=!1;for(;o;){gt=!0,__VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&!r&&(a("Hydration children mismatch on",e,"\nServer rendered element contains more child nodes than client vdom."),r=!0);const t=o;o=o.nextSibling,c(t)}}else 8&h&&e.textContent!==t.children&&(gt=!0,__VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&a("Hydration text content mismatch on",e,`\n - rendered on server: ${e.textContent}\n - expected on client: ${t.children}`),e.textContent=t.children);if(p)if(g||!i||48&d)for(const t in p)(g&&(t.endsWith("value")||"indeterminate"===t)||(0,r.F7)(t)&&!(0,r.Gg)(t)||"."===t[0])&&o(e,t,null,p[t],void 0,void 0,n);else p.onClick&&o(e,"onClick",null,p.onClick,void 0,void 0,n);(u=p&&p.onVnodeBeforeMount)&&en(u,n,t),v&&ee(t,null,n,"beforeMount"),((u=p&&p.onVnodeMounted)||v||w)&&U((()=>{u&&en(u,n,t),w&&m.enter(e),v&&ee(t,null,n,"mounted")}),l)}return e.nextSibling},f=(e,t,o,r,l,s,i)=>{i=i||!!t.dynamicChildren;const c=t.children,u=c.length;let p=!1;for(let t=0;t{const{slotScopeIds:a}=t;a&&(r=r?r.concat(a):a);const c=i(e),d=f(s(e),t,c,n,o,r,l);return d&&bt(d)&&"]"===d.data?s(t.anchor=d):(gt=!0,u(t.anchor=p("]"),c,d),d)},m=(e,t,o,r,l,u)=>{if(gt=!0,__VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&a("Hydration node mismatch:\n- rendered on server:",e,3===e.nodeType?"(text)":bt(e)&&"["===e.data?"(start of fragment)":"","\n- expected on client:",t.type),t.el=null,u){const t=g(e);for(;;){const n=s(e);if(!n||n===t)break;c(n)}}const p=s(e),d=i(e);return c(e),n(null,t,d,p,o,r,yt(d),l),p},g=(e,t="[",n="]")=>{let o=0;for(;e;)if((e=s(e))&&bt(e)&&(e.data===t&&o++,e.data===n)){if(0===o)return s(e);o--}return e},y=(e,t,n)=>{const o=t.parentNode;o&&o.replaceChild(e,t);let r=n;for(;r;)r.vnode.el===t&&(r.vnode.el=r.subTree.el=e),r=r.parent},b=e=>1===e.nodeType&&"template"===e.tagName.toLowerCase();return[(e,t)=>{if(!t.hasChildNodes())return __VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&a("Attempting to hydrate existing markup but container is empty. Performing full mount instead."),n(null,e,t),x(),void(t._vnode=e);gt=!1,d(t.firstChild,e,null,null,null),x(),t._vnode=e,gt&&console.error("Hydration completed but contains mismatches.")},d]}const kt=U;function _t(e){return Ct(e)}function St(e){return Ct(e,wt)}function Ct(e,t){"boolean"!=typeof __VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&((0,r.E9)().__VUE_PROD_HYDRATION_MISMATCH_DETAILS__=!1),(0,r.E9)().__VUE__=!0;const{insert:n,remove:l,patchProp:a,createElement:s,createText:i,createComment:u,setText:d,setElementText:h,parentNode:m,nextSibling:g,setScopeId:y=r.dG,insertStaticContent:b}=e,w=(e,t,n,o=null,r=null,l=null,a=void 0,s=null,i=!!t.dynamicChildren)=>{if(e===t)return;e&&!Bt(e,t)&&(o=te(e),W(e,r,l,!0),e=null),-2===t.patchFlag&&(i=!1,t.dynamicChildren=null);const{type:c,ref:u,shapeFlag:p}=t;switch(c){case Lt:k(e,t,n,o);break;case Ot:S(e,t,n,o);break;case Mt:null==e&&T(t,n,o,a);break;case Ft:N(e,t,n,o,r,l,a,s,i);break;default:1&p?I(e,t,n,o,r,l,a,s,i):6&p?j(e,t,n,o,r,l,a,s,i):(64&p||128&p)&&c.process(e,t,n,o,r,l,a,s,i,re)}null!=u&&r&&mt(u,e&&e.ref,l,t||e,!t)},k=(e,t,o,r)=>{if(null==e)n(t.el=i(t.children),o,r);else{const n=t.el=e.el;t.children!==e.children&&d(n,t.children)}},S=(e,t,o,r)=>{null==e?n(t.el=u(t.children||""),o,r):t.el=e.el},T=(e,t,n,o)=>{[e.el,e.anchor]=b(e.children,t,n,o,e.el,e.anchor)},I=(e,t,n,o,r,l,a,s,i)=>{"svg"===t.type?a="svg":"math"===t.type&&(a="mathml"),null==e?E(t,n,o,r,l,a,s,i):P(e,t,r,l,a,s,i)},E=(e,t,o,l,i,c,u,p)=>{let d,f;const{props:v,shapeFlag:m,transition:g,dirs:y}=e;if(d=e.el=s(e.type,c,v&&v.is,v),8&m?h(d,e.children):16&m&&M(e.children,d,null,l,i,xt(e,c),u,p),y&&ee(e,null,l,"created"),O(d,e,e.scopeId,u,l),v){for(const t in v)"value"===t||(0,r.Gg)(t)||a(d,t,null,v[t],c,e.children,l,i,Q);"value"in v&&a(d,"value",null,v.value,c),(f=v.onVnodeBeforeMount)&&en(f,l,e)}y&&ee(e,null,l,"beforeMount");const b=It(i,g);b&&g.beforeEnter(d),n(d,t,o),((f=v&&v.onVnodeMounted)||b||y)&&kt((()=>{f&&en(f,l,e),b&&g.enter(d),y&&ee(e,null,l,"mounted")}),i)},O=(e,t,n,o,r)=>{if(n&&y(e,n),o)for(let t=0;t{for(let c=i;c{const c=t.el=e.el;let{patchFlag:u,dynamicChildren:p,dirs:d}=t;u|=16&e.patchFlag;const f=e.props||r.kT,v=t.props||r.kT;let m;if(n&&Tt(n,!1),(m=v.onVnodeBeforeUpdate)&&en(m,n,t,e),d&&ee(t,e,n,"beforeUpdate"),n&&Tt(n,!0),p?R(e.dynamicChildren,p,c,n,o,xt(t,l),s):i||q(e,t,c,null,n,o,xt(t,l),s,!1),u>0){if(16&u)$(c,t,f,v,n,o,l);else if(2&u&&f.class!==v.class&&a(c,"class",null,v.class,l),4&u&&a(c,"style",f.style,v.style,l),8&u){const r=t.dynamicProps;for(let t=0;t{m&&en(m,n,t,e),d&&ee(t,e,n,"updated")}),o)},R=(e,t,n,o,r,l,a)=>{for(let s=0;s{if(n!==o){if(n!==r.kT)for(const c in n)(0,r.Gg)(c)||c in o||a(e,c,n[c],null,i,t.children,l,s,Q);for(const c in o){if((0,r.Gg)(c))continue;const u=o[c],p=n[c];u!==p&&"value"!==c&&a(e,c,p,u,i,t.children,l,s,Q)}"value"in o&&a(e,"value",n.value,o.value,i)}},N=(e,t,o,r,l,a,s,c,u)=>{const p=t.el=e?e.el:i(""),d=t.anchor=e?e.anchor:i("");let{patchFlag:h,dynamicChildren:f,slotScopeIds:v}=t;v&&(c=c?c.concat(v):v),null==e?(n(p,o,r),n(d,o,r),M(t.children||[],o,d,l,a,s,c,u)):h>0&&64&h&&f&&e.dynamicChildren?(R(e.dynamicChildren,f,o,l,a,s,c),(null!=t.key||l&&t===l.subTree)&&Et(e,t,!0)):q(e,t,o,d,l,a,s,c,u)},j=(e,t,n,o,r,l,a,s,i)=>{t.slotScopeIds=s,null==e?512&t.shapeFlag?r.ctx.activate(t,n,o,a,i):V(t,n,o,r,l,a,i):B(e,t,i)},V=(e,t,n,l,a,s,i)=>{const u=e.component=function(e,t,n){const l=e.type,a=(t?t.appContext:e.appContext)||tn,s={uid:nn++,vnode:e,type:l,parent:t,appContext:a,root:null,next:null,subTree:null,effect:null,update:null,scope:new o.Bj(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(a.provides),accessCache:null,renderCache:[],components:null,directives:null,propsOptions:rt(l,a),emitsOptions:F(l,a),emit:null,emitted:null,propsDefaults:r.kT,inheritAttrs:l.inheritAttrs,ctx:r.kT,data:r.kT,props:r.kT,attrs:r.kT,slots:r.kT,refs:r.kT,setupState:r.kT,setupContext:null,attrsProxy:null,slotsProxy:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return s.ctx={_:s},s.root=t?t.root:s,s.emit=A.bind(null,s),e.ce&&e.ce(s),s}(e,l,a);if(ge(e)&&(u.ctx.renderer=re),function(e,t=!1){t&&an(t);const{props:n,children:l}=e.vnode,a=un(e);!function(e,t,n,l=!1){const a={},s={};(0,r.Nj)(s,zt,1),e.propsDefaults=Object.create(null),nt(e,t,a,s);for(const t in e.propsOptions[0])t in a||(a[t]=void 0);n?e.props=l?a:(0,o.Um)(a):e.type.props?e.props=a:e.props=s,e.attrs=s}(e,n,a,t),ft(e,l);const s=a?function(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=(0,o.Xl)(new Proxy(e.ctx,$e));const{setup:l}=n;if(l){const n=e.setupContext=l.length>1?function(e){const t=t=>{e.exposed=t||{}};return{get attrs(){return function(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get:(t,n)=>((0,o.j)(e,"get","$attrs"),t[n])}))}(e)},slots:e.slots,emit:e.emit,expose:t}}(e):null,a=sn(e);(0,o.Jd)();const s=c(l,e,0,[e.props,n]);if((0,o.lk)(),a(),(0,r.tI)(s)){if(s.then(cn,cn),t)return s.then((n=>{fn(e,n,t)})).catch((t=>{p(t,e,0)}));e.asyncDep=s}else fn(e,s,t)}else vn(e,t)}(e,t):void 0;t&&an(!1)}(u),u.asyncDep){if(a&&a.registerDep(u,z),!e.el){const e=u.subTree=Jt(Ot);S(null,e,t,n)}}else z(u,e,t,n,a,s,i)},B=(e,t,n)=>{const o=t.component=e.component;if(function(e,t,n){const{props:o,children:r,component:l}=e,{props:a,children:s,patchFlag:i}=t,c=l.emitsOptions;if(t.dirs||t.transition)return!0;if(!(n&&i>=0))return!(!r&&!s||s&&s.$stable)||o!==a&&(o?!a||D(o,a,c):!!a);if(1024&i)return!0;if(16&i)return o?D(o,a,c):!!a;if(8&i){const e=t.dynamicProps;for(let t=0;tv&&f.splice(t,1)}(o.update),o.effect.dirty=!0,o.update()}else t.el=e.el,o.vnode=t},z=(e,t,n,l,a,s,i)=>{const c=()=>{if(e.isMounted){let{next:t,bu:n,u:o,parent:l,vnode:u}=e;{const n=At(e);if(n)return t&&(t.el=u.el,U(e,t,i)),void n.asyncDep.then((()=>{e.isUnmounted||c()}))}let p,d=t;Tt(e,!1),t?(t.el=u.el,U(e,t,i)):t=u,n&&(0,r.ir)(n),(p=t.props&&t.props.onVnodeBeforeUpdate)&&en(p,l,t,u),Tt(e,!0);const h=H(e),f=e.subTree;e.subTree=h,w(f,h,m(f.el),te(f),e,a,s),t.el=h.el,null===d&&function({vnode:e,parent:t},n){for(;t;){const o=t.subTree;if(o.suspense&&o.suspense.activeBranch===e&&(o.el=e.el),o!==e)break;(e=t.vnode).el=n,t=t.parent}}(e,h.el),o&&kt(o,a),(p=t.props&&t.props.onVnodeUpdated)&&kt((()=>en(p,l,t,u)),a)}else{let o;const{el:i,props:c}=t,{bm:u,m:p,parent:d}=e,h=fe(t);if(Tt(e,!1),u&&(0,r.ir)(u),!h&&(o=c&&c.onVnodeBeforeMount)&&en(o,d,t),Tt(e,!0),i&&ae){const n=()=>{e.subTree=H(e),ae(i,e.subTree,e,a,null)};h?t.type.__asyncLoader().then((()=>!e.isUnmounted&&n())):n()}else{const o=e.subTree=H(e);w(null,o,n,l,e,a,s),t.el=o.el}if(p&&kt(p,a),!h&&(o=c&&c.onVnodeMounted)){const e=t;kt((()=>en(o,d,e)),a)}(256&t.shapeFlag||d&&fe(d.vnode)&&256&d.vnode.shapeFlag)&&e.a&&kt(e.a,a),e.isMounted=!0,t=n=l=null}},u=e.effect=new o.qq(c,r.dG,(()=>_(p)),e.scope),p=e.update=()=>{u.dirty&&u.run()};p.id=e.uid,Tt(e,!0),p()},U=(e,t,n)=>{t.component=e;const l=e.vnode.props;e.vnode=t,e.next=null,function(e,t,n,l){const{props:a,attrs:s,vnode:{patchFlag:i}}=e,c=(0,o.IU)(a),[u]=e.propsOptions;let p=!1;if(!(l||i>0)||16&i){let o;nt(e,t,a,s)&&(p=!0);for(const l in c)t&&((0,r.RI)(t,l)||(o=(0,r.rs)(l))!==l&&(0,r.RI)(t,o))||(u?!n||void 0===n[l]&&void 0===n[o]||(a[l]=ot(u,c,l,void 0,e,!0)):delete a[l]);if(s!==c)for(const e in s)t&&(0,r.RI)(t,e)||(delete s[e],p=!0)}else if(8&i){const n=e.vnode.dynamicProps;for(let o=0;o{const c=e&&e.children,u=e?e.shapeFlag:0,p=t.children,{patchFlag:d,shapeFlag:f}=t;if(d>0){if(128&d)return void J(c,p,n,o,r,l,a,s,i);if(256&d)return void Z(c,p,n,o,r,l,a,s,i)}8&f?(16&u&&Q(c,r,l),p!==c&&h(n,p)):16&u?16&f?J(c,p,n,o,r,l,a,s,i):Q(c,r,l,!0):(8&u&&h(n,""),16&f&&M(p,n,o,r,l,a,s,i))},Z=(e,t,n,o,l,a,s,i,c)=>{e=e||r.Z6,t=t||r.Z6;const u=e.length,p=t.length,d=Math.min(u,p);let h;for(h=0;hp?Q(e,l,a,!0,!1,d):M(t,n,o,l,a,s,i,c,d)},J=(e,t,n,o,l,a,s,i,c)=>{let u=0;const p=t.length;let d=e.length-1,h=p-1;for(;u<=d&&u<=h;){const o=e[u],r=t[u]=c?Xt(t[u]):Kt(t[u]);if(!Bt(o,r))break;w(o,r,n,null,l,a,s,i,c),u++}for(;u<=d&&u<=h;){const o=e[d],r=t[h]=c?Xt(t[h]):Kt(t[h]);if(!Bt(o,r))break;w(o,r,n,null,l,a,s,i,c),d--,h--}if(u>d){if(u<=h){const e=h+1,r=eh)for(;u<=d;)W(e[u],l,a,!0),u++;else{const f=u,v=u,m=new Map;for(u=v;u<=h;u++){const e=t[u]=c?Xt(t[u]):Kt(t[u]);null!=e.key&&m.set(e.key,u)}let g,y=0;const b=h-v+1;let k=!1,_=0;const S=new Array(b);for(u=0;u=b){W(o,l,a,!0);continue}let r;if(null!=o.key)r=m.get(o.key);else for(g=v;g<=h;g++)if(0===S[g-v]&&Bt(o,t[g])){r=g;break}void 0===r?W(o,l,a,!0):(S[r-v]=u+1,r>=_?_=r:k=!0,w(o,t[r],n,null,l,a,s,i,c),y++)}const C=k?function(e){const t=e.slice(),n=[0];let o,r,l,a,s;const i=e.length;for(o=0;o>1,e[n[s]]0&&(t[o]=n[l-1]),n[l]=o)}}for(l=n.length,a=n[l-1];l-- >0;)n[l]=a,a=t[a];return n}(S):r.Z6;for(g=C.length-1,u=b-1;u>=0;u--){const e=v+u,r=t[e],d=e+1
{const{el:a,type:s,transition:i,children:c,shapeFlag:u}=e;if(6&u)Y(e.component.subTree,t,o,r);else if(128&u)e.suspense.move(t,o,r);else if(64&u)s.move(e,t,o,re);else if(s!==Ft)if(s!==Mt)if(2!==r&&1&u&&i)if(0===r)i.beforeEnter(a),n(a,t,o),kt((()=>i.enter(a)),l);else{const{leave:e,delayLeave:r,afterLeave:l}=i,s=()=>n(a,t,o),c=()=>{e(a,(()=>{s(),l&&l()}))};r?r(a,s,c):c()}else n(a,t,o);else(({el:e,anchor:t},o,r)=>{let l;for(;e&&e!==t;)l=g(e),n(e,o,r),e=l;n(t,o,r)})(e,t,o);else{n(a,t,o);for(let e=0;e{const{type:l,props:a,ref:s,children:i,dynamicChildren:c,shapeFlag:u,patchFlag:p,dirs:d}=e;if(null!=s&&mt(s,null,n,e,!0),256&u)return void t.ctx.deactivate(e);const h=1&u&&d,f=!fe(e);let v;if(f&&(v=a&&a.onVnodeBeforeUnmount)&&en(v,t,e),6&u)X(e.component,n,o);else{if(128&u)return void e.suspense.unmount(n,o);h&&ee(e,null,t,"beforeUnmount"),64&u?e.type.remove(e,t,n,r,re,o):c&&(l!==Ft||p>0&&64&p)?Q(c,t,n,!1,!0):(l===Ft&&384&p||!r&&16&u)&&Q(i,t,n),o&&G(e)}(f&&(v=a&&a.onVnodeUnmounted)||h)&&kt((()=>{v&&en(v,t,e),h&&ee(e,null,t,"unmounted")}),n)},G=e=>{const{type:t,el:n,anchor:o,transition:r}=e;if(t===Ft)return void K(n,o);if(t===Mt)return void(({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=g(e),l(e),e=n;l(t)})(e);const a=()=>{l(n),r&&!r.persisted&&r.afterLeave&&r.afterLeave()};if(1&e.shapeFlag&&r&&!r.persisted){const{leave:t,delayLeave:o}=r,l=()=>t(n,a);o?o(e.el,a,l):l()}else a()},K=(e,t)=>{let n;for(;e!==t;)n=g(e),l(e),e=n;l(t)},X=(e,t,n)=>{const{bum:o,scope:l,update:a,subTree:s,um:i}=e;o&&(0,r.ir)(o),l.stop(),a&&(a.active=!1,W(s,e,t,n)),i&&kt(i,t),kt((()=>{e.isUnmounted=!0}),t),t&&t.pendingBranch&&!t.isUnmounted&&e.asyncDep&&!e.asyncResolved&&e.suspenseId===t.pendingId&&(t.deps--,0===t.deps&&t.resolve())},Q=(e,t,n,o=!1,r=!1,l=0)=>{for(let a=l;a6&e.shapeFlag?te(e.component.subTree):128&e.shapeFlag?e.suspense.next():g(e.anchor||e.el);let ne=!1;const oe=(e,t,n)=>{null==e?t._vnode&&W(t._vnode,null,null,!0):w(t._vnode||null,e,t,null,null,null,n),ne||(ne=!0,C(),x(),ne=!1),t._vnode=e},re={p:w,um:W,m:Y,r:G,mt:V,mc:M,pc:q,pbc:R,n:te,o:e};let le,ae;return t&&([le,ae]=t(re)),{render:oe,hydrate:le,createApp:Xe(oe,le)}}function xt({type:e,props:t},n){return"svg"===n&&"foreignObject"===e||"mathml"===n&&"annotation-xml"===e&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Tt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function It(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Et(e,t,n=!1){const o=e.children,l=t.children;if((0,r.kJ)(o)&&(0,r.kJ)(l))for(let e=0;e0?Rt||r.Z6:null,Pt.pop(),Rt=Pt[Pt.length-1]||null,$t>0&&Rt&&Rt.push(e),e}function jt(e,t,n,o,r,l){return Dt(Zt(e,t,n,o,r,l,!0))}function Vt(e){return!!e&&!0===e.__v_isVNode}function Bt(e,t){return e.type===t.type&&e.key===t.key}const zt="__vInternal",Ut=({key:e})=>null!=e?e:null,qt=({ref:e,ref_key:t,ref_for:n})=>("number"==typeof e&&(e=""+e),null!=e?(0,r.HD)(e)||(0,o.dq)(e)||(0,r.mf)(e)?{i:O,r:e,k:t,f:!!n}:e:null);function Zt(e,t=null,n=null,o=0,l=null,a=(e===Ft?0:1),s=!1,i=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Ut(t),ref:t&&qt(t),scopeId:M,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:a,patchFlag:o,dynamicProps:l,dynamicChildren:null,appContext:null,ctx:O};return i?(Qt(c,n),128&a&&e.normalize(c)):n&&(c.shapeFlag|=(0,r.HD)(n)?8:16),$t>0&&!s&&Rt&&(c.patchFlag>0||6&a)&&32!==c.patchFlag&&Rt.push(c),c}const Jt=function(e,t=null,n=null,l=0,a=null,s=!1){if(e&&e!==B||(e=Ot),Vt(e)){const o=Yt(e,t,!0);return n&&Qt(o,n),$t>0&&!s&&Rt&&(6&o.shapeFlag?Rt[Rt.indexOf(e)]=o:Rt.push(o)),o.patchFlag|=-2,o}if(i=e,(0,r.mf)(i)&&"__vccOpts"in i&&(e=e.__vccOpts),t){t=function(e){return e?(0,o.X3)(e)||zt in e?(0,r.l7)({},e):e:null}(t);let{class:e,style:n}=t;e&&!(0,r.HD)(e)&&(t.class=(0,r.C_)(e)),(0,r.Kn)(n)&&((0,o.X3)(n)&&!(0,r.kJ)(n)&&(n=(0,r.l7)({},n)),t.style=(0,r.j5)(n))}var i;return Zt(e,t,n,l,a,(0,r.HD)(e)?1:(e=>e.__isSuspense)(e)?128:(e=>e.__isTeleport)(e)?64:(0,r.Kn)(e)?4:(0,r.mf)(e)?2:0,s,!0)};function Yt(e,t,n=!1){const{props:o,ref:l,patchFlag:a,children:s}=e,i=t?function(...e){const t={};for(let n=0;non||O;let ln,an;{const e=(0,r.E9)(),t=(t,n)=>{let o;return(o=e[t])||(o=e[t]=[]),o.push(n),e=>{o.length>1?o.forEach((t=>t(e))):o[0](e)}};ln=t("__VUE_INSTANCE_SETTERS__",(e=>on=e)),an=t("__VUE_SSR_SETTERS__",(e=>hn=e))}const sn=e=>{const t=on;return ln(e),e.scope.on(),()=>{e.scope.off(),ln(t)}},cn=()=>{on&&on.scope.off(),ln(null)};function un(e){return 4&e.vnode.shapeFlag}let pn,dn,hn=!1;function fn(e,t,n){(0,r.mf)(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:(0,r.Kn)(t)&&(e.setupState=(0,o.WL)(t)),vn(e,n)}function vn(e,t,n){const l=e.type;if(!e.render){if(!t&&pn&&!l.render){const t=l.template||Be(e).template;if(t){const{isCustomElement:n,compilerOptions:o}=e.appContext.config,{delimiters:a,compilerOptions:s}=l,i=(0,r.l7)((0,r.l7)({isCustomElement:n,delimiters:a},o),s);l.render=pn(t,i)}}e.render=l.render||r.dG,dn&&dn(e)}{const t=sn(e);(0,o.Jd)();try{!function(e){const t=Be(e),n=e.proxy,l=e.ctx;De=!1,t.beforeCreate&&je(t.beforeCreate,e,"bc");const{data:a,computed:s,methods:i,watch:c,provide:u,inject:p,created:d,beforeMount:h,mounted:f,beforeUpdate:v,updated:m,activated:g,deactivated:y,beforeDestroy:b,beforeUnmount:w,destroyed:k,unmounted:_,render:S,renderTracked:C,renderTriggered:x,errorCaptured:T,serverPrefetch:I,expose:E,inheritAttrs:A,components:F,directives:L,filters:O}=t;if(p&&function(e,t,n=r.dG){(0,r.kJ)(e)&&(e=Ze(e));for(const n in e){const l=e[n];let a;a=(0,r.Kn)(l)?"default"in l?tt(l.from||n,l.default,!0):tt(l.from||n):tt(l),(0,o.dq)(a)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>a.value,set:e=>a.value=e}):t[n]=a}}(p,l,null),i)for(const e in i){const t=i[e];(0,r.mf)(t)&&(l[e]=t.bind(n))}if(a){const t=a.call(n,n);(0,r.Kn)(t)&&(e.data=(0,o.qj)(t))}if(De=!0,s)for(const e in s){const t=s[e],o=(0,r.mf)(t)?t.bind(n,n):(0,r.mf)(t.get)?t.get.bind(n,n):r.dG,a=!(0,r.mf)(t)&&(0,r.mf)(t.set)?t.set.bind(n):r.dG,i=kn({get:o,set:a});Object.defineProperty(l,e,{enumerable:!0,configurable:!0,get:()=>i.value,set:e=>i.value=e})}if(c)for(const e in c)Ve(c[e],l,n,e);if(u){const e=(0,r.mf)(u)?u.call(n):u;Reflect.ownKeys(e).forEach((t=>{et(t,e[t])}))}function M(e,t){(0,r.kJ)(t)?t.forEach((t=>e(t.bind(n)))):t&&e(t.bind(n))}if(d&&je(d,e,"c"),M(Ce,h),M(xe,f),M(Te,v),M(Ie,m),M(ye,g),M(be,y),M(Me,T),M(Oe,C),M(Le,x),M(Ee,w),M(Ae,_),M(Fe,I),(0,r.kJ)(E))if(E.length){const t=e.exposed||(e.exposed={});E.forEach((e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t})}))}else e.exposed||(e.exposed={});S&&e.render===r.dG&&(e.render=S),null!=A&&(e.inheritAttrs=A),F&&(e.components=F),L&&(e.directives=L)}(e)}finally{(0,o.lk)(),t()}}}function mn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy((0,o.WL)((0,o.Xl)(e.exposed)),{get:(t,n)=>n in t?t[n]:n in Re?Re[n](e):void 0,has:(e,t)=>t in e||t in Re}))}const gn=/(?:^|[-_])(\w)/g,yn=e=>e.replace(gn,(e=>e.toUpperCase())).replace(/[-_]/g,"");function bn(e,t=!0){return(0,r.mf)(e)?e.displayName||e.name:e.name||t&&e.__name}function wn(e,t,n=!1){let o=bn(t);if(!o&&t.__file){const e=t.__file.match(/([^/\\]+)\.\w+$/);e&&(o=e[1])}if(!o&&e&&e.parent){const n=e=>{for(const n in e)if(e[n]===t)return n};o=n(e.components||e.parent.type.components)||n(e.appContext.components)}return o?yn(o):n?"App":"Anonymous"}const kn=(e,t)=>(0,o.Fl)(e,t,hn);function _n(e,t,n){const o=arguments.length;return 2===o?(0,r.Kn)(t)&&!(0,r.kJ)(t)?Vt(t)?Jt(e,null,[t]):Jt(e,t):Jt(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):3===o&&Vt(n)&&(n=[n]),Jt(e,t,n))}const Sn="3.4.15"},9963:(e,t,n)=>{n.d(t,{W3:()=>q,uT:()=>d,vr:()=>X});var o=n(6252),r=n(3577),l=n(2262);const a="undefined"!=typeof document?document:null,s=a&&a.createElement("template"),i={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const r="svg"===t?a.createElementNS("http://www.w3.org/2000/svg",e):"mathml"===t?a.createElementNS("http://www.w3.org/1998/Math/MathML",e):a.createElement(e,n?{is:n}:void 0);return"select"===e&&o&&null!=o.multiple&&r.setAttribute("multiple",o.multiple),r},createText:e=>a.createTextNode(e),createComment:e=>a.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>a.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,r,l){const a=n?n.previousSibling:t.lastChild;if(r&&(r===l||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),r!==l&&(r=r.nextSibling););else{s.innerHTML="svg"===o?`${e} `:"mathml"===o?`${e} `:e;const r=s.content;if("svg"===o||"mathml"===o){const e=r.firstChild;for(;e.firstChild;)r.appendChild(e.firstChild);r.removeChild(e)}t.insertBefore(r,n)}return[a?a.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},c="transition",u="animation",p=Symbol("_vtc"),d=(e,{slots:t})=>(0,o.h)(o.P$,g(e),t);d.displayName="Transition";const h={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},f=d.props=(0,r.l7)({},o.nJ,h),v=(e,t=[])=>{(0,r.kJ)(e)?e.forEach((e=>e(...t))):e&&e(...t)},m=e=>!!e&&((0,r.kJ)(e)?e.some((e=>e.length>1)):e.length>1);function g(e){const t={};for(const n in e)n in h||(t[n]=e[n]);if(!1===e.css)return t;const{name:n="v",type:o,duration:l,enterFromClass:a=`${n}-enter-from`,enterActiveClass:s=`${n}-enter-active`,enterToClass:i=`${n}-enter-to`,appearFromClass:c=a,appearActiveClass:u=s,appearToClass:p=i,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:g=`${n}-leave-to`}=e,_=function(e){if(null==e)return null;if((0,r.Kn)(e))return[y(e.enter),y(e.leave)];{const t=y(e);return[t,t]}}(l),C=_&&_[0],x=_&&_[1],{onBeforeEnter:T,onEnter:E,onEnterCancelled:A,onLeave:F,onLeaveCancelled:L,onBeforeAppear:O=T,onAppear:M=E,onAppearCancelled:P=A}=t,R=(e,t,n)=>{w(e,t?p:i),w(e,t?u:s),n&&n()},H=(e,t)=>{e._isLeaving=!1,w(e,d),w(e,g),w(e,f),t&&t()},$=e=>(t,n)=>{const r=e?M:E,l=()=>R(t,e,n);v(r,[t,l]),k((()=>{w(t,e?c:a),b(t,e?p:i),m(r)||S(t,o,C,l)}))};return(0,r.l7)(t,{onBeforeEnter(e){v(T,[e]),b(e,a),b(e,s)},onBeforeAppear(e){v(O,[e]),b(e,c),b(e,u)},onEnter:$(!1),onAppear:$(!0),onLeave(e,t){e._isLeaving=!0;const n=()=>H(e,t);b(e,d),I(),b(e,f),k((()=>{e._isLeaving&&(w(e,d),b(e,g),m(F)||S(e,o,x,n))})),v(F,[e,n])},onEnterCancelled(e){R(e,!1),v(A,[e])},onAppearCancelled(e){R(e,!0),v(P,[e])},onLeaveCancelled(e){H(e),v(L,[e])}})}function y(e){return(0,r.He)(e)}function b(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.add(t))),(e[p]||(e[p]=new Set)).add(t)}function w(e,t){t.split(/\s+/).forEach((t=>t&&e.classList.remove(t)));const n=e[p];n&&(n.delete(t),n.size||(e[p]=void 0))}function k(e){requestAnimationFrame((()=>{requestAnimationFrame(e)}))}let _=0;function S(e,t,n,o){const r=e._endId=++_,l=()=>{r===e._endId&&o()};if(n)return setTimeout(l,n);const{type:a,timeout:s,propCount:i}=C(e,t);if(!a)return o();const c=a+"end";let u=0;const p=()=>{e.removeEventListener(c,d),l()},d=t=>{t.target===e&&++u>=i&&p()};setTimeout((()=>{u(n[e]||"").split(", "),r=o(`${c}Delay`),l=o(`${c}Duration`),a=x(r,l),s=o(`${u}Delay`),i=o(`${u}Duration`),p=x(s,i);let d=null,h=0,f=0;return t===c?a>0&&(d=c,h=a,f=l.length):t===u?p>0&&(d=u,h=p,f=i.length):(h=Math.max(a,p),d=h>0?a>p?c:u:null,f=d?d===c?l.length:i.length:0),{type:d,timeout:h,propCount:f,hasTransform:d===c&&/\b(transform|all)(,|$)/.test(o(`${c}Property`).toString())}}function x(e,t){for(;e.lengthT(t)+T(e[n]))))}function T(e){return"auto"===e?0:1e3*Number(e.slice(0,-1).replace(",","."))}function I(){return document.body.offsetHeight}const E=Symbol("_vod"),A=Symbol(""),F=/\s*!important$/;function L(e,t,n){if((0,r.kJ)(n))n.forEach((n=>L(e,t,n)));else if(null==n&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=function(e,t){const n=M[t];if(n)return n;let o=(0,r._A)(t);if("filter"!==o&&o in e)return M[t]=o;o=(0,r.kC)(o);for(let n=0;n$||(N.then((()=>$=0)),$=Date.now()),j=e=>111===e.charCodeAt(0)&&110===e.charCodeAt(1)&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123;"undefined"!=typeof HTMLElement&&HTMLElement;const V=new WeakMap,B=new WeakMap,z=Symbol("_moveCb"),U=Symbol("_enterCb"),q={name:"TransitionGroup",props:(0,r.l7)({},f,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=(0,o.FN)(),r=(0,o.Y8)();let a,s;return(0,o.ic)((()=>{if(!a.length)return;const t=e.moveClass||`${e.name||"v"}-move`;if(!function(e,t,n){const o=e.cloneNode(),r=e[p];r&&r.forEach((e=>{e.split(/\s+/).forEach((e=>e&&o.classList.remove(e)))})),n.split(/\s+/).forEach((e=>e&&o.classList.add(e))),o.style.display="none";const l=1===t.nodeType?t:t.parentNode;l.appendChild(o);const{hasTransform:a}=C(o);return l.removeChild(o),a}(a[0].el,n.vnode.el,t))return;a.forEach(Z),a.forEach(J);const o=a.filter(Y);I(),o.forEach((e=>{const n=e.el,o=n.style;b(n,t),o.transform=o.webkitTransform=o.transitionDuration="";const r=n[z]=e=>{e&&e.target!==n||e&&!/transform$/.test(e.propertyName)||(n.removeEventListener("transitionend",r),n[z]=null,w(n,t))};n.addEventListener("transitionend",r)}))})),()=>{const i=(0,l.IU)(e),c=g(i);let u=i.tag||o.HY;a=s,s=t.default?(0,o.Q6)(t.default()):[];for(let e=0;e{const d="svg"===a;"class"===t?function(e,t,n){const o=e[p];o&&(t=(t?[t,...o]:[...o]).join(" ")),null==t?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}(e,l,d):"style"===t?function(e,t,n){const o=e.style,l=o.display,a=(0,r.HD)(n);if(n&&!a){if(t&&!(0,r.HD)(t))for(const e in t)null==n[e]&&L(o,e,"");for(const e in n)L(o,e,n[e])}else if(a){if(t!==n){const e=o[A];e&&(n+=";"+e),o.cssText=n}}else t&&e.removeAttribute("style");E in e&&(o.display=l)}(e,n,l):(0,r.F7)(t)?(0,r.tR)(t)||function(e,t,n,l,a=null){const s=e[R]||(e[R]={}),i=s[t];if(l&&i)i.value=l;else{const[n,c]=function(e){let t;if(H.test(e)){let n;for(t={};n=e.match(H);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[":"===e[2]?e.slice(3):(0,r.rs)(e.slice(2)),t]}(t);if(l){const i=s[t]=function(e,t){const n=e=>{if(e._vts){if(e._vts<=n.attached)return}else e._vts=Date.now();(0,o.$d)(function(e,t){if((0,r.kJ)(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map((e=>t=>!t._stopped&&e&&e(t)))}return t}(e,n.value),t,5,[e])};return n.value=e,n.attached=D(),n}(l,a);!function(e,t,n,o){e.addEventListener(t,n,o)}(e,n,i,c)}else i&&(function(e,t,n,o){e.removeEventListener(t,n,o)}(e,n,i,c),s[t]=void 0)}}(e,t,0,l,i):("."===t[0]?(t=t.slice(1),1):"^"===t[0]?(t=t.slice(1),0):function(e,t,n,o){if(o)return"innerHTML"===t||"textContent"===t||!!(t in e&&j(t)&&(0,r.mf)(n));if("spellcheck"===t||"draggable"===t||"translate"===t)return!1;if("form"===t)return!1;if("list"===t&&"INPUT"===e.tagName)return!1;if("type"===t&&"TEXTAREA"===e.tagName)return!1;if("width"===t||"height"===t){const t=e.tagName;if("IMG"===t||"VIDEO"===t||"CANVAS"===t||"SOURCE"===t)return!1}return(!j(t)||!(0,r.HD)(n))&&t in e}(e,t,l,d))?function(e,t,n,o,l,a,s){if("innerHTML"===t||"textContent"===t)return o&&s(o,l,a),void(e[t]=null==n?"":n);const i=e.tagName;if("value"===t&&"PROGRESS"!==i&&!i.includes("-")){e._value=n;const o=null==n?"":n;return("OPTION"===i?e.getAttribute("value"):e.value)!==o&&(e.value=o),void(null==n&&e.removeAttribute(t))}let c=!1;if(""===n||null==n){const o=typeof e[t];"boolean"===o?n=(0,r.yA)(n):null==n&&"string"===o?(n="",c=!0):"number"===o&&(n=0,c=!0)}try{e[t]=n}catch(e){}c&&e.removeAttribute(t)}(e,t,l,s,i,c,u):("true-value"===t?e._trueValue=l:"false-value"===t&&(e._falseValue=l),function(e,t,n,o,l){if(o&&t.startsWith("xlink:"))null==n?e.removeAttributeNS(P,t.slice(6,t.length)):e.setAttributeNS(P,t,n);else{const o=(0,r.Pq)(t);null==n||o&&!(0,r.yA)(n)?e.removeAttribute(t):e.setAttribute(t,o?"":n)}}(e,t,l,d))}},i);let G,K=!1;const X=(...e)=>{const t=(G=K?G:(0,o.Eo)(W),K=!0,G).createApp(...e),{mount:n}=t;return t.mount=e=>{const t=function(e){if((0,r.HD)(e))return document.querySelector(e);return e}(e);if(t)return n(t,!0,function(e){return e instanceof SVGElement?"svg":"function"==typeof MathMLElement&&e instanceof MathMLElement?"mathml":void 0}(t))},t}},3577:(e,t,n)=>{function o(e,t){const n=new Set(e.split(","));return t?e=>n.has(e.toLowerCase()):e=>n.has(e)}n.d(t,{C_:()=>G,DM:()=>m,E9:()=>z,F7:()=>i,Gg:()=>A,HD:()=>w,He:()=>V,Kj:()=>y,Kn:()=>_,NO:()=>s,Nj:()=>D,Od:()=>p,PO:()=>I,Pq:()=>K,RI:()=>h,S0:()=>E,W7:()=>T,WV:()=>Q,Z6:()=>l,_A:()=>O,_N:()=>v,aU:()=>$,dG:()=>a,fY:()=>o,h5:()=>j,hR:()=>H,hq:()=>ee,ir:()=>N,j5:()=>q,kC:()=>R,kJ:()=>f,kT:()=>r,l7:()=>u,mf:()=>b,rs:()=>P,tI:()=>S,tR:()=>c,yA:()=>X,yk:()=>k,yl:()=>U});const r={},l=[],a=()=>{},s=()=>!1,i=e=>111===e.charCodeAt(0)&&110===e.charCodeAt(1)&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),c=e=>e.startsWith("onUpdate:"),u=Object.assign,p=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},d=Object.prototype.hasOwnProperty,h=(e,t)=>d.call(e,t),f=Array.isArray,v=e=>"[object Map]"===x(e),m=e=>"[object Set]"===x(e),g=e=>"[object Date]"===x(e),y=e=>"[object RegExp]"===x(e),b=e=>"function"==typeof e,w=e=>"string"==typeof e,k=e=>"symbol"==typeof e,_=e=>null!==e&&"object"==typeof e,S=e=>(_(e)||b(e))&&b(e.then)&&b(e.catch),C=Object.prototype.toString,x=e=>C.call(e),T=e=>x(e).slice(8,-1),I=e=>"[object Object]"===x(e),E=e=>w(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,A=o(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),F=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},L=/-(\w)/g,O=F((e=>e.replace(L,((e,t)=>t?t.toUpperCase():"")))),M=/\B([A-Z])/g,P=F((e=>e.replace(M,"-$1").toLowerCase())),R=F((e=>e.charAt(0).toUpperCase()+e.slice(1))),H=F((e=>e?`on${R(e)}`:"")),$=(e,t)=>!Object.is(e,t),N=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},j=e=>{const t=parseFloat(e);return isNaN(t)?e:t},V=e=>{const t=w(e)?Number(e):NaN;return isNaN(t)?e:t};let B;const z=()=>B||(B="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{}),U=o("Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error");function q(e){if(f(e)){const t={};for(let n=0;n{if(e){const n=e.split(J);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function G(e){let t="";if(w(e))t=e;else if(f(e))for(let n=0;nQ(e,t)))}},6669:(e,t,n)=>{var o=n(9e3),r=n(2291),l=n(9963),a=n(6252),s=n(2201),i=n(5214),c=n(7171),u=n(2456),p=n(1673),d=(0,a.aZ)({name:"Vuepress",setup(){const e=(0,o.xV)();return()=>(0,a.h)(e.value)}}),h=s.PO,f=([e,t,n=""])=>{const o=`head > ${e}${Object.entries(t).map((([e,t])=>(0,c.HD)(t)?`[${e}=${JSON.stringify(t)}]`:!0===t?`[${e}]`:"")).join("")}`;return Array.from(document.querySelectorAll(o)).find((e=>e.innerText===n))||null},v=([e,t,n])=>{if(!(0,c.HD)(e))return null;const o=document.createElement(e);return(0,c.PO)(t)&&Object.entries(t).forEach((([e,t])=>{(0,c.HD)(t)?o.setAttribute(e,t):!0===t&&o.setAttribute(e,"")})),(0,c.HD)(n)&&o.appendChild(document.createTextNode(n)),o},m=l.vr;(async()=>{const e=m({name:"VuepressApp",setup(){(()=>{const e=(0,o.mU)(),t=(0,o.Ym)();let n=[];const r=()=>{document.documentElement.lang=t.value;const o=(()=>{const t=[];return e.value.forEach((e=>{const n=v(e);n&&t.push(n)})),t})();n.forEach(((e,t)=>{const r=o.findIndex((t=>e.isEqualNode(t)));-1===r?(e.remove(),delete n[t]):o.splice(r,1)})),o.forEach((e=>document.head.appendChild(e))),n=[...n.filter((e=>!!e)),...o]};(0,a.JJ)(o.Vt,r),(0,a.bv)((()=>{e.value.forEach((e=>{const t=f(e);t&&n.push(t)})),(0,a.YP)(e,r,{immediate:!1})}))})();for(const e of r.W)e.setup?.();return()=>[(0,a.h)(s.MA),...r.W.flatMap((({rootComponents:e=[]})=>e.map((e=>(0,a.h)(e)))))]}}),t=(()=>{const e=(0,s.p7)({history:h((0,c.U1)("/")),routes:u.g.reduce(((e,[t,n,o,r])=>(e.push({name:t,path:n,component:d,meta:o},{path:n.endsWith("/")?n+"index.html":n.substring(0,n.length-5),redirect:n},...r.map((e=>({path:":md"===e?n.substring(0,n.length-5)+".md":e,redirect:n})))),e)),[{name:"404",path:"/:catchAll(.*)",component:d}]),scrollBehavior:(e,t,n)=>n||(e.hash?{el:e.hash}:{top:0})});return e.beforeResolve((async(e,t)=>{e.path===t.path&&t!==s.AJ||([e.meta._data]=await Promise.all([o.s_.resolvePageData(e.name),i.b[e.name]?.__asyncLoader()]))})),e})();(e=>{e.component("ClientOnly",o.qx),e.component("Content",o.VY)})(e),((e,t,n)=>{const r=(0,a.Fl)((()=>t.currentRoute.value.path)),l=(0,p.fA)(r,(()=>t.currentRoute.value.meta._data)),s=(0,a.Fl)((()=>o.s_.resolveLayouts(n))),i=(0,a.Fl)((()=>o.s_.resolveRouteLocale(o.HM.value.locales,r.value))),c=(0,a.Fl)((()=>o.s_.resolveSiteLocaleData(o.HM.value,i.value))),u=(0,a.Fl)((()=>o.s_.resolvePageFrontmatter(l.value))),d=(0,a.Fl)((()=>o.s_.resolvePageHeadTitle(l.value,c.value))),h=(0,a.Fl)((()=>o.s_.resolvePageHead(d.value,u.value,c.value))),f=(0,a.Fl)((()=>o.s_.resolvePageLang(l.value,c.value))),v=(0,a.Fl)((()=>o.s_.resolvePageLayout(l.value,s.value)));e.provide(o.hU,s),e.provide(o.Cv,l),e.provide(o.PY,u),e.provide(o.et,d),e.provide(o.VV,h),e.provide(o.b5,f),e.provide(o.hx,v),e.provide(o.C3,i),e.provide(o.AE,c),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>u.value},$head:{get:()=>h.value},$headTitle:{get:()=>d.value},$lang:{get:()=>f.value},$page:{get:()=>l.value},$routeLocale:{get:()=>i.value},$site:{get:()=>o.HM.value},$siteLocale:{get:()=>c.value},$withBase:{get:()=>o.pJ}}),o.HM})(e,t,r.W);for(const n of r.W)await(n.enhance?.({app:e,router:t,siteData:o.HM}));return e.use(t),{app:e,router:t}})().then((({app:e,router:t})=>{t.isReady().then((()=>{e.mount("#app")}))}))},9e3:(e,t,n)=>{n.d(t,{AE:()=>I,C3:()=>S,Cv:()=>u,HM:()=>x,I:()=>C,I2:()=>f,I5:()=>E,PY:()=>h,VV:()=>v,VY:()=>O,Vi:()=>d,Vt:()=>A,WF:()=>T,Ym:()=>b,b5:()=>y,et:()=>g,hU:()=>c,hx:()=>w,mU:()=>m,pJ:()=>P,qx:()=>L,r$:()=>M,s_:()=>F,xV:()=>k});var o=n(2262),r=n(6252),l=n(5719),a=n(4995),s=n(7171),i=n(5214),c=Symbol(""),u=Symbol(""),p=(0,o.OT)({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),d=()=>{const e=(0,r.f3)(u);if(!e)throw new Error("pageData() is called without provider.");return e},h=Symbol(""),f=()=>{const e=(0,r.f3)(h);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},v=Symbol(""),m=()=>{const e=(0,r.f3)(v);if(!e)throw new Error("usePageHead() is called without provider.");return e},g=Symbol(""),y=Symbol(""),b=()=>{const e=(0,r.f3)(y);if(!e)throw new Error("usePageLang() is called without provider.");return e},w=Symbol(""),k=()=>{const e=(0,r.f3)(w);if(!e)throw new Error("usePageLayout() is called without provider.");return e},_=(0,o.iH)(l.T),S=Symbol(""),C=()=>{const e=(0,r.f3)(S);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},x=(0,o.iH)(a.H),T=()=>x,I=Symbol(""),E=()=>{const e=(0,r.f3)(I);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},A=Symbol(""),F=(0,o.qj)({resolveLayouts:e=>e.reduce(((e,t)=>({...e,...t.layouts})),{}),resolvePageData:async e=>{const t=_.value[e];return await(t?.())??p},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const o=(0,s.HD)(t.description)?t.description:n.description,r=[...Array.isArray(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:o}]];return(0,s.H7)(r)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter((e=>!!e)).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let n;if(e.path){const t=e.frontmatter.layout;n=(0,s.HD)(t)?t:"Layout"}else n="NotFound";return t[n]},resolveRouteLocale:(e,t)=>(0,s.gb)(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t],head:[...e.locales[t]?.head??[],...e.head??[]]})}),L=(0,r.aZ)({name:"ClientOnly",setup(e,t){const n=(0,o.iH)(!1);return(0,r.bv)((()=>{n.value=!0})),()=>n.value?t.slots.default?.():null}}),O=(0,r.aZ)({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=d(),n=(0,r.Fl)((()=>i.b[e.pageKey||t.value.key]));return()=>n.value?(0,r.h)(n.value):(0,r.h)("div","404 Not Found")}}),M=(e={})=>e,P=e=>(0,s.ak)(e)?e:`/${(0,s.FY)(e)}`},4906:(e,t,n)=>{n.d(t,{Z:()=>i});var o=n(8102),r=n(6252),l=n(2201);const a=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:o=5})=>{const a=(0,l.tv)(),i=function(e,t,n){var o,r,l;void 0===t&&(t=50),void 0===n&&(n={});var a=null!=(o=n.isImmediate)&&o,s=null!=(r=n.callback)&&r,i=n.maxWait,c=Date.now(),u=[];function p(){if(void 0!==i){var e=Date.now()-c;if(e+t>=i)return i-e}return t}var d=function(){var t=[].slice.call(arguments),n=this;return new Promise((function(o,r){var i=a&&void 0===l;if(void 0!==l&&clearTimeout(l),l=setTimeout((function(){if(l=void 0,c=Date.now(),!a){var o=e.apply(n,t);s&&s(o),u.forEach((function(e){return(0,e.resolve)(o)})),u=[]}}),p()),i){var d=e.apply(n,t);return s&&s(d),o(d)}u.push({resolve:o,reject:r})}))};return d.cancel=function(e){void 0!==l&&clearTimeout(l),u.forEach((function(t){return(0,t.reject)(e)})),u=[]},d}((()=>{const n=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(n-0)c.some((t=>t.hash===e.hash))));for(let e=0;e=(t.parentElement?.offsetTop??0)-o,c=!r||n<(r.parentElement?.offsetTop??0)-o;if(!l||!c)continue;const p=decodeURIComponent(a.currentRoute.value.hash),d=decodeURIComponent(t.hash);if(p===d)return;if(i)for(let t=e+1;t{window.addEventListener("scroll",i)})),(0,r.Jd)((()=>{window.removeEventListener("scroll",i)}))},s=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))},i=(0,o.r$)({setup(){a({headerLinkSelector:".vp-sidebar-link, .toc-link",headerAnchorSelector:".header-anchor",delay:200,offset:5})}})},9567:(e,t,n)=>{n.d(t,{h:()=>a});var o=n(6252),r=n(8102);const l=(0,o.h)("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"},[(0,o.h)("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"}),(0,o.h)("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"})]),a=(0,o.aZ)({name:"ExternalLinkIcon",props:{locales:{type:Object,required:!1,default:()=>({})}},setup(e){const t=(0,r.I)(),n=(0,o.Fl)((()=>e.locales[t.value]??{openInNewWindow:"open in new window"}));return()=>(0,o.h)("span",[l,(0,o.h)("span",{class:"external-link-icon-sr-only"},n.value.openInNewWindow)])}})},7102:(e,t,n)=>{n.d(t,{Z:()=>s});var o=n(6252),r=n(8102),l=n(9567);const a={},s=(0,r.r$)({enhance({app:e}){e.component("ExternalLinkIcon",(0,o.h)(l.h,{locales:a}))}})},5281:(e,t,n)=>{n.d(t,{Z:()=>m});var o=n(8102),r=n(6252),l=n(2201);const a={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=a.isStarted();e=s(e,a.settings.minimum,1),a.status=1===e?null:e;const n=a.render(!t),o=n.querySelector(a.settings.barSelector),r=a.settings.speed,l=a.settings.easing;return n.offsetWidth,c((t=>{u(o,{transform:"translate3d("+i(e)+"%,0,0)",transition:"all "+r+"ms "+l}),1===e?(u(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout((function(){u(n,{transition:"all "+r+"ms linear",opacity:"0"}),setTimeout((function(){a.remove(),t()}),r)}),r)):setTimeout((()=>t()),r)})),a},isStarted:()=>"number"==typeof a.status,start:()=>{a.status||a.set(0);const e=()=>{setTimeout((()=>{a.status&&(a.trickle(),e())}),a.settings.trickleSpeed)};return a.settings.trickle&&e(),a},done:e=>e||a.status?a.inc(.3+.5*Math.random()).set(1):a,inc:e=>{let t=a.status;return t?("number"!=typeof e&&(e=(1-t)*s(Math.random()*t,.1,.95)),t=s(t+e,0,.994),a.set(t)):a.start()},trickle:()=>a.inc(Math.random()*a.settings.trickleRate),render:e=>{if(a.isRendered())return document.getElementById("nprogress");d(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=a.settings.template;const n=t.querySelector(a.settings.barSelector),o=e?"-100":i(a.status||0),r=document.querySelector(a.settings.parent);return u(n,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),r!==document.body&&d(r,"nprogress-custom-parent"),r?.appendChild(t),t},remove:()=>{h(document.documentElement,"nprogress-busy"),h(document.querySelector(a.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&v(e)},isRendered:()=>!!document.getElementById("nprogress")},s=(e,t,n)=>en?n:e,i=e=>100*(-1+e),c=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),1===e.length&&t()}}(),u=function(){const e=["Webkit","O","Moz","ms"],t={};function n(n,o,r){var l;l=(l=o).replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()})),o=t[l]??=function(t){const n=document.body.style;if(t in n)return t;let o=e.length;const r=t.charAt(0).toUpperCase()+t.slice(1);let l;for(;o--;)if(l=e[o]+r,l in n)return l;return t}(l),n.style[o]=r}return function(e,t){for(const o in t){const r=t[o];void 0!==r&&Object.prototype.hasOwnProperty.call(t,o)&&n(e,o,r)}}}(),p=(e,t)=>("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0,d=(e,t)=>{const n=f(e),o=n+t;p(n,t)||(e.className=o.substring(1))},h=(e,t)=>{const n=f(e);if(!p(e,t))return;const o=n.replace(" "+t+" "," ");e.className=o.substring(1,o.length-1)},f=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),v=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},m=(0,o.r$)({setup(){(0,r.bv)((()=>{const e=(0,l.tv)(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach((e=>{t.has(e.path)||a.start()})),e.afterEach((e=>{t.add(e.path),a.done()}))}))}})},395:(e,t,n)=>{n.d(t,{g$:()=>c,ZS:()=>s,BV:()=>l,X6:()=>i});var o=n(8417);const r=(0,n(2262).iH)(o.f),l=()=>r;var a=n(6252);const s=Symbol(""),i=()=>{const e=(0,a.f3)(s);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},c=(e,t)=>{const{locales:n,...o}=e;return{...o,...n?.[t]}}},7699:(e,t,n)=>{n.d(t,{Z:()=>a});var o=n(6252),r=n(8102),l=n(395);const a=(0,r.r$)({enhance({app:e}){const t=(0,l.BV)(),n=e._context.provides[r.C3],a=(0,o.Fl)((()=>(0,l.g$)(t.value,n.value)));e.provide(l.ZS,a),Object.defineProperties(e.config.globalProperties,{$theme:{get:()=>t.value},$themeLocale:{get:()=>a.value}})}})},7171:(e,t,n)=>{n.d(t,{FY:()=>c,H7:()=>l,HD:()=>p,PO:()=>s,U1:()=>i,ak:()=>a,gb:()=>u});var o=["link","meta","script","style","noscript","template"],r=["title","base"],l=e=>{const t=new Set,n=[];return e.forEach((e=>{const l=(([e,t,n])=>r.includes(e)?e:o.includes(e)?"meta"===e&&t.name?`${e}.${t.name}`:"template"===e&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map((([e,t])=>"boolean"==typeof t?t?[e,""]:null:[e,t])).filter((e=>null!=e)).sort((([e],[t])=>e.localeCompare(t))),n]):null)(e);l&&!t.has(l)&&(t.add(l),n.push(e))})),n},a=e=>/^(https?:)?\/\//.test(e),s=e=>"[object Object]"===Object.prototype.toString.call(e),i=e=>"/"===e[e.length-1]?e.slice(0,-1):e,c=e=>"/"===e[0]?e.slice(1):e,u=(e,t)=>{const n=Object.keys(e).sort(((e,t)=>{const n=t.split("/").length-e.split("/").length;return 0!==n?n:t.length-e.length}));for(const e of n)if(t.startsWith(e))return e;return"/"},p=e=>"string"==typeof e},6309:(e,t,n)=>{n.d(t,{Iyq:()=>x,O9U:()=>E,ORN:()=>u,PrY:()=>P,QA3:()=>C,VPI:()=>m,_aR:()=>F,baj:()=>R,h4X:()=>T,i9H:()=>d,iPe:()=>H,y$C:()=>S});var o=n(1673),r=n(6252),l=n(2262);function a(e){var t;const n=(0,o.Tn)(e);return null!=(t=null==n?void 0:n.$el)?t:n}const s=o.C5?window:void 0,i=o.C5?window.document:void 0,c=o.C5?window.navigator:void 0;function u(...e){let t,n,l,i;if("string"==typeof e[0]||Array.isArray(e[0])?([n,l,i]=e,t=s):[t,n,l,i]=e,!t)return o.ZT;Array.isArray(n)||(n=[n]),Array.isArray(l)||(l=[l]);const c=[],u=()=>{c.forEach((e=>e())),c.length=0},p=(0,r.YP)((()=>[a(t),(0,o.Tn)(i)]),(([e,t])=>{if(u(),!e)return;const r=(0,o.Kn)(t)?{...t}:t;c.push(...n.flatMap((t=>l.map((n=>((e,t,n,o)=>(e.addEventListener(t,n,o),()=>e.removeEventListener(t,n,o)))(e,t,n,r))))))}),{immediate:!0,flush:"post"}),d=()=>{p(),u()};return(0,o.IY)(d),d}o.C5&&window.location;let p=!1;function d(e,t,n={}){const{window:r=s,ignore:l=[],capture:i=!0,detectIframe:c=!1}=n;if(!r)return o.ZT;o.gn&&!p&&(p=!0,Array.from(r.document.body.children).forEach((e=>e.addEventListener("click",o.ZT))),r.document.documentElement.addEventListener("click",o.ZT));let d=!0;const h=e=>l.some((t=>{if("string"==typeof t)return Array.from(r.document.querySelectorAll(t)).some((t=>t===e.target||e.composedPath().includes(t)));{const n=a(t);return n&&(e.target===n||e.composedPath().includes(n))}})),f=[u(r,"click",(n=>{const o=a(e);o&&o!==n.target&&!n.composedPath().includes(o)&&(0===n.detail&&(d=!h(n)),d?t(n):d=!0)}),{passive:!0,capture:i}),u(r,"pointerdown",(t=>{const n=a(e);d=!h(t)&&!(!n||t.composedPath().includes(n))}),{passive:!0}),c&&u(r,"blur",(n=>{setTimeout((()=>{var o;const l=a(e);"IFRAME"!==(null==(o=r.document.activeElement)?void 0:o.tagName)||(null==l?void 0:l.contains(r.document.activeElement))||t(n)}),0)}))].filter(Boolean);return()=>f.forEach((e=>e()))}function h(e){const t=function(){const e=(0,l.iH)(!1);return(0,r.FN)()&&(0,r.bv)((()=>{e.value=!0})),e}();return(0,r.Fl)((()=>(t.value,Boolean(e()))))}function f(e,t={}){const{window:n=s}=t,a=h((()=>n&&"matchMedia"in n&&"function"==typeof n.matchMedia));let i;const c=(0,l.iH)(!1),u=e=>{c.value=e.matches},p=()=>{i&&("removeEventListener"in i?i.removeEventListener("change",u):i.removeListener(u))},d=(0,r.m0)((()=>{a.value&&(p(),i=n.matchMedia((0,o.Tn)(e)),"addEventListener"in i?i.addEventListener("change",u):i.addListener(u),c.value=i.matches)}));return(0,o.IY)((()=>{d(),p(),i=void 0})),c}function v(e,t={}){const{controls:n=!1,navigator:r=c}=t,a=h((()=>r&&"permissions"in r));let s;const i="string"==typeof e?{name:e}:e,p=(0,l.iH)(),d=()=>{s&&(p.value=s.state)},f=(0,o._m)((async()=>{if(a.value){if(!s)try{s=await r.permissions.query(i),u(s,"change",d),d()}catch(e){p.value="prompt"}return s}}));return f(),n?{state:p,isSupported:a,query:f}:p}function m(e={}){const{navigator:t=c,read:n=!1,source:a,copiedDuring:s=1500,legacy:i=!1}=e,p=h((()=>t&&"clipboard"in t)),d=v("clipboard-read"),f=v("clipboard-write"),m=(0,r.Fl)((()=>p.value||i)),g=(0,l.iH)(""),y=(0,l.iH)(!1),b=(0,o.eM)((()=>y.value=!1),s);return m.value&&n&&u(["copy","cut"],(function(){var e,n,o;p.value&&"denied"!==d.value?t.clipboard.readText().then((e=>{g.value=e})):g.value=null!=(o=null==(n=null==(e=null==document?void 0:document.getSelection)?void 0:e.call(document))?void 0:n.toString())?o:""})),{isSupported:m,text:g,copied:y,copy:async function(e=(0,o.Tn)(a)){m.value&&null!=e&&(p.value&&"denied"!==f.value?await t.clipboard.writeText(e):function(e){const t=document.createElement("textarea");t.value=null!=e?e:"",t.style.position="absolute",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),t.remove()}(e),g.value=e,y.value=!0,b.start())}}}const g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},y="__vueuse_ssr_handlers__",b=w();function w(){return y in g||(g[y]=g[y]||{}),g[y]}const k={boolean:{read:e=>"true"===e,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()}},_="vueuse-storage";function S(e,t,n,a={}){var i;const{flush:c="pre",deep:p=!0,listenToStorageChanges:d=!0,writeDefaults:h=!0,mergeDefaults:f=!1,shallow:v,window:m=s,eventFilter:g,onError:y=(e=>{console.error(e)}),initOnMounted:w}=a,S=(v?l.XI:l.iH)("function"==typeof t?t():t);if(!n)try{n=function(e,t){return b[e]||t}("getDefaultStorage",(()=>{var e;return null==(e=s)?void 0:e.localStorage}))()}catch(e){y(e)}if(!n)return S;const C=(0,o.Tn)(t),x=function(e){return null==e?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":"boolean"==typeof e?"boolean":"string"==typeof e?"string":"object"==typeof e?"object":Number.isNaN(e)?"any":"number"}(C),T=null!=(i=a.serializer)?i:k[x],{pause:I,resume:E}=(0,o._I)(S,(()=>function(t){try{if(null==t)n.removeItem(e);else{const o=T.write(t),r=n.getItem(e);r!==o&&(n.setItem(e,o),m&&m.dispatchEvent(new CustomEvent(_,{detail:{key:e,oldValue:r,newValue:o,storageArea:n}})))}}catch(e){y(e)}}(S.value)),{flush:c,deep:p,eventFilter:g});return m&&d&&(0,o.u7)((()=>{u(m,"storage",F),u(m,_,A),w&&F()})),w||F(),S;function A(e){F(e.detail)}function F(t){if(!t||t.storageArea===n)if(t&&null==t.key)S.value=C;else if(!t||t.key===e){I();try{(null==t?void 0:t.newValue)!==T.write(S.value)&&(S.value=function(t){const o=t?t.newValue:n.getItem(e);if(null==o)return h&&null!=C&&n.setItem(e,T.write(C)),C;if(!t&&f){const e=T.read(o);return"function"==typeof f?f(e,C):"object"!==x||Array.isArray(e)?e:{...C,...e}}return"string"!=typeof o?o:T.read(o)}(t))}catch(e){y(e)}finally{t?(0,r.Y3)(E):E()}}}}function C(e){return f("(prefers-color-scheme: dark)",e)}function x(e,t,n={}){const{window:l=s,...i}=n;let c;const u=h((()=>l&&"MutationObserver"in l)),p=()=>{c&&(c.disconnect(),c=void 0)},d=(0,r.YP)((()=>a(e)),(e=>{p(),u.value&&l&&e&&(c=new MutationObserver(t),c.observe(e,i))}),{immediate:!0}),f=()=>{p(),d()};return(0,o.IY)(f),{isSupported:u,stop:f,takeRecords:()=>null==c?void 0:c.takeRecords()}}function T(e,t={width:0,height:0},n={}){const{window:i=s,box:c="content-box"}=n,u=(0,r.Fl)((()=>{var t,n;return null==(n=null==(t=a(e))?void 0:t.namespaceURI)?void 0:n.includes("svg")})),p=(0,l.iH)(t.width),d=(0,l.iH)(t.height),{stop:f}=function(e,t,n={}){const{window:l=s,...i}=n;let c;const u=h((()=>l&&"ResizeObserver"in l)),p=()=>{c&&(c.disconnect(),c=void 0)},d=(0,r.Fl)((()=>Array.isArray(e)?e.map((e=>a(e))):[a(e)])),f=(0,r.YP)(d,(e=>{if(p(),u.value&&l){c=new ResizeObserver(t);for(const t of e)t&&c.observe(t,i)}}),{immediate:!0,flush:"post",deep:!0}),v=()=>{p(),f()};return(0,o.IY)(v),{isSupported:u,stop:v}}(e,(([t])=>{const n="border-box"===c?t.borderBoxSize:"content-box"===c?t.contentBoxSize:t.devicePixelContentBoxSize;if(i&&u.value){const t=a(e);if(t){const e=i.getComputedStyle(t);p.value=Number.parseFloat(e.width),d.value=Number.parseFloat(e.height)}}else if(n){const e=Array.isArray(n)?n:[n];p.value=e.reduce(((e,{inlineSize:t})=>e+t),0),d.value=e.reduce(((e,{blockSize:t})=>e+t),0)}else p.value=t.contentRect.width,d.value=t.contentRect.height}),n);(0,o.u7)((()=>{const n=a(e);n&&(p.value="offsetWidth"in n?n.offsetWidth:t.width,d.value="offsetHeight"in n?n.offsetHeight:t.height)}));const v=(0,r.YP)((()=>a(e)),(e=>{p.value=e?t.width:0,d.value=e?t.height:0}));return{width:p,height:d,stop:function(){f(),v()}}}const I=["fullscreenchange","webkitfullscreenchange","webkitendfullscreen","mozfullscreenchange","MSFullscreenChange"];function E(e,t={}){const{document:n=i,autoExit:s=!1}=t,c=(0,r.Fl)((()=>{var t;return null!=(t=a(e))?t:null==n?void 0:n.querySelector("html")})),p=(0,l.iH)(!1),d=(0,r.Fl)((()=>["requestFullscreen","webkitRequestFullscreen","webkitEnterFullscreen","webkitEnterFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].find((e=>n&&e in n||c.value&&e in c.value)))),f=(0,r.Fl)((()=>["exitFullscreen","webkitExitFullscreen","webkitExitFullScreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].find((e=>n&&e in n||c.value&&e in c.value)))),v=(0,r.Fl)((()=>["fullScreen","webkitIsFullScreen","webkitDisplayingFullscreen","mozFullScreen","msFullscreenElement"].find((e=>n&&e in n||c.value&&e in c.value)))),m=["fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement"].find((e=>n&&e in n)),g=h((()=>c.value&&n&&void 0!==d.value&&void 0!==f.value&&void 0!==v.value)),y=()=>{if(v.value){if(n&&null!=n[v.value])return n[v.value];{const e=c.value;if(null!=(null==e?void 0:e[v.value]))return Boolean(e[v.value])}}return!1};async function b(){if(g.value&&p.value){if(f.value)if(null!=(null==n?void 0:n[f.value]))await n[f.value]();else{const e=c.value;null!=(null==e?void 0:e[f.value])&&await e[f.value]()}p.value=!1}}async function w(){if(!g.value||p.value)return;y()&&await b();const e=c.value;d.value&&null!=(null==e?void 0:e[d.value])&&(await e[d.value](),p.value=!0)}const k=()=>{const e=y();(!e||e&&m&&(null==n?void 0:n[m])===c.value)&&(p.value=e)};return u(n,I,k,!1),u((()=>a(c)),I,k,!1),s&&(0,o.IY)(b),{isSupported:g,isFullscreen:p,enter:w,exit:b,toggle:async function(){await(p.value?b():w())}}}function A(e){return"undefined"!=typeof Window&&e instanceof Window?e.document.documentElement:"undefined"!=typeof Document&&e instanceof Document?e.documentElement:e}function F(e,t,n={}){const{window:o=s}=n;return S(e,t,null==o?void 0:o.localStorage,n)}function L(e){const t=window.getComputedStyle(e);if("scroll"===t.overflowX||"scroll"===t.overflowY||"auto"===t.overflowX&&e.clientWidth1||(t.preventDefault&&t.preventDefault(),!1))}const M=new WeakMap;function P(e,t=!1){const n=(0,l.iH)(t);let a=null;(0,r.YP)((0,o.Vh)(e),(e=>{const t=A((0,o.Tn)(e));if(t){const e=t;M.get(e)||M.set(e,void 0),n.value&&(e.style.overflow="hidden")}}),{immediate:!0});const s=()=>{var t;const r=A((0,o.Tn)(e));r&&n.value&&(o.gn&&(null==a||a()),r.style.overflow=null!=(t=M.get(r))?t:"",M.delete(r),n.value=!1)};return(0,o.IY)(s),(0,r.Fl)({get:()=>n.value,set(t){t?(()=>{const t=A((0,o.Tn)(e));t&&!n.value&&(o.gn&&(a=u(t,"touchmove",(e=>{O(e)}),{passive:!1})),t.style.overflow="hidden",n.value=!0)})():s()}})}Number.POSITIVE_INFINITY;function R(e={}){const{window:t=s,behavior:n="auto"}=e;if(!t)return{x:(0,l.iH)(0),y:(0,l.iH)(0)};const o=(0,l.iH)(t.scrollX),a=(0,l.iH)(t.scrollY),i=(0,r.Fl)({get:()=>o.value,set(e){scrollTo({left:e,behavior:n})}}),c=(0,r.Fl)({get:()=>a.value,set(e){scrollTo({top:e,behavior:n})}});return u(t,"scroll",(()=>{o.value=t.scrollX,a.value=t.scrollY}),{capture:!1,passive:!0}),{x:i,y:c}}function H(e={}){const{window:t=s,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:a=Number.POSITIVE_INFINITY,listenOrientation:i=!0,includeScrollbar:c=!0}=e,p=(0,l.iH)(n),d=(0,l.iH)(a),h=()=>{t&&(c?(p.value=t.innerWidth,d.value=t.innerHeight):(p.value=t.document.documentElement.clientWidth,d.value=t.document.documentElement.clientHeight))};if(h(),(0,o.u7)(h),u("resize",h,{passive:!0}),i){const e=f("(orientation: portrait)");(0,r.YP)(e,(()=>h()))}return{width:p,height:d}}o.yR},1673:(e,t,n)=>{n.d(t,{fA:()=>l,_m:()=>w,yR:()=>b,C5:()=>i,gn:()=>d,Kn:()=>u,ZT:()=>p,_I:()=>x,Vh:()=>k,Tn:()=>s,u7:()=>T,IY:()=>a,DI:()=>_,vA:()=>S,eM:()=>I,OT:()=>E});var o=n(2262),r=n(6252);function l(e,t){let n,l,a;const s=(0,o.iH)(!0),i=()=>{s.value=!0,a()};(0,r.YP)(e,i,{flush:"sync"});const c="function"==typeof t?t:t.get,u="function"==typeof t?void 0:t.set,p=(0,o.ZM)(((e,t)=>(l=e,a=t,{get:()=>(s.value&&(n=c(),s.value=!1),l(),n),set(e){null==u||u(e)}})));return Object.isExtensible(p)&&(p.trigger=i),p}function a(e){return!!(0,o.nZ)()&&((0,o.EB)(e),!0)}function s(e){return"function"==typeof e?e():(0,o.SU)(e)}const i="undefined"!=typeof window&&"undefined"!=typeof document,c=("undefined"!=typeof WorkerGlobalScope&&(globalThis,WorkerGlobalScope),Object.prototype.toString),u=e=>"[object Object]"===c.call(e),p=()=>{},d=h();function h(){var e,t;return i&&(null==(e=null==window?void 0:window.navigator)?void 0:e.userAgent)&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||(null==(t=null==window?void 0:window.navigator)?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(null==window?void 0:window.navigator.userAgent))}function f(e,t){return function(...n){return new Promise(((o,r)=>{Promise.resolve(e((()=>t.apply(this,n)),{fn:t,thisArg:this,args:n})).then(o).catch(r)}))}}const v=e=>e();function m(e){const t=Object.create(null);return n=>t[n]||(t[n]=e(n))}const g=/\B([A-Z])/g,y=(m((e=>e.replace(g,"-$1").toLowerCase())),/-(\w)/g);function b(e){return e}function w(e){let t;function n(){return t||(t=e()),t}return n.reset=async()=>{const e=t;t=void 0,e&&await e},n}function k(...e){if(1!==e.length)return(0,o.Vh)(...e);const t=e[0];return"function"==typeof t?(0,o.OT)((0,o.ZM)((()=>({get:t,set:p})))):(0,o.iH)(t)}function _(e,t=200,n={}){return f(function(e,t={}){let n,o,r=p;const l=e=>{clearTimeout(e),r(),r=p};return a=>{const i=s(e),c=s(t.maxWait);return n&&l(n),i<=0||void 0!==c&&c<=0?(o&&(l(o),o=null),Promise.resolve(a())):new Promise(((e,s)=>{r=t.rejectOnCancel?s:e,c&&!o&&(o=setTimeout((()=>{n&&l(n),o=null,e(a())}),c)),n=setTimeout((()=>{o&&l(o),o=null,e(a())}),i)}))}}(t,n),e)}function S(e,t=200,n=!1,o=!0,r=!1){return f(function(e,t=!0,n=!0,o=!1){let r,l,a=0,i=!0,c=p;const u=()=>{r&&(clearTimeout(r),r=void 0,c(),c=p)};return p=>{const d=s(e),h=Date.now()-a,f=()=>l=p();return u(),d<=0?(a=Date.now(),f()):(h>d&&(n||!i)?(a=Date.now(),f()):t&&(l=new Promise(((e,t)=>{c=o?t:e,r=setTimeout((()=>{a=Date.now(),i=!0,e(f()),u()}),Math.max(0,d-h))}))),n||r||(r=setTimeout((()=>i=!0),d)),i=!1,l)}}(t,n,o,r),e)}function C(e,t,n={}){const{eventFilter:o=v,...l}=n;return(0,r.YP)(e,f(o,t),l)}function x(e,t,n={}){const{eventFilter:r,...l}=n,{eventFilter:a,pause:s,resume:i,isActive:c}=function(e=v){const t=(0,o.iH)(!0);return{isActive:(0,o.OT)(t),pause:function(){t.value=!1},resume:function(){t.value=!0},eventFilter:(...n)=>{t.value&&e(...n)}}}(r);return{stop:C(e,t,{...l,eventFilter:a}),pause:s,resume:i,isActive:c}}function T(e,t=!0,n){!function(e){return e||(0,r.FN)()}()?t?e():(0,r.Y3)(e):(0,r.bv)(e,n)}function I(e,t,n={}){const{immediate:r=!0}=n,l=(0,o.iH)(!1);let c=null;function u(){c&&(clearTimeout(c),c=null)}function p(){l.value=!1,u()}function d(...n){u(),l.value=!0,c=setTimeout((()=>{l.value=!1,c=null,e(...n)}),s(t))}return r&&(l.value=!0,i&&d()),a(p),{isPending:(0,o.OT)(l),start:d,stop:p}}function E(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,l=(0,o.dq)(e),a=(0,o.iH)(e);function i(e){if(arguments.length)return a.value=e,a.value;{const e=s(n);return a.value=a.value===e?s(r):e,a.value}}return l?i:[a,i]}m((e=>e.replace(y,((e,t)=>t?t.toUpperCase():""))))},2201:(e,t,n)=>{n.d(t,{AJ:()=>F,MA:()=>Fe,PO:()=>E,nB:()=>xe,p7:()=>Le,tv:()=>Oe,yj:()=>Me});var o=n(6252),r=n(2262);const l="undefined"!=typeof window;const a=Object.assign;function s(e,t){const n={};for(const o in t){const r=t[o];n[o]=c(r)?r.map(e):e(r)}return n}const i=()=>{},c=Array.isArray,u=/\/$/,p=e=>e.replace(u,"");function d(e,t,n="/"){let o,r={},l="",a="";const s=t.indexOf("#");let i=t.indexOf("?");return s=0&&(i=-1),i>-1&&(o=t.slice(0,i),l=t.slice(i+1,s>-1?s:t.length),r=e(l)),s>-1&&(o=o||t.slice(0,s),a=t.slice(s,t.length)),o=function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),o=e.split("/"),r=o[o.length-1];".."!==r&&"."!==r||o.push("");let l,a,s=n.length-1;for(l=0;l1&&s--}return n.slice(0,s).join("/")+"/"+o.slice(l-(l===o.length?1:0)).join("/")}(null!=o?o:t,n),{fullPath:o+(l&&"?")+l+a,path:o,query:r,hash:a}}function h(e,t){return t&&e.toLowerCase().startsWith(t.toLowerCase())?e.slice(t.length)||"/":e}function f(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function v(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!m(e[n],t[n]))return!1;return!0}function m(e,t){return c(e)?g(e,t):c(t)?g(t,e):e===t}function g(e,t){return c(t)?e.length===t.length&&e.every(((e,n)=>e===t[n])):1===e.length&&e[0]===t}var y,b;!function(e){e.pop="pop",e.push="push"}(y||(y={})),function(e){e.back="back",e.forward="forward",e.unknown=""}(b||(b={}));const w=/^[^#]+#/;function k(e,t){return e.replace(w,"#")+t}const _=()=>({left:window.pageXOffset,top:window.pageYOffset});function S(e,t){return(history.state?history.state.position-t:-1)+e}const C=new Map;let x=()=>location.protocol+"//"+location.host;function T(e,t){const{pathname:n,search:o,hash:r}=t,l=e.indexOf("#");if(l>-1){let t=r.includes(e.slice(l))?e.slice(l).length:1,n=r.slice(t);return"/"!==n[0]&&(n="/"+n),h(n,"")}return h(n,e)+o+r}function I(e,t,n,o=!1,r=!1){return{back:e,current:t,forward:n,replaced:o,position:window.history.length,scroll:r?_():null}}function E(e){const t=function(e){const{history:t,location:n}=window,o={value:T(e,n)},r={value:t.state};function l(o,l,a){const s=e.indexOf("#"),i=s>-1?(n.host&&document.querySelector("base")?e:e.slice(s))+o:x()+e+o;try{t[a?"replaceState":"pushState"](l,"",i),r.value=l}catch(e){console.error(e),n[a?"replace":"assign"](i)}}return r.value||l(o.value,{back:null,current:o.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0),{location:o,state:r,push:function(e,n){const s=a({},r.value,t.state,{forward:e,scroll:_()});l(s.current,s,!0),l(e,a({},I(o.value,e,null),{position:s.position+1},n),!1),o.value=e},replace:function(e,n){l(e,a({},t.state,I(r.value.back,e,r.value.forward,!0),n,{position:r.value.position}),!0),o.value=e}}}(e=function(e){if(!e)if(l){const t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),p(e)}(e)),n=function(e,t,n,o){let r=[],l=[],s=null;const i=({state:l})=>{const a=T(e,location),i=n.value,c=t.value;let u=0;if(l){if(n.value=a,t.value=l,s&&s===i)return void(s=null);u=c?l.position-c.position:0}else o(a);r.forEach((e=>{e(n.value,i,{delta:u,type:y.pop,direction:u?u>0?b.forward:b.back:b.unknown})}))};function c(){const{history:e}=window;e.state&&e.replaceState(a({},e.state,{scroll:_()}),"")}return window.addEventListener("popstate",i),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:function(){s=n.value},listen:function(e){r.push(e);const t=()=>{const t=r.indexOf(e);t>-1&&r.splice(t,1)};return l.push(t),t},destroy:function(){for(const e of l)e();l=[],window.removeEventListener("popstate",i),window.removeEventListener("beforeunload",c)}}}(e,t.state,t.location,t.replace),o=a({location:"",base:e,go:function(e,t=!0){t||n.pauseListeners(),history.go(e)},createHref:k.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 A(e){return"string"==typeof e||"symbol"==typeof e}const F={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},L=Symbol("");var O;function M(e,t){return a(new Error,{type:e,[L]:!0},t)}function P(e,t){return e instanceof Error&&L in e&&(null==t||!!(e.type&t))}!function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"}(O||(O={}));const R="[^/]+?",H={sensitive:!1,strict:!1,start:!0,end:!0},$=/[.+*?^${}()[\]/\\]/g;function N(e,t){let n=0;for(;nt.length?1===t.length&&80===t[0]?1:-1:0}function D(e,t){let n=0;const o=e.score,r=t.score;for(;n0&&t[t.length-1]<0}const V={type:0,value:""},B=/[a-zA-Z0-9_]/;function z(e,t,n){const o=function(e,t){const n=a({},H,t),o=[];let r=n.start?"^":"";const l=[];for(const t of e){const e=t.length?[]:[90];n.strict&&!t.length&&(r+="/");for(let o=0;o1&&("*"===s||"+"===s)&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),l.push({type:1,value:c,regexp:u,repeatable:"*"===s||"+"===s,optional:"*"===s||"?"===s})):t("Invalid state to consume buffer"),c="")}function d(){c+=s}for(;ia(e,t.meta)),{})}function Y(e,t){const n={};for(const o in e)n[o]=o in t?t[o]:e[o];return n}function W(e,t){return t.children.some((t=>t===e||W(e,t)))}const G=/#/g,K=/&/g,X=/\//g,Q=/=/g,ee=/\?/g,te=/\+/g,ne=/%5B/g,oe=/%5D/g,re=/%5E/g,le=/%60/g,ae=/%7B/g,se=/%7C/g,ie=/%7D/g,ce=/%20/g;function ue(e){return encodeURI(""+e).replace(se,"|").replace(ne,"[").replace(oe,"]")}function pe(e){return ue(e).replace(te,"%2B").replace(ce,"+").replace(G,"%23").replace(K,"%26").replace(le,"`").replace(ae,"{").replace(ie,"}").replace(re,"^")}function de(e){return null==e?"":function(e){return ue(e).replace(G,"%23").replace(ee,"%3F")}(e).replace(X,"%2F")}function he(e){try{return decodeURIComponent(""+e)}catch(e){}return""+e}function fe(e){const t={};if(""===e||"?"===e)return t;const n=("?"===e[0]?e.slice(1):e).split("&");for(let e=0;ee&&pe(e))):[o&&pe(o)]).forEach((e=>{void 0!==e&&(t+=(t.length?"&":"")+n,null!=e&&(t+="="+e))})):void 0!==o&&(t+=(t.length?"&":"")+n)}return t}function me(e){const t={};for(const n in e){const o=e[n];void 0!==o&&(t[n]=c(o)?o.map((e=>null==e?null:""+e)):null==o?o:""+o)}return t}const ge=Symbol(""),ye=Symbol(""),be=Symbol(""),we=Symbol(""),ke=Symbol("");function _e(){let e=[];return{add:function(t){return e.push(t),()=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)}},list:()=>e.slice(),reset:function(){e=[]}}}function Se(e,t,n,o,r){const l=o&&(o.enterCallbacks[r]=o.enterCallbacks[r]||[]);return()=>new Promise(((a,s)=>{const i=e=>{var i;!1===e?s(M(4,{from:n,to:t})):e instanceof Error?s(e):"string"==typeof(i=e)||i&&"object"==typeof i?s(M(2,{from:t,to:e})):(l&&o.enterCallbacks[r]===l&&"function"==typeof e&&l.push(e),a())},c=e.call(o&&o.instances[r],t,n,i);let u=Promise.resolve(c);e.length<3&&(u=u.then(i)),u.catch((e=>s(e)))}))}function Ce(e,t,n,o){const r=[];for(const a of e)for(const e in a.components){let s=a.components[e];if("beforeRouteEnter"===t||a.instances[e])if("object"==typeof(l=s)||"displayName"in l||"props"in l||"__vccOpts"in l){const l=(s.__vccOpts||s)[t];l&&r.push(Se(l,n,o,a,e))}else{let l=s();r.push((()=>l.then((r=>{if(!r)return Promise.reject(new Error(`Couldn't resolve component "${e}" at "${a.path}"`));const l=(s=r).__esModule||"Module"===s[Symbol.toStringTag]?r.default:r;var s;a.components[e]=l;const i=(l.__vccOpts||l)[t];return i&&Se(i,n,o,a,e)()}))))}}var l;return r}function xe(e){const t=(0,o.f3)(be),n=(0,o.f3)(we),l=(0,o.Fl)((()=>t.resolve((0,r.SU)(e.to)))),a=(0,o.Fl)((()=>{const{matched:e}=l.value,{length:t}=e,o=e[t-1],r=n.matched;if(!o||!r.length)return-1;const a=r.findIndex(f.bind(null,o));if(a>-1)return a;const s=Ie(e[t-2]);return t>1&&Ie(o)===s&&r[r.length-1].path!==s?r.findIndex(f.bind(null,e[t-2])):a})),s=(0,o.Fl)((()=>a.value>-1&&function(e,t){for(const n in t){const o=t[n],r=e[n];if("string"==typeof o){if(o!==r)return!1}else if(!c(r)||r.length!==o.length||o.some(((e,t)=>e!==r[t])))return!1}return!0}(n.params,l.value.params))),u=(0,o.Fl)((()=>a.value>-1&&a.value===n.matched.length-1&&v(n.params,l.value.params)));return{route:l,href:(0,o.Fl)((()=>l.value.href)),isActive:s,isExactActive:u,navigate:function(n={}){return function(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey||e.defaultPrevented||void 0!==e.button&&0!==e.button)){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}}(n)?t[(0,r.SU)(e.replace)?"replace":"push"]((0,r.SU)(e.to)).catch(i):Promise.resolve()}}}const Te=(0,o.aZ)({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:xe,setup(e,{slots:t}){const n=(0,r.qj)(xe(e)),{options:l}=(0,o.f3)(be),a=(0,o.Fl)((()=>({[Ee(e.activeClass,l.linkActiveClass,"router-link-active")]:n.isActive,[Ee(e.exactActiveClass,l.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive})));return()=>{const r=t.default&&t.default(n);return e.custom?r:(0,o.h)("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:a.value},r)}}});function Ie(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Ee=(e,t,n)=>null!=e?e:null!=t?t:n;function Ae(e,t){if(!e)return null;const n=e(t);return 1===n.length?n[0]:n}const Fe=(0,o.aZ)({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const l=(0,o.f3)(ke),s=(0,o.Fl)((()=>e.route||l.value)),i=(0,o.f3)(ye,0),c=(0,o.Fl)((()=>{let e=(0,r.SU)(i);const{matched:t}=s.value;let n;for(;(n=t[e])&&!n.components;)e++;return e})),u=(0,o.Fl)((()=>s.value.matched[c.value]));(0,o.JJ)(ye,(0,o.Fl)((()=>c.value+1))),(0,o.JJ)(ge,u),(0,o.JJ)(ke,s);const p=(0,r.iH)();return(0,o.YP)((()=>[p.value,u.value,e.name]),(([e,t,n],[o,r,l])=>{t&&(t.instances[n]=e,r&&r!==t&&e&&e===o&&(t.leaveGuards.size||(t.leaveGuards=r.leaveGuards),t.updateGuards.size||(t.updateGuards=r.updateGuards))),!e||!t||r&&f(t,r)&&o||(t.enterCallbacks[n]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const r=s.value,l=e.name,i=u.value,c=i&&i.components[l];if(!c)return Ae(n.default,{Component:c,route:r});const d=i.props[l],h=d?!0===d?r.params:"function"==typeof d?d(r):d:null,f=(0,o.h)(c,a({},h,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[l]=null)},ref:p}));return Ae(n.default,{Component:f,route:r})||f}}});function Le(e){const t=function(e,t){const n=[],o=new Map;function r(e,n,o){const c=!o,u=function(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:q(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}(e);u.aliasOf=o&&o.record;const p=Y(t,e),d=[u];if("alias"in e){const t="string"==typeof e.alias?[e.alias]:e.alias;for(const e of t)d.push(a({},u,{components:o?o.record.components:u.components,path:e,aliasOf:o?o.record:u}))}let h,f;for(const t of d){const{path:a}=t;if(n&&"/"!==a[0]){const e=n.record.path,o="/"===e[e.length-1]?"":"/";t.path=n.record.path+(a&&o+a)}if(h=z(t,n,p),o?o.alias.push(h):(f=f||h,f!==h&&f.alias.push(h),c&&e.name&&!Z(h)&&l(e.name)),u.children){const e=u.children;for(let t=0;t{l(f)}:i}function l(e){if(A(e)){const t=o.get(e);t&&(o.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(l),t.alias.forEach(l))}else{const t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&o.delete(e.record.name),e.children.forEach(l),e.alias.forEach(l))}}function s(e){let t=0;for(;t=0&&(e.record.path!==n[t].record.path||!W(e,n[t]));)t++;n.splice(t,0,e),e.record.name&&!Z(e)&&o.set(e.record.name,e)}return t=Y({strict:!1,end:!0,sensitive:!1},t),e.forEach((e=>r(e))),{addRoute:r,resolve:function(e,t){let r,l,s,i={};if("name"in e&&e.name){if(r=o.get(e.name),!r)throw M(1,{location:e});s=r.record.name,i=a(U(t.params,r.keys.filter((e=>!e.optional)).map((e=>e.name))),e.params&&U(e.params,r.keys.map((e=>e.name)))),l=r.stringify(i)}else if("path"in e)l=e.path,r=n.find((e=>e.re.test(l))),r&&(i=r.parse(l),s=r.record.name);else{if(r=t.name?o.get(t.name):n.find((e=>e.re.test(t.path))),!r)throw M(1,{location:e,currentLocation:t});s=r.record.name,i=a({},t.params,e.params),l=r.stringify(i)}const c=[];let u=r;for(;u;)c.unshift(u.record),u=u.parent;return{name:s,path:l,params:i,matched:c,meta:J(c)}},removeRoute:l,getRoutes:function(){return n},getRecordMatcher:function(e){return o.get(e)}}}(e.routes,e),n=e.parseQuery||fe,u=e.stringifyQuery||ve,p=e.history,h=_e(),m=_e(),g=_e(),b=(0,r.XI)(F);let w=F;l&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const k=s.bind(null,(e=>""+e)),x=s.bind(null,de),T=s.bind(null,he);function I(e,o){if(o=a({},o||b.value),"string"==typeof e){const r=d(n,e,o.path),l=t.resolve({path:r.path},o),s=p.createHref(r.fullPath);return a(r,l,{params:T(l.params),hash:he(r.hash),redirectedFrom:void 0,href:s})}let r;if("path"in e)r=a({},e,{path:d(n,e.path,o.path).path});else{const t=a({},e.params);for(const e in t)null==t[e]&&delete t[e];r=a({},e,{params:x(t)}),o.params=x(o.params)}const l=t.resolve(r,o),s=e.hash||"";l.params=k(T(l.params));const i=function(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}(u,a({},e,{hash:(c=s,ue(c).replace(ae,"{").replace(ie,"}").replace(re,"^")),path:l.path}));var c;const h=p.createHref(i);return a({fullPath:i,hash:s,query:u===ve?me(e.query):e.query||{}},l,{redirectedFrom:void 0,href:h})}function E(e){return"string"==typeof e?d(n,e,b.value.path):a({},e)}function L(e,t){if(w!==e)return M(8,{from:t,to:e})}function O(e){return H(e)}function R(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:n}=t;let o="function"==typeof n?n(e):n;return"string"==typeof o&&(o=o.includes("?")||o.includes("#")?o=E(o):{path:o},o.params={}),a({query:e.query,hash:e.hash,params:"path"in o?{}:e.params},o)}}function H(e,t){const n=w=I(e),o=b.value,r=e.state,l=e.force,s=!0===e.replace,i=R(n);if(i)return H(a(E(i),{state:"object"==typeof i?a({},r,i.state):r,force:l,replace:s}),t||n);const c=n;let p;return c.redirectedFrom=t,!l&&function(e,t,n){const o=t.matched.length-1,r=n.matched.length-1;return o>-1&&o===r&&f(t.matched[o],n.matched[r])&&v(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}(u,o,n)&&(p=M(16,{to:c,from:o}),ne(o,o,!0,!1)),(p?Promise.resolve(p):j(c,o)).catch((e=>P(e)?P(e,2)?e:te(e):ee(e,c,o))).then((e=>{if(e){if(P(e,2))return H(a({replace:s},E(e.to),{state:"object"==typeof e.to?a({},r,e.to.state):r,force:l}),t||c)}else e=B(c,o,!0,s,r);return V(c,o,e),e}))}function $(e,t){const n=L(e,t);return n?Promise.reject(n):Promise.resolve()}function N(e){const t=se.values().next().value;return t&&"function"==typeof t.runWithContext?t.runWithContext(e):e()}function j(e,t){let n;const[o,r,l]=function(e,t){const n=[],o=[],r=[],l=Math.max(t.matched.length,e.matched.length);for(let a=0;af(e,l)))?o.push(l):n.push(l));const s=e.matched[a];s&&(t.matched.find((e=>f(e,s)))||r.push(s))}return[n,o,r]}(e,t);n=Ce(o.reverse(),"beforeRouteLeave",e,t);for(const r of o)r.leaveGuards.forEach((o=>{n.push(Se(o,e,t))}));const a=$.bind(null,e,t);return n.push(a),pe(n).then((()=>{n=[];for(const o of h.list())n.push(Se(o,e,t));return n.push(a),pe(n)})).then((()=>{n=Ce(r,"beforeRouteUpdate",e,t);for(const o of r)o.updateGuards.forEach((o=>{n.push(Se(o,e,t))}));return n.push(a),pe(n)})).then((()=>{n=[];for(const o of l)if(o.beforeEnter)if(c(o.beforeEnter))for(const r of o.beforeEnter)n.push(Se(r,e,t));else n.push(Se(o.beforeEnter,e,t));return n.push(a),pe(n)})).then((()=>(e.matched.forEach((e=>e.enterCallbacks={})),n=Ce(l,"beforeRouteEnter",e,t),n.push(a),pe(n)))).then((()=>{n=[];for(const o of m.list())n.push(Se(o,e,t));return n.push(a),pe(n)})).catch((e=>P(e,8)?e:Promise.reject(e)))}function V(e,t,n){g.list().forEach((o=>N((()=>o(e,t,n)))))}function B(e,t,n,o,r){const s=L(e,t);if(s)return s;const i=t===F,c=l?history.state:{};n&&(o||i?p.replace(e.fullPath,a({scroll:i&&c&&c.scroll},r)):p.push(e.fullPath,r)),b.value=e,ne(e,t,n,i),te()}let G;let K,X=_e(),Q=_e();function ee(e,t,n){te(e);const o=Q.list();return o.length?o.forEach((o=>o(e,t,n))):console.error(e),Promise.reject(e)}function te(e){return K||(K=!e,G||(G=p.listen(((e,t,n)=>{if(!ce.listening)return;const o=I(e),r=R(o);if(r)return void H(a(r,{replace:!0}),o).catch(i);w=o;const s=b.value;var c,u;l&&(c=S(s.fullPath,n.delta),u=_(),C.set(c,u)),j(o,s).catch((e=>P(e,12)?e:P(e,2)?(H(e.to,o).then((e=>{P(e,20)&&!n.delta&&n.type===y.pop&&p.go(-1,!1)})).catch(i),Promise.reject()):(n.delta&&p.go(-n.delta,!1),ee(e,o,s)))).then((e=>{(e=e||B(o,s,!1))&&(n.delta&&!P(e,8)?p.go(-n.delta,!1):n.type===y.pop&&P(e,20)&&p.go(-1,!1)),V(o,s,e)})).catch(i)}))),X.list().forEach((([t,n])=>e?n(e):t())),X.reset()),e}function ne(t,n,r,a){const{scrollBehavior:s}=e;if(!l||!s)return Promise.resolve();const i=!r&&function(e){const t=C.get(e);return C.delete(e),t}(S(t.fullPath,0))||(a||!r)&&history.state&&history.state.scroll||null;return(0,o.Y3)().then((()=>s(t,n,i))).then((e=>e&&function(e){let t;if("el"in e){const n=e.el,o="string"==typeof n&&n.startsWith("#"),r="string"==typeof n?o?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!r)return;t=function(e,t){const n=document.documentElement.getBoundingClientRect(),o=e.getBoundingClientRect();return{behavior:t.behavior,left:o.left-n.left-(t.left||0),top:o.top-n.top-(t.top||0)}}(r,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.pageXOffset,null!=t.top?t.top:window.pageYOffset)}(e))).catch((e=>ee(e,t,n)))}const oe=e=>p.go(e);let le;const se=new Set,ce={currentRoute:b,listening:!0,addRoute:function(e,n){let o,r;return A(e)?(o=t.getRecordMatcher(e),r=n):r=e,t.addRoute(r,o)},removeRoute:function(e){const n=t.getRecordMatcher(e);n&&t.removeRoute(n)},hasRoute:function(e){return!!t.getRecordMatcher(e)},getRoutes:function(){return t.getRoutes().map((e=>e.record))},resolve:I,options:e,push:O,replace:function(e){return O(a(E(e),{replace:!0}))},go:oe,back:()=>oe(-1),forward:()=>oe(1),beforeEach:h.add,beforeResolve:m.add,afterEach:g.add,onError:Q.add,isReady:function(){return K&&b.value!==F?Promise.resolve():new Promise(((e,t)=>{X.add([e,t])}))},install(e){e.component("RouterLink",Te),e.component("RouterView",Fe),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>(0,r.SU)(b)}),l&&!le&&b.value===F&&(le=!0,O(p.location).catch((e=>{})));const t={};for(const e in F)Object.defineProperty(t,e,{get:()=>b.value[e],enumerable:!0});e.provide(be,this),e.provide(we,(0,r.Um)(t)),e.provide(ke,b);const n=e.unmount;se.add(e),e.unmount=function(){se.delete(e),se.size<1&&(w=F,G&&G(),G=null,b.value=F,le=!1,K=!1),n()}}};function pe(e){return e.reduce(((e,t)=>e.then((()=>N(t)))),Promise.resolve())}return ce}function Oe(){return(0,o.f3)(be)}function Me(){return(0,o.f3)(we)}},5529:(e,t,n)=>{n.d(t,{Z:()=>u});var o=n(8102),r=n(5682),l=n(6252),a=n(2262),s=n(2201),i=n(1370),c=(0,l.aZ)({name:"AutoCatalog",props:{base:{type:String,default:""},level:{type:Number,default:3},index:Boolean,hideHeading:Boolean},setup(e){const t=(0,i.dO)(),n=(0,r.zT)({"/":{title:"Catalog",empty:"No catalog"}}),c=(0,o.Vi)(),u=(0,s.tv)(),p=(0,o.WF)(),d=(0,a.XI)(u.getRoutes().filter((({path:e})=>(0,r.pn)(e,".html")&&!(0,r.pn)(e,"/index.html")||(0,r.pn)(e,"/"))).map((({meta:e,path:n})=>{const o=t(e);if(!o)return null;const l=n.split("/").length;return{level:(0,r.pn)(n,"/")?l-2:l-1,base:n.replace(/\/[^/]+\/?$/,"/"),path:n,...o}})).filter((e=>(0,r.PO)(e)&&(0,r.HD)(e.title)))),h=(0,l.Fl)((()=>{const t=e.base?(0,r.e7)((0,r.ZO)(e.base)):c.value.path.replace(/\/[^/]+$/,"/"),n=t.split("/").length-2,o=[];return d.value.filter((({level:o,path:l})=>{if(!(0,r.Ny)(l,t)||l===t)return!1;if("/"===t){const e=(0,r.XP)(p.value.locales).filter((e=>"/"!==e));if("/404.html"===l||e.some((e=>(0,r.Ny)(l,e))))return!1}return o-n<=e.level})).sort((({title:e,level:t,order:n},{title:o,level:l,order:a})=>t-l||((0,r.hj)(n)?(0,r.hj)(a)?n>0?a>0?n-a:-1:a<0?n-a:1:n:(0,r.hj)(a)?a:e.localeCompare(o)))).forEach((e=>{const{base:t,level:r}=e;switch(r-n){case 1:o.push(e);break;case 2:{const n=o.find((e=>e.path===t));n&&(n.children??=[]).push(e);break}default:{const n=o.find((e=>e.path===t.replace(/\/[^/]+\/$/,"/")));if(n){const o=n.children?.find((e=>e.path===t));o&&(o.children??=[]).push(e)}}}})),o}));return()=>{const t=h.value.some((e=>e.children));return(0,l.h)("div",{class:["vp-catalog-wrapper",{index:e.index}]},[e.hideHeading?null:(0,l.h)("h2",{class:"vp-catalog-main-title"},n.value.title),h.value.length?(0,l.h)(e.index?"ol":"ul",{class:["vp-catalogs",{deep:t}]},h.value.map((({children:n=[],title:o,path:a,content:s})=>{const i=(0,l.h)(r.RG,{class:"vp-catalog-title",to:a},(()=>s?(0,l.h)(s):o));return(0,l.h)("li",{class:"vp-catalog"},t?[(0,l.h)("h3",{id:o,class:["vp-catalog-child-title",{"has-children":n.length}]},[(0,l.h)("a",{href:`#${o}`,class:"header-anchor","aria-hidden":!0},"#"),i]),n.length?(0,l.h)(e.index?"ol":"ul",{class:"vp-child-catalogs"},n.map((({children:t=[],content:n,path:o,title:a})=>(0,l.h)("li",{class:"vp-child-catalog"},[(0,l.h)("div",{class:["vp-catalog-sub-title",{"has-children":t.length}]},[(0,l.h)("a",{href:`#${a}`,class:"header-anchor"},"#"),(0,l.h)(r.RG,{class:"vp-catalog-title",to:o},(()=>n?(0,l.h)(n):a))]),t.length?(0,l.h)(e.index?"ol":"div",{class:e.index?"vp-sub-catalogs":"vp-sub-catalogs-wrapper"},t.map((({content:t,path:n,title:o})=>e.index?(0,l.h)("li",{class:"vp-sub-catalog"},(0,l.h)(r.RG,{to:n},(()=>t?(0,l.h)(t):o))):(0,l.h)(r.RG,{class:"vp-sub-catalog-link",to:n},(()=>t?(0,l.h)(t):o))))):null])))):null]:(0,l.h)("div",{class:"vp-catalog-child-title"},i))}))):(0,l.h)("p",{class:"vp-empty-catalog"},n.value.empty)])}}}),u=(0,o.r$)({enhance:({app:e})=>{(0,i.Mn)(e),(0,r.li)("AutoCatalog",e)||e.component("AutoCatalog",c)}})},1370:(e,t,n)=>{n.d(t,{Mn:()=>c,_V:()=>s,dO:()=>i});var o=n(6252),r=n(5682);let l=e=>(0,r.HD)(e.title)?{title:e.title}:null;const a=Symbol(""),s=e=>{l=e},i=()=>(0,o.f3)(a),c=e=>{e.provide(a,l)}},2378:(e,t,n)=>{n.d(t,{Z:()=>u});var o=n(6309),r=n(6252),l=n(2262),a=n(9963),s=n(8102),i=n(5682);const c=()=>(0,r.h)(i.A0,{name:"back-to-top"},(()=>[(0,r.h)("path",{d:"M512 843.2c-36.2 0-66.4-13.6-85.8-21.8-10.8-4.6-22.6 3.6-21.8 15.2l7 102c.4 6.2 7.6 9.4 12.6 5.6l29-22c3.6-2.8 9-1.8 11.4 2l41 64.2c3 4.8 10.2 4.8 13.2 0l41-64.2c2.4-3.8 7.8-4.8 11.4-2l29 22c5 3.8 12.2.6 12.6-5.6l7-102c.8-11.6-11-20-21.8-15.2-19.6 8.2-49.6 21.8-85.8 21.8z"}),(0,r.h)("path",{d:"m795.4 586.2-96-98.2C699.4 172 513 32 513 32S324.8 172 324.8 488l-96 98.2c-3.6 3.6-5.2 9-4.4 14.2L261.2 824c1.8 11.4 14.2 17 23.6 10.8L419 744s41.4 40 94.2 40c52.8 0 92.2-40 92.2-40l134.2 90.8c9.2 6.2 21.6.6 23.6-10.8l37-223.8c.4-5.2-1.2-10.4-4.8-14zM513 384c-34 0-61.4-28.6-61.4-64s27.6-64 61.4-64c34 0 61.4 28.6 61.4 64S547 384 513 384z"})]));c.displayName="BackToTopIcon";var u=(0,r.aZ)({name:"BackToTop",props:{threshold:{type:Number,default:100},noProgress:Boolean},setup(e){const t=(0,s.I2)(),n=(0,i.zT)({"/":{backToTop:"Back to top"}}),u=(0,l.XI)(),{height:p}=(0,o.h4X)(u),{height:d}=(0,o.iPe)(),{y:h}=(0,o.baj)(),f=(0,r.Fl)((()=>!1!==t.value.backToTop&&h.value>e.threshold)),v=(0,r.Fl)((()=>h.value/(p.value-d.value)*100));return(0,r.bv)((()=>{u.value=document.body})),()=>(0,r.h)(a.uT,{name:"fade"},(()=>f.value?(0,r.h)("button",{type:"button",class:"vp-back-to-top-button","aria-label":n.value.backToTop,"data-balloon-pos":"left",onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},[e.noProgress?null:(0,r.h)("span",{class:"vp-scroll-progress",role:"progressbar","aria-labelledby":"loadinglabel","aria-valuenow":v.value},(0,r.h)("svg",(0,r.h)("circle",{cx:"50%",cy:"50%",style:{"stroke-dasharray":`calc(${Math.PI*v.value}% - ${4*Math.PI}px) calc(${100*Math.PI}% - ${4*Math.PI}px)`}}))),(0,r.h)(c)]):null))}})},3349:(e,t,n)=>{n.d(t,{Z:()=>r});var o=n(6252);const r=({type:e="info",text:t="",vertical:n,color:r},{slots:l})=>(0,o.h)("span",{class:["vp-badge",e,{diy:r}],style:{verticalAlign:n??!1,backgroundColor:r??!1}},l.default?.()||t);r.displayName="Badge"},3340:(e,t,n)=>{n.d(t,{Z:()=>l});var o=n(6252),r=n(5682),l=(0,o.aZ)({name:"FontIcon",props:{icon:{type:String,default:""},color:{type:String,default:""},size:{type:[String,Number],default:""}},setup(e){const t=(0,o.Fl)((()=>{const t=["font-icon icon"],n=`${e.icon}`;return t.push(n),t})),n=(0,o.Fl)((()=>{const t={};return e.color&&(t.color=e.color),e.size&&(t["font-size"]=Number.isNaN(Number(e.size))?e.size:`${e.size}px`),(0,r.XP)(t).length?t:null}));return()=>e.icon?(0,o.h)("span",{key:e.icon,class:t.value,style:n.value}):null}})},2453:(e,t,n)=>{n.d(t,{Z:()=>u});var o=n(8102),r=n(6309),l=n(6252),a=n(5682);const s={"/":{copy:"Copy code",copied:"Copied",hint:"Copied successfully"}},i=['.theme-hope-content div[class*="language-"] pre'],c=new Map;var u=(0,o.r$)({setup:()=>{(()=>{const{copy:e}=(0,r.VPI)({legacy:!0}),t=(0,a.zT)(s),n=(0,o.Vi)(),u=(0,a.dD)(),p=e=>{if(!e.hasAttribute("copy-code-registered")){const n=document.createElement("button");n.type="button",n.classList.add("copy-code-button"),n.innerHTML='
',n.setAttribute("aria-label",t.value.copy),n.setAttribute("data-copied",t.value.copied),e.parentElement&&e.parentElement.insertBefore(n,e),e.setAttribute("copy-code-registered","")}},d=()=>{(0,l.Y3)().then((()=>setTimeout((()=>{i.forEach((e=>{document.querySelectorAll(e).forEach(p)}))}),800)))},h=(t,n,o)=>{let{innerText:r=""}=n;/language-(shellscript|shell|bash|sh|zsh)/.test(t.classList.toString())&&(r=r.replace(/^ *(\$|>) /gm,"")),e(r).then((()=>{o.classList.add("copied"),clearTimeout(c.get(o));const e=setTimeout((()=>{o.classList.remove("copied"),o.blur(),c.delete(o)}),2e3);c.set(o,e)}))};(0,l.bv)((()=>{!u.value&&d(),(0,r.ORN)("click",(e=>{const t=e.target;if(t.matches('div[class*="language-"] > button.copy')){const e=t.parentElement,n=t.nextElementSibling;n&&h(e,n,t)}else if(t.matches('div[class*="language-"] div.copy-icon')){const e=t.parentElement,n=e.parentElement,o=e.nextElementSibling;o&&h(n,o,e)}})),(0,l.YP)((()=>n.value.path),(()=>{!u.value&&d()}))}))})()}})},2369:(e,t,n)=>{n.d(t,{U:()=>r});var o=n(6309);const r=()=>{(0,o.ORN)("beforeprint",(()=>{document.querySelectorAll("details").forEach((e=>{e.open=!0}))}))}},7909:(e,t,n)=>{n.d(t,{Z:()=>p});var o=n(8102),r=n(6252);let l={};const a=Symbol("");var s=n(6309),i=n(5682);const c={"/":{closeTitle:"Close",downloadTitle:"Download Image",fullscreenTitle:"Switch to full screen",zoomTitle:"Zoom in/out",arrowPrevTitle:"Prev (Arrow Left)",arrowNextTitle:"Next (Arrow Right)"}},u=e=>new Promise(((t,n)=>{e.complete?t({type:"image",element:e,src:e.src,width:e.naturalWidth,height:e.naturalHeight,alt:e.alt,msrc:e.src}):(e.onload=()=>t(u(e)),e.onerror=e=>n(e))}));var p=(0,o.r$)({enhance:({app:e})=>{e.provide(a,l)},setup:()=>{(()=>{const e=(0,i.zT)(c),t=(0,o.I2)(),l=(0,o.Vi)(),{isSupported:p,toggle:d}=(0,s.O9U)(),h=(0,r.f3)(a);let f;const v=(0,r.Fl)((()=>!1!==t.value.photoSwipe&&(t.value.photoSwipe||".theme-hope-content :not(a) > img:not([no-view])"))),m=async()=>{if(v.value)return Promise.all([n.e(5826).then(n.bind(n,5826)),(0,r.Y3)().then((()=>new Promise((e=>setTimeout(e,800))).then((()=>(e=>(0,i.HD)(e)?Array.from(document.querySelectorAll(e)):e.map((e=>Array.from(document.querySelectorAll(e)))).flat())(v.value)))))]).then((([{default:t},n])=>{const o=n.map((e=>({html:'',element:e,msrc:e.src})));n.forEach(((n,r)=>{const l=()=>{f=new t({preloaderDelay:0,showHideAnimationType:"zoom",...e.value,...h,dataSource:o,index:r,closeOnVerticalDrag:!0,wheelToZoom:!1}),(e=>{e.on("uiRegister",(()=>{p&&e.ui.registerElement({name:"fullscreen",order:7,isButton:!0,html:' ',onClick:()=>{d()}}),e.ui.registerElement({name:"download",order:8,isButton:!0,tagName:"a",html:{isCustomSVG:!0,inner:' ',outlineID:"pswp__icn-download"},onInit:(e,t)=>{e.setAttribute("download",""),e.setAttribute("target","_blank"),e.setAttribute("rel","noopener"),t.on("change",(()=>{e.setAttribute("href",t.currSlide.data.src)}))}}),e.ui.registerElement({name:"bulletsIndicator",className:"photo-swipe-bullets-indicator",appendTo:"wrapper",onInit:(e,t)=>{const n=[];let o=-1;for(let o=0;o{t.goTo(n.indexOf(e.target))},n.push(o),e.appendChild(o)}t.on("change",(()=>{o>=0&&n[o].classList.remove("active"),n[t.currIndex].classList.add("active"),o=t.currIndex}))}})}))})(f),f.addFilter("thumbEl",(()=>n)),f.addFilter("placeholderSrc",(()=>n.src)),f.init()};n.style.cursor="zoom-in",n.addEventListener("click",(()=>{l()})),n.addEventListener("keypress",(({key:e})=>{"Enter"===e&&l()}))})),n.forEach(((e,t)=>{u(e).then((e=>{o.splice(t,1,e),f?.refreshSlideContent(t)}))}))}))};(0,r.bv)((()=>{(0,s.ORN)("wheel",(()=>{f?.close()})),(0,r.YP)((()=>l.value.path),m,{immediate:!0})}))})()}})},4319:(e,t,n)=>{n.d(t,{C:()=>d,H:()=>s,S:()=>p,T:()=>i,a:()=>l,b:()=>a,c:()=>c});var o=n(6252),r=n(5682);const l=()=>(0,o.h)(r.A0,{name:"heading"},(()=>(0,o.h)("path",{d:"M250.4 704.6H64V595.4h202.4l26.2-166.6H94V319.6h214.4L352 64h127.8l-43.6 255.4h211.2L691 64h126.2l-43.6 255.4H960v109.2H756.2l-24.6 166.6H930v109.2H717L672 960H545.8l43.6-255.4H376.6L333 960H206.8l43.6-255.4zm168.4-276L394 595.4h211.2l24.6-166.6h-211z"})));l.displayName="HeadingIcon";const a=()=>(0,o.h)(r.A0,{name:"heart"},(()=>(0,o.h)("path",{d:"M1024 358.156C1024 195.698 892.3 64 729.844 64c-86.362 0-164.03 37.218-217.844 96.49C458.186 101.218 380.518 64 294.156 64 131.698 64 0 195.698 0 358.156 0 444.518 37.218 522.186 96.49 576H96l320 320c32 32 64 64 96 64s64-32 96-64l320-320h-.49c59.272-53.814 96.49-131.482 96.49-217.844zM841.468 481.232 517.49 805.49a2981.962 2981.962 0 0 1-5.49 5.48c-1.96-1.95-3.814-3.802-5.49-5.48L182.532 481.234C147.366 449.306 128 405.596 128 358.156 128 266.538 202.538 192 294.156 192c47.44 0 91.15 19.366 123.076 54.532L512 350.912l94.768-104.378C638.696 211.366 682.404 192 729.844 192 821.462 192 896 266.538 896 358.156c0 47.44-19.368 91.15-54.532 123.076z"})));a.displayName="HeartIcon";const s=()=>(0,o.h)(r.A0,{name:"history"},(()=>(0,o.h)("path",{d:"M512 1024a512 512 0 1 1 512-512 512 512 0 0 1-512 512zm0-896a384 384 0 1 0 384 384 384 384 0 0 0-384-384zm192 448H512a64 64 0 0 1-64-64V320a64 64 0 0 1 128 0v128h128a64 64 0 0 1 0 128z"})));s.displayName="HistoryIcon";const i=()=>(0,o.h)(r.A0,{name:"title"},(()=>(0,o.h)("path",{d:"M512 256c70.656 0 134.656 28.672 180.992 75.008A254.933 254.933 0 0 1 768 512c0 83.968-41.024 157.888-103.488 204.48C688.96 748.736 704 788.48 704 832c0 105.984-86.016 192-192 192-106.048 0-192-86.016-192-192h128a64 64 0 1 0 128 0 64 64 0 0 0-64-64 255.19 255.19 0 0 1-181.056-75.008A255.403 255.403 0 0 1 256 512c0-83.968 41.024-157.824 103.488-204.544C335.04 275.264 320 235.584 320 192A192 192 0 0 1 512 0c105.984 0 192 85.952 192 192H576a64.021 64.021 0 0 0-128 0c0 35.328 28.672 64 64 64zM384 512c0 70.656 57.344 128 128 128s128-57.344 128-128-57.344-128-128-128-128 57.344-128 128z"})));i.displayName="TitleIcon";const c=()=>(0,o.h)(r.A0,{name:"search"},(()=>(0,o.h)("path",{d:"M192 480a256 256 0 1 1 512 0 256 256 0 0 1-512 0m631.776 362.496-143.2-143.168A318.464 318.464 0 0 0 768 480c0-176.736-143.264-320-320-320S128 303.264 128 480s143.264 320 320 320a318.016 318.016 0 0 0 184.16-58.592l146.336 146.368c12.512 12.48 32.768 12.48 45.28 0 12.48-12.512 12.48-32.768 0-45.28"})));c.displayName="SearchIcon";const u=()=>(0,o.h)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"32",height:"32",preserveAspectRatio:"xMidYMid",viewBox:"0 0 100 100"},[(0,o.h)("circle",{cx:"28",cy:"75",r:"11",fill:"currentColor"},(0,o.h)("animate",{attributeName:"fill-opacity",begin:"0s",dur:"1s",keyTimes:"0;0.2;1",repeatCount:"indefinite",values:"0;1;1"})),(0,o.h)("path",{fill:"none",stroke:"#88baf0","stroke-width":"10",d:"M28 47a28 28 0 0 1 28 28"},(0,o.h)("animate",{attributeName:"stroke-opacity",begin:"0.1s",dur:"1s",keyTimes:"0;0.2;1",repeatCount:"indefinite",values:"0;1;1"})),(0,o.h)("path",{fill:"none",stroke:"#88baf0","stroke-width":"10",d:"M28 25a50 50 0 0 1 50 50"},(0,o.h)("animate",{attributeName:"stroke-opacity",begin:"0.2s",dur:"1s",keyTimes:"0;0.2;1",repeatCount:"indefinite",values:"0;1;1"}))]);u.displayName="LoadingIcon";const p=({hint:e})=>(0,o.h)("div",{class:"search-pro-result-wrapper loading"},[(0,o.h)(u),e]);p.displayName="SearchLoading";const d=' '},9526:(e,t,n)=>{n.d(t,{Z:()=>m});var o=n(8102),r=n(1673),l=n(6309),a=n(2262),s=n(6252),i=n(5682),c=n(4319),u=n(808);const p=Symbol(""),d=u.d[0];var h=(0,s.aZ)({name:"SearchBox",setup(){const e=(0,i.zT)(u.a),t=(0,s.f3)(p),n=(0,a.iH)(!1),o=(0,s.Fl)((()=>d?[(n.value?["⌃","⇧","⌥","⌘"]:["Ctrl","Shift","Alt","Win"]).filter(((e,t)=>d[["ctrl","shift","alt","meta"][t]])),d.key.toUpperCase()]:null));return(0,l.ORN)("keydown",(e=>{!t.value&&(e=>u.d.some((t=>{const{key:n,ctrl:o=!1,shift:r=!1,alt:l=!1,meta:a=!1}=t;return n===e.key&&o===e.ctrlKey&&r===e.shiftKey&&l===e.altKey&&a===e.metaKey})))(e)&&!(e=>e instanceof Element&&document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")))(e.target)&&(e.preventDefault(),t.value=!0)})),(0,s.bv)((()=>{const{userAgent:e}=navigator;n.value=(0,i.cd)(e)||(0,i._2)(e)||(0,i.I)(e)})),()=>[(0,s.h)("button",{type:"button",class:"search-pro-button","aria-label":e.value.search,onClick:()=>{t.value=!0}},[(0,s.h)(c.c),(0,s.h)("div",{class:"search-pro-placeholder"},e.value.search),o.value?(0,s.h)("div",{class:"search-pro-key-hints"},o.value.map((e=>(0,s.h)("kbd",{class:"search-pro-key"},e)))):null])]}});const f=(0,s.RC)({loader:()=>Promise.all([n.e(7622),n.e(512)]).then(n.bind(n,512)),loadingComponent:()=>{const e=(0,i.zT)(u.a);return(0,s.h)(c.S,{hint:e.value.loading})}});var v=(0,s.aZ)({name:"SearchModal",setup(){const e=(0,s.f3)(p),t=(0,o.I5)(),n=(0,i.dD)(),d=(0,i.zT)(u.a),h=(0,a.iH)(""),{suggestions:v}=(e=>{const t=(0,a.iH)([]);if(u.e){const n=(0,u.u)(),l=(0,o.I)();(0,s.bv)((()=>{const o=(0,r.DI)((e=>{e?a({type:"suggest",query:e,locale:l.value,options:n}).then((n=>{t.value=n.length?(0,i.Ny)(n[0],e)&&!n[0].slice(e.length).includes(" ")?n:[e,...n]:[]})).catch((e=>{console.error(e)})):t.value=[]}),u.s.suggestDelay),{search:a,terminate:c}=(0,u.c)();(0,s.YP)([e,l],(()=>o(e.value)),{immediate:!0}),(0,s.Ah)((()=>{c()}))}))}return{suggestions:t}})(h),m=(0,a.iH)(!1),{index:g,prev:y,next:b}=((e,t=!1)=>{const n=(0,a.iH)(0),o=(0,s.Fl)((()=>e.value[n.value]));return(0,s.YP)(e,(()=>{t||(n.value=0)})),{index:n,item:o,prev:()=>{n.value=n.value>0?n.value-1:e.value.length-1},next:()=>{n.value=n.value{h.value=v.value[e],m.value=!1};return(0,l.ORN)("keydown",(t=>{m.value?"ArrowUp"===t.key?y():"ArrowDown"===t.key?b():"Enter"===t.key?_():"Escape"===t.key&&(m.value=!1):"Escape"===t.key&&(e.value=!1)})),(0,s.bv)((()=>{const t=(0,l.PrY)(document.body);(0,s.YP)(e,(async e=>{t.value=e,e&&(await(0,s.Y3)(),w.value?.focus())})),(0,l.i9H)(k,(()=>{m.value=!1})),(0,s.Ah)((()=>{t.value=!1}))})),()=>e.value?(0,s.h)("div",{class:"search-pro-modal-wrapper"},[(0,s.h)("div",{class:"search-pro-mask",onClick:()=>{e.value=!1,h.value=""}}),(0,s.h)("div",{class:"search-pro-modal"},[(0,s.h)("div",{class:"search-pro-box"},[(0,s.h)("form",[(0,s.h)("label",{for:"search-pro","aria-label":d.value.search},(0,s.h)(c.c)),(0,s.h)("input",{ref:w,type:"search",class:"search-pro-input",id:"search-pro",placeholder:d.value.placeholder,spellcheck:"false",autocapitalize:"off",autocomplete:"off",autocorrect:"off",name:`${t.value.title}-search`,value:h.value,"aria-controls":"search-pro-results",onKeydown:e=>{const{key:t}=e;v.value.length&&("Tab"===t?(_(),e.preventDefault()):("ArrowDown"===t||"ArrowUp"===t||"Escape"===t)&&e.preventDefault())},onInput:({target:e})=>{h.value=e.value,m.value=!0,g.value=0}}),h.value?(0,s.h)("button",{type:"reset",class:"search-pro-clear-button",innerHTML:c.C,onClick:()=>{h.value=""}}):null,u.e&&m.value&&v.value.length?(0,s.h)("ul",{class:"search-pro-suggestions",ref:k},v.value.map(((e,t)=>(0,s.h)("li",{class:["search-pro-suggestion",{active:t===g.value}],onClick:()=>{_(t)}},[(0,s.h)("kbd",{class:"search-pro-auto-complete",title:`Tab ${d.value.autocomplete}`},"Tab"),e])))):null]),(0,s.h)("button",{type:"button",class:"search-pro-close-button",onClick:()=>{e.value=!1,h.value=""}},d.value.cancel)]),(0,s.h)(f,{query:h.value,isFocusing:!m.value,onClose:()=>{e.value=!1},onUpdateQuery:e=>{h.value=e}}),n.value?null:(0,s.h)("div",{class:"search-pro-hints"},[(0,s.h)("span",{class:"search-pro-hint"},[(0,s.h)("kbd",{innerHTML:' '}),d.value.select]),(0,s.h)("span",{class:"search-pro-hint"},[(0,s.h)("kbd",{innerHTML:' '}),(0,s.h)("kbd",{innerHTML:' '}),d.value.navigate]),(0,s.h)("span",{class:"search-pro-hint"},[(0,s.h)("kbd",{innerHTML:' '}),d.value.exit])])])]):null}}),m=(0,o.r$)({enhance({app:e}){(0,u.i)(e),e.component("SearchBox",h)},setup(){(()=>{const e=(0,a.iH)(!1);(0,s.JJ)(p,e)})()},rootComponents:[v]})},808:(e,t,n)=>{n.d(t,{a:()=>i,b:()=>a,c:()=>h,d:()=>s,e:()=>l,i:()=>d,s:()=>r,u:()=>p});var o=n(6252);const r={searchDelay:150,suggestDelay:0,queryHistoryCount:5,resultHistoryCount:5,hotKeys:[{key:"k",ctrl:!0},{key:"/",ctrl:!0}],worker:"search-pro.worker.js"},l=!0,a={},s=r.hotKeys,i={"/":{cancel:"取消",placeholder:"搜索",search:"搜索",searching:"搜索中",defaultTitle:"Documentation",select:"选择",navigate:"切换",autocomplete:"to autocomplete",exit:"关闭",queryHistory:"Search History",resultHistory:"Result History",emptyHistory:"无搜索历史",emptyResult:"没有找到结果",loading:"正在加载搜索索引...",history:"搜索历史"}};let c={};const u=Symbol(""),p=()=>(0,o.f3)(u),d=e=>{e.provide(u,c)},h=()=>{const e=new Worker(`/${r.worker}`,{}),t=[];return e.addEventListener("message",(({data:e})=>{const{resolve:n}=t.shift();n(e)})),{search:n=>new Promise(((o,r)=>{e.postMessage(n),t.push({resolve:o,reject:r})})),terminate:()=>{e.terminate(),t.forEach((({reject:e})=>e(new Error("Worker has been terminated."))))}}}},5682:(e,t,n)=>{n.d(t,{A0:()=>i,Ai:()=>W,Au:()=>P,FY:()=>S,HD:()=>x,HZ:()=>z,H_:()=>B,I:()=>u,M0:()=>K,Ny:()=>I,PF:()=>w,PO:()=>k,Qi:()=>O,R8:()=>c,RG:()=>J,U1:()=>_,XP:()=>L,ZO:()=>m,Zr:()=>q,_2:()=>p,_3:()=>h,ai:()=>f,ak:()=>g,c9:()=>U,cO:()=>G,cd:()=>d,dD:()=>ee,e7:()=>v,fy:()=>Y,h1:()=>$,hj:()=>C,kJ:()=>T,kd:()=>X,li:()=>Q,n3:()=>H,pn:()=>E,qh:()=>A,sD:()=>N,sq:()=>F,tm:()=>b,v0:()=>D,zT:()=>te});var o=n(6252),r=n(2262),l=n(3577),a=n(2201),s=n(8102);const i=({name:e="",color:t="currentColor"},{slots:n})=>(0,o.h)("svg",{xmlns:"http://www.w3.org/2000/svg",class:["icon",`${e}-icon`],viewBox:"0 0 1024 1024",fill:t,"aria-label":`${e} icon`},n.default?.());i.displayName="IconBase";const c=(e,{slots:t})=>t.default?.(),u=e=>[/\((ipad);[-\w),; ]+apple/i,/applecoremedia\/[\w.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i].some((t=>t.test(e))),p=e=>[/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i,/cfnetwork\/.+darwin/i].some((t=>t.test(e))),d=e=>[/(mac os x) ?([\w. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+haiku)/i].some((t=>t.test(e))),h=(e="")=>{if(e){if("number"==typeof e)return new Date(e);const t=Date.parse(e.toString());if(!Number.isNaN(t))return new Date(t)}return null},f=(e,t)=>{let n=1;for(let t=0;t>6;return n+=n<<3,n^=n>>11,n%t};var v=e=>"/"===e[0]?e:`/${e}`,m=e=>"/"===e[e.length-1]||e.endsWith(".html")?e:`${e}/`,g=e=>/^(https?:)?\/\//.test(e),y=/.md((\?|#).*)?$/,b=(e,t="/")=>!(!g(e)&&(!e.startsWith("/")||e.startsWith(t)||y.test(e))),w=e=>/^[a-z][a-z0-9+.-]*:/.test(e),k=e=>"[object Object]"===Object.prototype.toString.call(e),_=e=>"/"===e[e.length-1]?e.slice(0,-1):e,S=e=>"/"===e[0]?e.slice(1):e;Object.prototype.toString;const C=e=>"number"==typeof e,x=e=>"string"==typeof e,T=Array.isArray,I=(e,t)=>x(e)&&e.startsWith(t),E=(e,t)=>x(e)&&e.endsWith(t),A=Object.entries,F=Object.fromEntries,L=Object.keys,O=(Object.values,e=>{const[t,n=""]=e.split("#");return t?`${(e=>(e.endsWith(".md")&&(e=`${e.slice(0,-3)}.html`),!e.endsWith("/")&&!e.endsWith(".html")&&(e=`${e}.html`),e.replace(/(^|\/)(?:README|index).html$/i,"$1")))(t)}${n?`#${n}`:""}`:e}),M=e=>k(e)&&x(e.name),P=(e,t=!1)=>e?T(e)?e.map((e=>x(e)?{name:e}:M(e)?e:null)).filter((e=>null!==e)):x(e)?[{name:e}]:M(e)?[e]:(console.error(`Expect "author" to be \`AuthorInfo[] | AuthorInfo | string[] | string ${t?"":"| false"} | undefined\`, but got`,e),[]):[],R=(e,t)=>{if(e){if(T(e)&&e.every(x))return e;if(x(e))return[e];console.error(`Expect ${t||"value"} to be \`string[] | string | undefined\`, but got`,e)}return[]},H=e=>R(e,"category"),$=e=>R(e,"tag"),N=e=>I(e,"/");class D{constructor(){this.messageElements={};const e="message-container",t=document.getElementById(e);t?this.containerElement=t:(this.containerElement=document.createElement("div"),this.containerElement.id=e,document.body.appendChild(this.containerElement))}pop(e,t=2e3){const n=document.createElement("div"),o=Date.now();return n.className="message move-in",n.innerHTML=e,this.containerElement.appendChild(n),this.messageElements[o]=n,t>0&&setTimeout((()=>{this.close(o)}),t),o}close(e){if(e){const t=this.messageElements[e];t.classList.remove("move-in"),t.classList.add("move-out"),t.addEventListener("animationend",(()=>{t.remove(),delete this.messageElements[e]}))}else L(this.messageElements).forEach((e=>this.close(Number(e))))}destroy(){document.body.removeChild(this.containerElement)}}const j=/#.*$/u,V=e=>decodeURI(e).replace(j,"").replace(/(index)?\.html$/i,"").replace(/(README|index)?\.md$/i,""),B=(e,t)=>{if(void 0===t)return!1;const n=V(e.path),o=V(t),r=(e=>{const t=j.exec(e);return t?t[0]:""})(t);return r?r===e.hash&&(!o||n===o):n===o},z=e=>g(e)?e:`https://github.com/${e}`,U=e=>!g(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,q=(e,...t)=>{const n=e.resolve(...t),o=n.matched[n.matched.length-1];if(!o?.redirect)return n;const{redirect:r}=o,l=(e=>"function"==typeof e)(r)?r(n):r,a=(e=>"string"==typeof e)(l)?{path:l}:l;return q(e,{hash:n.hash,query:n.query,params:n.params,...a})},Z=e=>{if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey||e.defaultPrevented||void 0!==e.button&&0!==e.button||e.currentTarget&&e.currentTarget.getAttribute("target")?.match(/\b_blank\b/i)))return e.preventDefault(),!0},J=((0,o.aZ)({name:"RouterLink",props:{to:{type:String,required:!0}},slots:Object,setup(e,{slots:t}){const n=(e=>{const t=(0,a.tv)(),n=(0,a.yj)(),l=(0,o.Fl)((()=>q(t,(0,r.SU)(e)))),s=(0,o.Fl)((()=>l.value.fullPath===n.fullPath));return{route:l,href:(0,o.Fl)((()=>l.value.href)),isActive:s,navigate:(n={})=>Z(n)?t.push((0,r.SU)(e)).catch():Promise.resolve()}})((0,r.Vh)(e,"to"));return()=>(0,o.h)("a",{class:["vp-link",{"vp-active":n.isActive.value}],href:n.href.value,onClick:n.navigate},t.default?.(n))}}),({to:e="",class:t="",...n},{slots:r})=>{const l=(0,a.tv)(),i=O(e);return(0,o.h)("a",{...n,class:["vp-link",t],href:I(i,"/")?(0,s.pJ)(i):i,onClick:(t={})=>Z(t)?l.push(e).catch():Promise.resolve()},r.default?.())});J.displayName="VPLink";const Y=()=>(0,o.h)(i,{name:"github"},(()=>(0,o.h)("path",{d:"M511.957 21.333C241.024 21.333 21.333 240.981 21.333 512c0 216.832 140.544 400.725 335.574 465.664 24.49 4.395 32.256-10.07 32.256-23.083 0-11.69.256-44.245 0-85.205-136.448 29.61-164.736-64.64-164.736-64.64-22.315-56.704-54.4-71.765-54.4-71.765-44.587-30.464 3.285-29.824 3.285-29.824 49.195 3.413 75.179 50.517 75.179 50.517 43.776 75.008 114.816 53.333 142.762 40.79 4.523-31.66 17.152-53.377 31.19-65.537-108.971-12.458-223.488-54.485-223.488-242.602 0-53.547 19.114-97.323 50.517-131.67-5.035-12.33-21.93-62.293 4.779-129.834 0 0 41.258-13.184 134.912 50.346a469.803 469.803 0 0 1 122.88-16.554c41.642.213 83.626 5.632 122.88 16.554 93.653-63.488 134.784-50.346 134.784-50.346 26.752 67.541 9.898 117.504 4.864 129.834 31.402 34.347 50.474 78.123 50.474 131.67 0 188.586-114.73 230.016-224.042 242.09 17.578 15.232 33.578 44.672 33.578 90.454v135.85c0 13.142 7.936 27.606 32.854 22.87C862.25 912.597 1002.667 728.747 1002.667 512c0-271.019-219.648-490.667-490.71-490.667z"})));Y.displayName="GitHubIcon";const W=()=>(0,o.h)(i,{name:"gitlab"},(()=>(0,o.h)("path",{d:"M229.333 78.688C223.52 62 199.895 62 193.895 78.688L87.958 406.438h247.5c-.188 0-106.125-327.75-106.125-327.75zM33.77 571.438c-4.875 15 .563 31.687 13.313 41.25l464.812 345L87.77 406.438zm301.5-165 176.813 551.25 176.812-551.25zm655.125 165-54-165-424.312 551.25 464.812-345c12.938-9.563 18.188-26.25 13.5-41.25zM830.27 78.688c-5.812-16.688-29.437-16.688-35.437 0l-106.125 327.75h247.5z"})));W.displayName="GitLabIcon";const G=()=>(0,o.h)(i,{name:"gitee"},(()=>(0,o.h)("path",{d:"M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm242.97-533.34H482.39a23.7 23.7 0 0 0-23.7 23.7l-.03 59.28c0 13.08 10.59 23.7 23.7 23.7h165.96a23.7 23.7 0 0 1 23.7 23.7v11.85a71.1 71.1 0 0 1-71.1 71.1H375.71a23.7 23.7 0 0 1-23.7-23.7V423.11a71.1 71.1 0 0 1 71.1-71.1h331.8a23.7 23.7 0 0 0 23.7-23.7l.06-59.25a23.73 23.73 0 0 0-23.7-23.73H423.11a177.78 177.78 0 0 0-177.78 177.75v331.83c0 13.08 10.62 23.7 23.7 23.7h349.62a159.99 159.99 0 0 0 159.99-159.99V482.33a23.7 23.7 0 0 0-23.7-23.7z"})));G.displayName="GiteeIcon";const K=()=>(0,o.h)(i,{name:"bitbucket"},(()=>(0,o.h)("path",{d:"M575.256 490.862c6.29 47.981-52.005 85.723-92.563 61.147-45.714-20.004-45.714-92.562-1.133-113.152 38.29-23.442 93.696 7.424 93.696 52.005zm63.451-11.996c-10.276-81.152-102.29-134.839-177.152-101.156-47.433 21.138-79.433 71.424-77.129 124.562 2.853 69.705 69.157 126.866 138.862 120.576S647.3 548.571 638.708 478.83zm136.558-309.723c-25.161-33.134-67.986-38.839-105.728-45.13-106.862-17.151-216.576-17.7-323.438 1.134-35.438 5.706-75.447 11.996-97.719 43.996 36.572 34.304 88.576 39.424 135.424 45.129 84.553 10.862 171.447 11.447 256 .585 47.433-5.705 99.987-10.276 135.424-45.714zm32.585 591.433c-16.018 55.99-6.839 131.438-66.304 163.986-102.29 56.576-226.304 62.867-338.87 42.862-59.43-10.862-129.135-29.696-161.72-85.723-14.3-54.858-23.442-110.848-32.585-166.84l3.438-9.142 10.276-5.157c170.277 112.567 408.576 112.567 579.438 0 26.844 8.01 6.84 40.558 6.29 60.014zm103.424-549.157c-19.42 125.148-41.728 249.71-63.415 374.272-6.29 36.572-41.728 57.162-71.424 72.558-106.862 53.724-231.424 62.866-348.562 50.286-79.433-8.558-160.585-29.696-225.134-79.433-30.28-23.443-30.28-63.415-35.986-97.134-20.005-117.138-42.862-234.277-57.161-352.585 6.839-51.42 64.585-73.728 107.447-89.71 57.16-21.138 118.272-30.866 178.87-36.571 129.134-12.58 261.157-8.01 386.304 28.562 44.581 13.13 92.563 31.415 122.844 69.705 13.714 17.7 9.143 40.01 6.29 60.014z"})));K.displayName="BitbucketIcon";const X=()=>(0,o.h)(i,{name:"source"},(()=>(0,o.h)("path",{d:"M601.92 475.2c0 76.428-8.91 83.754-28.512 99.594-14.652 11.88-43.956 14.058-78.012 16.434-18.81 1.386-40.392 2.97-62.172 6.534-18.612 2.97-36.432 9.306-53.064 17.424V299.772c37.818-21.978 63.36-62.766 63.36-109.692 0-69.894-56.826-126.72-126.72-126.72S190.08 120.186 190.08 190.08c0 46.926 25.542 87.714 63.36 109.692v414.216c-37.818 21.978-63.36 62.766-63.36 109.692 0 69.894 56.826 126.72 126.72 126.72s126.72-56.826 126.72-126.72c0-31.086-11.286-59.598-29.7-81.576 13.266-9.504 27.522-17.226 39.996-19.206 16.038-2.574 32.868-3.762 50.688-5.148 48.312-3.366 103.158-7.326 148.896-44.55 61.182-49.698 74.25-103.158 75.24-187.902V475.2h-126.72zM316.8 126.72c34.848 0 63.36 28.512 63.36 63.36s-28.512 63.36-63.36 63.36-63.36-28.512-63.36-63.36 28.512-63.36 63.36-63.36zm0 760.32c-34.848 0-63.36-28.512-63.36-63.36s28.512-63.36 63.36-63.36 63.36 28.512 63.36 63.36-28.512 63.36-63.36 63.36zM823.68 158.4h-95.04V63.36h-126.72v95.04h-95.04v126.72h95.04v95.04h126.72v-95.04h95.04z"})));X.displayName="SourceIcon";const Q=(e,t)=>{const n=(t?._instance||(0,o.FN)())?.appContext.components;return!!n&&(e in n||(0,l._A)(e)in n||(0,l.kC)((0,l._A)(e))in n)},ee=()=>{const e=function(e){return function(){const e=(0,r.iH)(!1);(0,o.FN)()&&(0,o.bv)((()=>{e.value=!0}))}(),(0,o.Fl)((()=>!!e()))}((()=>typeof window<"u"&&window.navigator&&"userAgent"in window.navigator));return(0,o.Fl)((()=>e.value&&/\b(?:Android|iPhone)/i.test(navigator.userAgent)))},te=e=>{const t=(0,s.I)();return(0,o.Fl)((()=>e[t.value]))}},6291:(e,t,n)=>{n.d(t,{eF:()=>C,Ar:()=>St,TX:()=>xt,bc:()=>O,KT:()=>M,fR:()=>Z,P$:()=>at});var o=n(2201),r=n(5682),l=n(6309),a=n(1673),s=n(6252),i=n(2262),c=n(9963),u=n(8102);const p=()=>{const e=(0,u.Vi)();return(0,s.Fl)((()=>e.value.readingTime??null))},d=typeof{"/":{word:"About $word words",less1Minute:"Less than 1 minute",time:"About $time min"}}>"u"?null:{"/":{word:"About $word words",less1Minute:"Less than 1 minute",time:"About $time min"}},h={words:"",time:""},f=()=>{if(typeof d>"u")return(0,s.Fl)((()=>h));const e=p(),t=d?(0,r.zT)(d):(0,s.Fl)((()=>null));return(0,s.Fl)((()=>e.value&&t.value?((e,t)=>{const{minutes:n,words:o}=e,{less1Minute:r,word:l,time:a}=t;return{time:n<1?r:a.replace("$time",Math.round(n).toString()),words:l.replace("$word",o.toString())}})(e.value,t.value):h))};var v=n(395);const m=()=>(0,v.BV)(),g=()=>(0,v.X6)(),y=()=>{const e=m();return(0,s.Fl)((()=>!!e.value.pure))};var b=(0,s.aZ)({name:"EmptyComponent",setup:()=>()=>null}),w=n(9567);const k={mobileBreakPoint:"719px",pcBreakPoint:"1440px",enableThemeColor:"false"};var _=n(1246);const S=e=>{const{icon:t="",color:n,size:o}=e,l=n||o?{}:null;return n&&(l.color=n),o&&(l.height=Number.isNaN(Number(o))?o:`${o}px`),(0,r.ak)(t)?(0,s.h)("img",{class:"icon",src:t,alt:"","no-view":"",style:l}):(0,r.sD)(t)?(0,s.h)("img",{class:"icon",src:(0,u.pJ)(t),alt:"","aria-hidden":"","no-view":"",style:l}):(0,s.h)((0,s.up)("FontIcon"),e)};S.displayName="HopeIcon";var C=S;const x=()=>{const e=g(),t=(0,u.I2)();return(0,s.Fl)((()=>{const{author:n}=t.value;return n?(0,r.Au)(n):!1===n?[]:(0,r.Au)(e.value.author,!1)}))},{mobileBreakPoint:T,pcBreakPoint:I}=k,E=e=>e.endsWith("px")?Number(e.slice(0,-2)):null,A=()=>{const e=(0,i.iH)(!1),t=(0,i.iH)(!1),n=()=>{e.value=window.innerWidth<=(E(T)??719),t.value=window.innerWidth>=(E(I)??1440)};return(0,s.bv)((()=>{n(),(0,l.ORN)("resize",n,!1),(0,l.ORN)("orientationchange",n,!1)})),{isMobile:e,isPC:t}},F=Symbol(""),L=()=>{const e=(0,s.f3)(F);if(!e)throw new Error("useDarkmode() is called without provider.");return e},O=e=>{const t=m(),n=(0,l.QA3)(),o=(0,s.Fl)((()=>t.value.darkmode||"switch")),r=(0,l.y$C)("vuepress-theme-hope-scheme","auto"),a=(0,s.Fl)((()=>{const e=o.value;return"disable"!==e&&("enable"===e||("auto"===e?n.value:"toggle"===e?"dark"===r.value:"dark"===r.value||"auto"===r.value&&n.value))})),i=(0,s.Fl)((()=>{const e=o.value;return"switch"===e||"toggle"===e}));e.provide(F,{canToggle:i,config:o,isDarkmode:a,status:r}),Object.defineProperties(e.config.globalProperties,{$isDarkmode:{get:()=>a.value}})},M=()=>{const{config:e,isDarkmode:t,status:n}=L();(0,s.m0)((()=>{"disable"===e.value?n.value="light":"enable"===e.value&&(n.value="dark")})),(0,s.bv)((()=>{(0,s.YP)(t,(e=>document.documentElement.setAttribute("data-theme",e?"dark":"light")),{immediate:!0})}))};var P=(0,s.aZ)({name:"AutoLink",inheritAttrs:!1,props:{config:{type:Object,required:!0},exact:Boolean,noExternalLinkIcon:Boolean},emits:["focusout"],slots:Object,setup(e,{attrs:t,emit:n,slots:l}){const a=(0,o.yj)(),c=(0,u.WF)(),p=(0,i.Vh)(e,"config"),d=(0,s.Fl)((()=>(0,r.ak)(p.value.link))),h=(0,s.Fl)((()=>!d.value&&(0,r.PF)(p.value.link))),f=(0,s.Fl)((()=>p.value.target||(d.value?"_blank":void 0))),v=(0,s.Fl)((()=>"_blank"===f.value)),m=(0,s.Fl)((()=>!d.value&&!h.value&&!v.value)),g=(0,s.Fl)((()=>p.value.rel||(v.value?"noopener noreferrer":void 0))),y=(0,s.Fl)((()=>p.value.ariaLabel||p.value.text)),b=(0,s.Fl)((()=>{if(e.exact)return!1;const t=(0,r.XP)(c.value.locales);return t.length?t.every((e=>e!==p.value.link)):"/"!==p.value.link})),k=(0,s.Fl)((()=>!!m.value&&(p.value.activeMatch?new RegExp(p.value.activeMatch).test(a.path):b.value?(0,r.Ny)(a.path,p.value.link):a.path===p.value.link)));return()=>{const{before:o,after:a,default:i}=l,{text:c,icon:u,link:d}=p.value;return m.value?(0,s.h)(r.RG,{to:d,"aria-label":y.value,...t,class:["nav-link",{active:k.value},t.class],onFocusout:()=>n("focusout")},(()=>i?i():[o?o():(0,s.h)(C,{icon:u}),c,a?.()])):(0,s.h)("a",{href:d,rel:g.value,target:f.value,"aria-label":y.value,...t,class:["nav-link",t.class],onFocusout:()=>n("focusout")},i?i():[o?o():(0,s.h)(C,{icon:u}),c,e.noExternalLinkIcon?null:(0,s.h)(w.h),a?.()])}}});const R=(e,t,n=!1)=>"activeMatch"in t?new RegExp(t.activeMatch).test(e.path):!!(0,r.H_)(e,t.link)||!(!t.children||n)&&t.children.some((t=>R(e,t))),H=(e,t)=>"group"===t.type&&(t.children.some((t=>"group"===t.type?H(e,t):"page"===t.type&&R(e,t,!0)))||"prefix"in t&&(0,r.H_)(e,t.prefix)),$=(e,t)=>(0,r.HD)(e.link)?(0,s.h)(P,{...t,config:e}):(0,s.h)("p",t,[(0,s.h)(C,{icon:e.icon}),e.text]),N=e=>{const t=(0,o.yj)();return e?(0,s.h)("ul",{class:"vp-sidebar-sub-headers"},e.map((e=>(0,s.h)("li",{class:"vp-sidebar-sub-header"},[$(e,{class:["vp-sidebar-link","vp-heading",{active:R(t,e,!0)}]}),N(e.children)])))):null};var D=(e=>(e.type="y",e.title="t",e.shortTitle="s",e.icon="i",e.author="a",e.date="d",e.localizedDate="l",e.category="c",e.tag="g",e.isEncrypted="n",e.isOriginal="o",e.readingTime="r",e.excerpt="e",e.sticky="u",e.cover="v",e.index="I",e.order="O",e))(D||{}),j=(e=>(e.article="a",e.home="h",e.slide="s",e.page="p",e))(j||{});const V=(e="",t="")=>(0,r.sD)(t)?t:`${(0,r.ZO)(e)}${t}`,B=(e,t,n=!1)=>{let o=(0,r.Zr)(e,(0,r.Qi)(encodeURI(t)));"404"===o.name&&(o=(0,r.Zr)(e,t));const{fullPath:l,meta:a,name:s}=o;return{text:!n&&a[D.shortTitle]?a[D.shortTitle]:a[D.title]||t,link:"404"===s?t:l,...a[D.icon]?{icon:a[D.icon]}:{}}},z=(e,t,n)=>n>0?t.map((t=>({type:"heading",text:t.title,link:`${e.path}#${t.slug}`,children:z(e,t.children,n-1)}))):[],U=({config:e,router:t,page:n,headerDepth:o,prefix:l=""})=>{const a=(e,s=l)=>{const i=(0,r.HD)(e)?B(t,V(s,e)):e.link?{...e,...(0,r.tm)(e.link)?{}:{link:B(t,V(s,e.link)).link}}:e;if("children"in i){const e=V(s,i.prefix),t="structure"===i.children?_.G[e]:i.children;return{type:"group",...i,prefix:e,children:t.map((t=>a(t,e)))}}return{type:"page",...i,children:i.link===n.path?z(n,1===n.headers[0]?.level?n.headers[0].children:n.headers,o):[]}};return e.map((e=>a(e)))},q=Symbol(""),Z=()=>{const e=(0,u.I2)(),t=g(),n=(0,u.Vi)(),l=(0,u.I)(),i=(0,o.tv)(),c=(0,s.Fl)((()=>!e.value.home&&(e.value.sidebar??t.value.sidebar??"structure"))),p=(0,s.Fl)((()=>e.value.headerDepth??t.value.headerDepth??2)),d=(0,a.fA)((()=>[c.value,p.value,n.value.path,null]),(()=>(({config:e,router:t,routeLocale:n,page:o,headerDepth:l})=>"heading"===e?z(o,o.headers,l):"structure"===e?U({config:_.G[n],router:t,page:o,headerDepth:l,prefix:n}):(0,r.kJ)(e)?U({config:e,router:t,page:o,headerDepth:l}):(0,r.PO)(e)?(({config:e,router:t,page:n,headerDepth:o})=>{const l=(0,r.XP)(e).sort(((e,t)=>t.length-e.length));for(const a of l)if((0,r.Ny)(decodeURI(n.path),a)){const r=e[a];return r?U({config:"structure"===r?_.G[a]:"heading"===r?z(n,n.headers,o):r,router:t,page:n,headerDepth:o,prefix:a}):[]}return console.warn(`${n.path} is missing sidebar config.`),[]})({config:e,router:t,page:o,headerDepth:l}):[])({config:c.value,router:i,routeLocale:l.value,page:n.value,headerDepth:p.value})));(0,s.JJ)(q,d)},J=()=>{const e=(0,s.f3)(q);if(!e)throw new Error("useSidebarItems() is called without provider.");return e};var Y=(0,s.aZ)({name:"PageFooter",setup(){const e=m(),t=g(),n=(0,u.I2)(),o=x(),l=(0,s.Fl)((()=>{const{copyright:e,footer:o}=n.value;return!1!==o&&!!(e||o||t.value.displayFooter)})),a=(0,s.Fl)((()=>{const{footer:e}=n.value;return!1!==e&&((0,r.HD)(e)?e:t.value.footer||"")})),i=(0,s.Fl)((()=>o.value.map((({name:e})=>e)).join(", "))),c=e=>`Copyright © ${(new Date).getFullYear()} ${i.value} ${e?`${e} Licensed`:""}`,p=(0,s.Fl)((()=>{const{copyright:o,license:l=""}=n.value,{license:a}=e.value,{copyright:s}=t.value;return o??(l?c(l):(0,r.HD)(s)?s:!(!i.value&&!a)&&c(a))}));return()=>l.value?(0,s.h)("footer",{class:"vp-footer-wrapper"},[a.value?(0,s.h)("div",{class:"vp-footer",innerHTML:a.value}):null,p.value?(0,s.h)("div",{class:"vp-copyright",innerHTML:p.value}):null]):null}}),W=(0,s.aZ)({name:"NavbarDropdownLink",props:{config:{type:Object,required:!0}},slots:Object,setup(e,{slots:t}){const n=(0,u.Vi)(),o=(0,i.Vh)(e,"config"),r=(0,s.Fl)((()=>o.value.ariaLabel||o.value.text)),l=(0,i.iH)(!1);(0,s.YP)((()=>n.value.path),(()=>{l.value=!1}));const a=e=>{0===e.detail&&(l.value=!l.value)};return()=>(0,s.h)("div",{class:["dropdown-wrapper",{open:l.value}]},[(0,s.h)("button",{type:"button",class:"dropdown-title","aria-label":r.value,onClick:a},[t.title?.()||(0,s.h)("span",{class:"title"},[(0,s.h)(C,{icon:o.value.icon}),e.config.text]),(0,s.h)("span",{class:"arrow"}),(0,s.h)("ul",{class:"nav-dropdown"},o.value.children.map(((e,t)=>{const n=t===o.value.children.length-1;return(0,s.h)("li",{class:"dropdown-item"},"children"in e?[(0,s.h)("h4",{class:"dropdown-subtitle"},e.link?(0,s.h)(P,{config:e,onFocusout:()=>{0===e.children.length&&n&&(l.value=!1)}}):(0,s.h)("span",e.text)),(0,s.h)("ul",{class:"dropdown-subitem-wrapper"},e.children.map(((t,o)=>(0,s.h)("li",{class:"dropdown-subitem"},(0,s.h)(P,{config:t,onFocusout:()=>{o===e.children.length-1&&n&&(l.value=!1)}})))))]:(0,s.h)(P,{config:e,onFocusout:()=>{n&&(l.value=!1)}}))})))])])}});const G=()=>(0,s.h)(r.A0,{name:"i18n"},(()=>[(0,s.h)("path",{d:"M379.392 460.8 494.08 575.488l-42.496 102.4L307.2 532.48 138.24 701.44l-71.68-72.704L234.496 460.8l-45.056-45.056c-27.136-27.136-51.2-66.56-66.56-108.544h112.64c7.68 14.336 16.896 27.136 26.112 35.84l45.568 46.08 45.056-45.056C382.976 312.32 409.6 247.808 409.6 204.8H0V102.4h256V0h102.4v102.4h256v102.4H512c0 70.144-37.888 161.28-87.04 210.944L378.88 460.8zM576 870.4 512 1024H409.6l256-614.4H768l256 614.4H921.6l-64-153.6H576zM618.496 768h196.608L716.8 532.48 618.496 768z"})]));G.displayName="I18nIcon";const K=(e,t,n="")=>(0,r.HD)(t)?B(e,V(n,t)):"children"in t?{...t,...t.link&&!(0,r.tm)(t.link)?B(e,V(n,t.link)):{},children:t.children.map((o=>K(e,o,V(n,t.prefix))))}:{...t,link:(0,r.tm)(t.link)?t.link:B(e,V(n,t.link)).link},X=()=>{const e=g(),t=(0,o.tv)();return(0,a.fA)((()=>e.value.navbar),(()=>(e.value.navbar||[]).map((e=>K(t,e)))))};(0,s.aZ)({name:"LanguageDropdown",setup(){const e=(()=>{const e=(0,o.tv)(),t=(0,o.yj)(),n=(0,u.I)(),l=(0,u.I5)(),s=m(),i=g();return(0,a.fA)((()=>t.path),(()=>{const o=(0,r.XP)(l.value.locales),a=(0,r.qh)(s.value.extraLocales??{});if(o.length<2&&!a.length)return null;const{path:c,fullPath:u}=t,{navbarLocales:p}=i.value;return{text:"",ariaLabel:p?.selectLangAriaLabel,children:[...o.map((t=>{const o=l.value.locales?.[t]??{},r=s.value.locales?.[t]??{},a=o.lang||"",i=r.navbarLocales?.langName??a;let p;if(a===l.value.lang)p=c;else{const o=c.replace(n.value,t);p=e.getRoutes().some((e=>e.path===o))?u.replace(c,o):r.home??t}return{text:i,link:p}})),...a.map((([e,o])=>({text:e,link:o.replace(":route",t.path.replace(n.value,""))})))]}}))})();return()=>e.value?(0,s.h)("div",{class:"nav-item"},(0,s.h)(W,{class:"i18n-dropdown",config:e.value},{title:()=>(0,s.h)(G,{"aria-label":e.value?.ariaLabel,style:{width:"1rem",height:"1rem",verticalAlign:"middle"}})})):null}});var Q=(0,s.aZ)({name:"NavScreenDropdown",props:{config:{type:Object,required:!0}},setup(e){const t=(0,u.Vi)(),n=(0,i.Vh)(e,"config"),o=(0,s.Fl)((()=>n.value.ariaLabel||n.value.text)),r=(0,i.iH)(!1);(0,s.YP)((()=>t.value.path),(()=>{r.value=!1}));const l=(e,t)=>t[t.length-1]===e;return()=>[(0,s.h)("button",{type:"button",class:["nav-screen-dropdown-title",{active:r.value}],"aria-label":o.value,onClick:()=>{r.value=!r.value}},[(0,s.h)("span",{class:"title"},[(0,s.h)(C,{icon:n.value.icon}),e.config.text]),(0,s.h)("span",{class:["arrow",r.value?"down":"end"]})]),(0,s.h)("ul",{class:["nav-screen-dropdown",{hide:!r.value}]},n.value.children.map((e=>(0,s.h)("li",{class:"dropdown-item"},"children"in e?[(0,s.h)("h4",{class:"dropdown-subtitle"},e.link?(0,s.h)(P,{config:e,onFocusout:()=>{l(e,n.value.children)&&0===e.children.length&&(r.value=!1)}}):(0,s.h)("span",e.text)),(0,s.h)("ul",{class:"dropdown-subitem-wrapper"},e.children.map((t=>(0,s.h)("li",{class:"dropdown-subitem"},(0,s.h)(P,{config:t,onFocusout:()=>{l(t,e.children)&&l(e,n.value.children)&&(r.value=!1)}})))))]:(0,s.h)(P,{config:e,onFocusout:()=>{l(e,n.value.children)&&(r.value=!1)}})))))]}}),ee=(0,s.aZ)({name:"NavScreenLinks",setup(){const e=X();return()=>e.value.length?(0,s.h)("nav",{class:"nav-screen-links"},e.value.map((e=>(0,s.h)("div",{class:"navbar-links-item"},"children"in e?(0,s.h)(Q,{config:e}):(0,s.h)(P,{config:e}))))):null}});const te=()=>(0,s.h)(r.A0,{name:"dark"},(()=>(0,s.h)("path",{d:"M524.8 938.667h-4.267a439.893 439.893 0 0 1-313.173-134.4 446.293 446.293 0 0 1-11.093-597.334A432.213 432.213 0 0 1 366.933 90.027a42.667 42.667 0 0 1 45.227 9.386 42.667 42.667 0 0 1 10.24 42.667 358.4 358.4 0 0 0 82.773 375.893 361.387 361.387 0 0 0 376.747 82.774 42.667 42.667 0 0 1 54.187 55.04 433.493 433.493 0 0 1-99.84 154.88 438.613 438.613 0 0 1-311.467 128z"})));te.displayName="DarkIcon";const ne=()=>(0,s.h)(r.A0,{name:"light"},(()=>(0,s.h)("path",{d:"M952 552h-80a40 40 0 0 1 0-80h80a40 40 0 0 1 0 80zM801.88 280.08a41 41 0 0 1-57.96-57.96l57.96-58a41.04 41.04 0 0 1 58 58l-58 57.96zM512 752a240 240 0 1 1 0-480 240 240 0 0 1 0 480zm0-560a40 40 0 0 1-40-40V72a40 40 0 0 1 80 0v80a40 40 0 0 1-40 40zm-289.88 88.08-58-57.96a41.04 41.04 0 0 1 58-58l57.96 58a41 41 0 0 1-57.96 57.96zM192 512a40 40 0 0 1-40 40H72a40 40 0 0 1 0-80h80a40 40 0 0 1 40 40zm30.12 231.92a41 41 0 0 1 57.96 57.96l-57.96 58a41.04 41.04 0 0 1-58-58l58-57.96zM512 832a40 40 0 0 1 40 40v80a40 40 0 0 1-80 0v-80a40 40 0 0 1 40-40zm289.88-88.08 58 57.96a41.04 41.04 0 0 1-58 58l-57.96-58a41 41 0 0 1 57.96-57.96z"})));ne.displayName="LightIcon";const oe=()=>(0,s.h)(r.A0,{name:"auto"},(()=>(0,s.h)("path",{d:"M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm0-840c-198.78 0-360 161.22-360 360 0 198.84 161.22 360 360 360s360-161.16 360-360c0-198.78-161.22-360-360-360zm0 660V212c165.72 0 300 134.34 300 300 0 165.72-134.28 300-300 300z"})));oe.displayName="AutoIcon";const re=()=>(0,s.h)(r.A0,{name:"enter-fullscreen"},(()=>(0,s.h)("path",{d:"M762.773 90.24h-497.28c-96.106 0-174.4 78.293-174.4 174.4v497.28c0 96.107 78.294 174.4 174.4 174.4h497.28c96.107 0 175.04-78.293 174.4-174.4V264.64c0-96.213-78.186-174.4-174.4-174.4zm-387.2 761.173H215.04c-21.867 0-40.427-17.92-41.067-41.066V649.92c0-22.507 17.92-40.427 40.427-40.427 11.307 0 21.227 4.694 28.48 11.947 7.253 7.253 11.947 17.92 11.947 28.48v62.293l145.28-145.28c15.893-15.893 41.813-15.893 57.706 0 15.894 15.894 15.894 41.814 0 57.707l-145.28 145.28h62.294c22.506 0 40.426 17.92 40.426 40.427s-17.173 41.066-39.68 41.066zM650.24 165.76h160.427c21.866 0 40.426 17.92 41.066 41.067v160.426c0 22.507-17.92 40.427-40.426 40.427-11.307 0-21.227-4.693-28.48-11.947-7.254-7.253-11.947-17.92-11.947-28.48v-62.186L625.6 450.347c-15.893 15.893-41.813 15.893-57.707 0-15.893-15.894-15.893-41.814 0-57.707l145.28-145.28H650.88c-22.507 0-40.427-17.92-40.427-40.427s17.174-41.173 39.787-41.173z"})));re.displayName="EnterFullScreenIcon";const le=()=>(0,s.h)(r.A0,{name:"cancel-fullscreen"},(()=>(0,s.h)("path",{d:"M778.468 78.62H247.922c-102.514 0-186.027 83.513-186.027 186.027V795.08c0 102.514 83.513 186.027 186.027 186.027h530.432c102.514 0 186.71-83.513 186.026-186.027V264.647C964.494 162.02 880.981 78.62 778.468 78.62zM250.88 574.35h171.122c23.324 0 43.122 19.115 43.804 43.805v171.121c0 24.008-19.114 43.122-43.122 43.122-12.06 0-22.641-5.006-30.378-12.743s-12.743-19.115-12.743-30.379V722.83L224.597 877.91c-16.953 16.952-44.6 16.952-61.553 0-16.953-16.954-16.953-44.602 0-61.554L318.009 661.39h-66.446c-24.007 0-43.122-19.114-43.122-43.122 0-24.12 18.432-43.918 42.439-43.918zm521.899-98.873H601.657c-23.325 0-43.122-19.114-43.805-43.804V260.55c0-24.007 19.115-43.122 43.122-43.122 12.06 0 22.642 5.007 30.379 12.743s12.743 19.115 12.743 30.38v66.445l154.965-154.965c16.953-16.953 44.601-16.953 61.554 0 16.953 16.953 16.953 44.6 0 61.554L705.536 388.55h66.446c24.007 0 43.122 19.115 43.122 43.122.114 24.007-18.318 43.804-42.325 43.804z"})));le.displayName="CancelFullScreenIcon";const ae=()=>(0,s.h)(r.A0,{name:"outlook"},(()=>[(0,s.h)("path",{d:"M224 800c0 9.6 3.2 44.8 6.4 54.4 6.4 48-48 76.8-48 76.8s80 41.6 147.2 0 134.4-134.4 38.4-195.2c-22.4-12.8-41.6-19.2-57.6-19.2C259.2 716.8 227.2 761.6 224 800zM560 675.2l-32 51.2c-51.2 51.2-83.2 32-83.2 32 25.6 67.2 0 112-12.8 128 25.6 6.4 51.2 9.6 80 9.6 54.4 0 102.4-9.6 150.4-32l0 0c3.2 0 3.2-3.2 3.2-3.2 22.4-16 12.8-35.2 6.4-44.8-9.6-12.8-12.8-25.6-12.8-41.6 0-54.4 60.8-99.2 137.6-99.2 6.4 0 12.8 0 22.4 0 12.8 0 38.4 9.6 48-25.6 0-3.2 0-3.2 3.2-6.4 0-3.2 3.2-6.4 3.2-6.4 6.4-16 6.4-16 6.4-19.2 9.6-35.2 16-73.6 16-115.2 0-105.6-41.6-198.4-108.8-268.8C704 396.8 560 675.2 560 675.2zM224 419.2c0-28.8 22.4-51.2 51.2-51.2 28.8 0 51.2 22.4 51.2 51.2 0 28.8-22.4 51.2-51.2 51.2C246.4 470.4 224 448 224 419.2zM320 284.8c0-22.4 19.2-41.6 41.6-41.6 22.4 0 41.6 19.2 41.6 41.6 0 22.4-19.2 41.6-41.6 41.6C339.2 326.4 320 307.2 320 284.8zM457.6 208c0-12.8 12.8-25.6 25.6-25.6 12.8 0 25.6 12.8 25.6 25.6 0 12.8-12.8 25.6-25.6 25.6C470.4 233.6 457.6 220.8 457.6 208zM128 505.6C128 592 153.6 672 201.6 736c28.8-60.8 112-60.8 124.8-60.8-16-51.2 16-99.2 16-99.2l316.8-422.4c-48-19.2-99.2-32-150.4-32C297.6 118.4 128 291.2 128 505.6zM764.8 86.4c-22.4 19.2-390.4 518.4-390.4 518.4-22.4 28.8-12.8 76.8 22.4 99.2l9.6 6.4c35.2 22.4 80 12.8 99.2-25.6 0 0 6.4-12.8 9.6-19.2 54.4-105.6 275.2-524.8 288-553.6 6.4-19.2-3.2-32-19.2-32C777.6 76.8 771.2 80 764.8 86.4z"})]));ae.displayName="OutlookIcon";var se=(0,s.aZ)({name:"AppearanceSwitch",setup(){const{config:e,isDarkmode:t,status:n}=L(),o=y(),r=()=>{"switch"===e.value?n.value={light:"dark",dark:"auto",auto:"light"}[n.value]:n.value="light"===n.value?"dark":"light"},l=async e=>{if(!document.startViewTransition||window.matchMedia("(prefers-reduced-motion: reduce)").matches||o.value||!e)return void r();const n=e.clientX,l=e.clientY,a=Math.hypot(Math.max(n,innerWidth-n),Math.max(l,innerHeight-l)),i=t.value;await document.startViewTransition((async()=>{r(),await(0,s.Y3)()})).ready,t.value!==i&&document.documentElement.animate({clipPath:t.value?[`circle(${a}px at ${n}px ${l}px)`,`circle(0px at ${n}px ${l}px)`]:[`circle(0px at ${n}px ${l}px)`,`circle(${a}px at ${n}px ${l}px)`]},{duration:400,pseudoElement:t.value?"::view-transition-old(root)":"::view-transition-new(root)"})};return()=>(0,s.h)("button",{type:"button",id:"appearance-switch",onClick:l},[(0,s.h)(oe,{style:{display:"auto"===n.value?"block":"none"}}),(0,s.h)(te,{style:{display:"dark"===n.value?"block":"none"}}),(0,s.h)(ne,{style:{display:"light"===n.value?"block":"none"}})])}}),ie=(0,s.aZ)({name:"AppearanceMode",setup(){const e=g(),{canToggle:t}=L(),n=(0,s.Fl)((()=>e.value.outlookLocales.darkmode));return()=>t.value?(0,s.h)("div",{class:"appearance-wrapper"},[(0,s.h)("label",{class:"appearance-title",for:"appearance-switch"},n.value),(0,s.h)(se)]):null}});const ce="VUEPRESS_THEME_COLOR";var ue=(0,s.aZ)({name:"ThemeColorPicker",props:{themeColor:{type:Object,required:!0}},setup(e){const t=(t="")=>{const n=document.documentElement.classList,o=(0,r.XP)(e.themeColor);if(!t)return localStorage.removeItem(ce),void n.remove(...o);n.remove(...o.filter((e=>e!==t))),n.add(t),localStorage.setItem(ce,t)};return(0,s.bv)((()=>{const e=localStorage.getItem(ce);e&&t(e)})),()=>(0,s.h)("ul",{id:"theme-color-picker"},[(0,s.h)("li",(0,s.h)("span",{class:"theme-color",onClick:()=>t()})),(0,r.qh)(e.themeColor).map((([e,n])=>(0,s.h)("li",(0,s.h)("span",{style:{background:n},onClick:()=>t(e)}))))])}});const pe="true"===k.enableThemeColor,de=pe?(0,r.sq)((0,r.qh)(k).filter((([e])=>e.startsWith("theme-")))):{};var he=(0,s.aZ)({name:"ThemeColor",setup(){const e=g(),t=(0,s.Fl)((()=>e.value.outlookLocales.themeColor));return()=>pe?(0,s.h)("div",{class:"theme-color-wrapper"},[(0,s.h)("label",{class:"theme-color-title",for:"theme-color-picker"},t.value),(0,s.h)(ue,{themeColor:de})]):null}}),fe=(0,s.aZ)({name:"ToggleFullScreenButton",setup(){const e=g(),{isSupported:t,isFullscreen:n,toggle:o}=(0,l.O9U)(),r=(0,s.Fl)((()=>e.value.outlookLocales.fullscreen));return()=>t?(0,s.h)("div",{class:"full-screen-wrapper"},[(0,s.h)("label",{class:"full-screen-title",for:"full-screen-switch"},r.value),(0,s.h)("button",{type:"button",id:"full-screen-switch",class:"full-screen",ariaPressed:n.value,onClick:()=>o()},n.value?(0,s.h)(le):(0,s.h)(re))]):null}}),ve=(0,s.aZ)({name:"OutlookSettings",setup(){const e=m(),t=y(),n=(0,s.Fl)((()=>!t.value&&e.value.fullscreen));return()=>(0,s.h)(u.qx,(()=>[pe?(0,s.h)(he):null,(0,s.h)(ie),n.value?(0,s.h)(fe):null]))}}),me=(0,s.aZ)({name:"NavScreen",props:{show:Boolean},emits:["close"],slots:Object,setup(e,{emit:t,slots:n}){const o=(0,u.Vi)(),{isMobile:r}=A(),a=(0,i.XI)(),p=(0,l.PrY)(a);return(0,s.bv)((()=>{a.value=document.body,(0,s.YP)(r,(n=>{!n&&e.show&&(p.value=!1,t("close"))})),(0,s.YP)((()=>o.value.path),(()=>{p.value=!1,t("close")}))})),(0,s.Ah)((()=>{p.value=!1})),()=>(0,s.h)(c.uT,{name:"fade",onEnter:()=>{p.value=!0},onAfterLeave:()=>{p.value=!1}},(()=>e.show?(0,s.h)("div",{id:"nav-screen"},(0,s.h)("div",{class:"vp-nav-screen-container"},[n.before?.(),(0,s.h)(ee),(0,s.h)("div",{class:"vp-outlook-wrapper"},(0,s.h)(ve)),n.after?.()])):null))}}),ge=(0,s.aZ)({name:"NavbarBrand",setup(){const e=(0,u.I)(),t=(0,u.I5)(),n=g(),o=(0,s.Fl)((()=>n.value.home||e.value)),l=(0,s.Fl)((()=>t.value.title)),a=(0,s.Fl)((()=>n.value.navTitle??l.value)),i=(0,s.Fl)((()=>n.value.logo?(0,u.pJ)(n.value.logo):null)),c=(0,s.Fl)((()=>n.value.logoDark?(0,u.pJ)(n.value.logoDark):null));return()=>(0,s.h)(r.RG,{to:o.value,class:"vp-brand"},(()=>[i.value?(0,s.h)("img",{class:["vp-nav-logo",{light:!!c.value}],src:i.value,alt:""}):null,c.value?(0,s.h)("img",{class:["vp-nav-logo dark"],src:c.value,alt:""}):null,a.value?(0,s.h)("span",{class:["vp-site-name",{"hide-in-pad":i.value&&!1!==n.value.hideSiteNameOnMobile}]},a.value):null]))}}),ye=(0,s.aZ)({name:"NavbarLinks",setup(){const e=X();return()=>e.value.length?(0,s.h)("nav",{class:"vp-nav-links"},e.value.map((e=>(0,s.h)("div",{class:"nav-item hide-in-mobile"},"children"in e?(0,s.h)(W,{config:e}):(0,s.h)(P,{config:e}))))):null}}),be=(0,s.aZ)({name:"RepoLink",components:{BitbucketIcon:r.M0,GiteeIcon:r.cO,GitHubIcon:r.fy,GitLabIcon:r.Ai,SourceIcon:r.kd},setup(){const e=(()=>{const e=g(),t=(0,s.Fl)((()=>e.value.repo||null)),n=(0,s.Fl)((()=>t.value?(0,r.HZ)(t.value):null)),o=(0,s.Fl)((()=>t.value?(0,r.c9)(t.value):null)),l=(0,s.Fl)((()=>n.value?e.value.repoLabel??(null===o.value?"Source":o.value):null));return(0,s.Fl)((()=>n.value&&l.value&&!1!==e.value.repoDisplay?{type:o.value||"Source",label:l.value,link:n.value}:null))})();return()=>e.value?(0,s.h)("div",{class:"nav-item vp-repo"},(0,s.h)("a",{class:"vp-repo-link",href:e.value.link,target:"_blank",rel:"noopener noreferrer","aria-label":e.value.label},(0,s.h)((0,s.up)(`${e.value.type}Icon`),{style:{width:"1.25rem",height:"1.25rem",verticalAlign:"middle"}}))):null}});const we=({active:e=!1},{emit:t})=>(0,s.h)("button",{type:"button",class:["vp-toggle-navbar-button",{"is-active":e}],"aria-label":"Toggle Navbar","aria-expanded":e,"aria-controls":"nav-screen",onClick:()=>t("toggle")},(0,s.h)("span",[(0,s.h)("span",{class:"vp-top"}),(0,s.h)("span",{class:"vp-middle"}),(0,s.h)("span",{class:"vp-bottom"})]));we.displayName="ToggleNavbarButton";var ke=we;const _e=(e,{emit:t})=>(0,s.h)("button",{type:"button",class:"vp-toggle-sidebar-button",title:"Toggle Sidebar",onClick:()=>t("toggle")},(0,s.h)("span",{class:"icon"}));_e.displayName="ToggleSidebarButton",_e.emits=["toggle"];var Se=_e,Ce=(0,s.aZ)({name:"OutlookButton",setup(){const{isSupported:e}=(0,l.O9U)(),t=m(),n=y(),o=(0,u.Vi)(),{canToggle:r}=L(),a=(0,i.iH)(!1),c=(0,s.Fl)((()=>!n.value&&t.value.fullscreen&&e));return(0,s.YP)((()=>o.value.path),(()=>{a.value=!1})),()=>r.value||c.value||pe?(0,s.h)("div",{class:"nav-item hide-in-mobile"},!r.value||c.value||pe?!c.value||r.value||pe?(0,s.h)("button",{type:"button",class:["outlook-button",{open:a.value}],tabindex:"-1","aria-hidden":!0},[(0,s.h)(ae),(0,s.h)("div",{class:"outlook-dropdown"},(0,s.h)(ve))]):(0,s.h)(fe):(0,s.h)(se)):null}}),xe=(0,s.aZ)({name:"NavBar",emits:["toggleSidebar"],slots:Object,setup(e,{emit:t,slots:n}){const o=g(),{isMobile:l}=A(),a=(0,i.iH)(!1),c=(0,s.Fl)((()=>{const{navbarAutoHide:e="mobile"}=o.value;return"none"!==e&&("always"===e||l.value)})),u=(0,s.Fl)((()=>o.value.navbarLayout||{start:["Brand"],center:["Links"],end:["Language","Repo","Outlook","Search"]})),p={Brand:ge,Language:b,Links:ye,Repo:be,Outlook:Ce,Search:(0,r.li)("Docsearch")?(0,s.up)("Docsearch"):(0,r.li)("SearchBox")?(0,s.up)("SearchBox"):b},d=e=>p[e]??((0,r.li)(e)?(0,s.up)(e):b);return()=>[(0,s.h)("header",{id:"navbar",class:["vp-navbar",{"auto-hide":c.value,"hide-icon":!1===o.value.navbarIcon}]},[(0,s.h)("div",{class:"vp-navbar-start"},[(0,s.h)(Se,{onToggle:()=>{a.value&&(a.value=!1),t("toggleSidebar")}}),n.startBefore?.(),(u.value.start||[]).map((e=>(0,s.h)(d(e)))),n.startAfter?.()]),(0,s.h)("div",{class:"vp-navbar-center"},[n.centerBefore?.(),(u.value.center||[]).map((e=>(0,s.h)(d(e)))),n.centerAfter?.()]),(0,s.h)("div",{class:"vp-navbar-end"},[n.endBefore?.(),(u.value.end||[]).map((e=>(0,s.h)(d(e)))),n.endAfter?.(),(0,s.h)(ke,{active:a.value,onToggle:()=>{a.value=!a.value}})])]),(0,s.h)(me,{show:a.value,onClose:()=>{a.value=!1}},{before:()=>n.screenTop?.(),after:()=>n.screenBottom?.()})]}}),Te=(0,s.aZ)({name:"SidebarChild",props:{config:{type:Object,required:!0}},setup(e){const t=(0,o.yj)();return()=>[$(e.config,{class:["vp-sidebar-link",`vp-sidebar-${e.config.type}`,{active:R(t,e.config,!0)}],exact:!0}),N(e.config.children)]}}),Ie=(0,s.aZ)({name:"SidebarGroup",props:{config:{type:Object,required:!0},open:{type:Boolean,required:!0}},emits:["toggle"],setup(e,{emit:t}){const n=(0,o.yj)(),r=(0,s.Fl)((()=>R(n,e.config))),l=(0,s.Fl)((()=>R(n,e.config,!0)));return()=>{const{collapsible:n,children:o=[],icon:a,prefix:i,link:c,text:u}=e.config;return(0,s.h)("section",{class:"vp-sidebar-group"},[(0,s.h)(n?"button":"p",{class:["vp-sidebar-heading",{clickable:n||c,exact:l.value,active:r.value}],...n?{type:"button",onClick:()=>t("toggle"),onKeydown:e=>{"Enter"===e.key&&t("toggle")}}:{}},[(0,s.h)(C,{icon:a}),c?(0,s.h)(P,{class:"vp-sidebar-title",config:{text:u,link:c},noExternalLinkIcon:!0}):(0,s.h)("span",{class:"vp-sidebar-title"},u),n?(0,s.h)("span",{class:["vp-arrow",e.open?"down":"end"]}):null]),e.open||!n?(0,s.h)(Ee,{key:i,config:o}):null])}}}),Ee=(0,s.aZ)({name:"SidebarLinks",props:{config:{type:Array,required:!0}},setup(e){const t=(0,o.yj)(),n=(0,i.iH)(-1);return(0,s.YP)((()=>t.path),(()=>{const o=e.config.findIndex((e=>H(t,e)));n.value=o}),{immediate:!0,flush:"post"}),()=>(0,s.h)("ul",{class:"vp-sidebar-links"},e.config.map(((e,t)=>(0,s.h)("li","group"===e.type?(0,s.h)(Ie,{config:e,open:t===n.value,onToggle:()=>(e=>{n.value=e===n.value?-1:e})(t)}):(0,s.h)(Te,{config:e})))))}}),Ae=(0,s.aZ)({name:"SideBar",slots:Object,setup(e,{slots:t}){const n=(0,o.yj)(),r=g(),l=J(),a=(0,i.XI)();return(0,s.bv)((()=>{(0,s.YP)((()=>n.hash),(e=>{const t=document.querySelector(`.vp-sidebar a.vp-sidebar-link[href="${n.path}${e}"]`);if(!t)return;const{top:o,height:r}=a.value.getBoundingClientRect(),{top:l,height:s}=t.getBoundingClientRect();lo+r&&t.scrollIntoView(!1)}),{immediate:!0})})),()=>(0,s.h)("aside",{ref:a,id:"sidebar",class:["vp-sidebar",{"hide-icon":!1===r.value.sidebarIcon}]},[t.top?.(),t.default?.()||(0,s.h)(Ee,{config:l.value}),t.bottom?.()])}}),Fe=(0,s.aZ)({name:"CommonWrapper",props:{containerClass:{type:String,default:""},noNavbar:Boolean,noSidebar:Boolean,noToc:Boolean},slots:Object,setup(e,{slots:t}){const n=(0,o.tv)(),p=(0,u.Vi)(),d=(0,u.I2)(),h=g(),{isMobile:f,isPC:v}=A(),[m,y]=(0,a.OT)(!1),[b,w]=(0,a.OT)(!1),k=J(),_=(0,i.iH)(!1),S=(0,s.Fl)((()=>!e.noNavbar&&!1!==d.value.navbar&&!1!==h.value.navbar&&!!(p.value.title||h.value.logo||h.value.repo||h.value.navbar))),C=(0,s.Fl)((()=>!e.noSidebar&&!1!==d.value.sidebar&&0!==k.value.length&&!d.value.home)),x=(0,s.Fl)((()=>!e.noToc&&!d.value.home&&(d.value.toc||!1!==h.value.toc&&!1!==d.value.toc))),T={x:0,y:0},I=e=>{T.x=e.changedTouches[0].clientX,T.y=e.changedTouches[0].clientY},E=e=>{const t=e.changedTouches[0].clientX-T.x,n=e.changedTouches[0].clientY-T.y;Math.abs(t)>1.5*Math.abs(n)&&Math.abs(t)>40&&(t>0&&T.x<=80?y(!0):y(!1))};let F=0;return(0,l.ORN)("scroll",(0,a.vA)((()=>{const e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;e<=58||e{e||y(!1)})),(0,s.bv)((()=>{const e=(0,l.PrY)(document.body);(0,s.YP)(m,(t=>{e.value=t}));const t=n.afterEach((()=>{y(!1)}));(0,s.Ah)((()=>{e.value=!1,t()}))})),()=>(0,s.h)((0,r.li)("GlobalEncrypt")?(0,s.up)("GlobalEncrypt"):r.R8,(()=>(0,s.h)("div",{class:["theme-container",{"no-navbar":!S.value,"no-sidebar":!C.value&&!(t.sidebar||t.sidebarTop||t.sidebarBottom),"has-toc":x.value,"hide-navbar":_.value,"sidebar-collapsed":!f.value&&!v.value&&b.value,"sidebar-open":f.value&&m.value},e.containerClass,d.value.containerClass||""],onTouchStart:I,onTouchEnd:E},[S.value?(0,s.h)(xe,{onToggleSidebar:()=>y()},{startBefore:()=>t.navbarStartBefore?.(),startAfter:()=>t.navbarStartAfter?.(),centerBefore:()=>t.navbarCenterBefore?.(),centerAfter:()=>t.navbarCenterAfter?.(),endBefore:()=>t.navbarEndBefore?.(),endAfter:()=>t.navbarEndAfter?.(),screenTop:()=>t.navScreenTop?.(),screenBottom:()=>t.navScreenBottom?.()}):null,(0,s.h)(c.uT,{name:"fade"},(()=>m.value?(0,s.h)("div",{class:"vp-sidebar-mask",onClick:()=>y(!1)}):null)),(0,s.h)(c.uT,{name:"fade"},(()=>f.value?null:(0,s.h)("div",{class:"toggle-sidebar-wrapper",onClick:()=>w()},(0,s.h)("span",{class:["arrow",b.value?"end":"start"]})))),(0,s.h)(Ae,{},{...t.sidebar?{default:()=>t.sidebar()}:{},top:()=>t.sidebarTop?.(),bottom:()=>t.sidebarBottom?.()}),t.default(),(0,s.h)(Y)])))}}),Le=(0,s.aZ)({name:"DropTransition",props:{type:{type:String,default:"single"},delay:{type:Number,default:0},duration:{type:Number,default:.25},appear:Boolean},slots:Object,setup(e,{slots:t}){const n=t=>{t.style.transition=`transform ${e.duration}s ease-in-out ${e.delay}s, opacity ${e.duration}s ease-in-out ${e.delay}s`,t.style.transform="translateY(-20px)",t.style.opacity="0"},o=e=>{e.style.transform="translateY(0)",e.style.opacity="1"};return()=>(0,s.h)("single"===e.type?c.uT:c.W3,{name:"drop",appear:e.appear,onAppear:n,onAfterAppear:o,onEnter:n,onAfterEnter:o,onBeforeLeave:n},(()=>t.default()))}});const Oe=({custom:e})=>(0,s.h)(u.VY,{class:["theme-hope-content",{custom:e}]});Oe.displayName="MarkdownContent",Oe.props={custom:Boolean};var Me=Oe;const Pe=()=>(0,s.h)(r.A0,{name:"author"},(()=>(0,s.h)("path",{d:"M649.6 633.6c86.4-48 147.2-144 147.2-249.6 0-160-128-288-288-288s-288 128-288 288c0 108.8 57.6 201.6 147.2 249.6-121.6 48-214.4 153.6-240 288-3.2 9.6 0 19.2 6.4 25.6 3.2 9.6 12.8 12.8 22.4 12.8h704c9.6 0 19.2-3.2 25.6-12.8 6.4-6.4 9.6-16 6.4-25.6-25.6-134.4-121.6-240-243.2-288z"})));Pe.displayName="AuthorIcon";const Re=()=>(0,s.h)(r.A0,{name:"calendar"},(()=>(0,s.h)("path",{d:"M716.4 110.137c0-18.753-14.72-33.473-33.472-33.473-18.753 0-33.473 14.72-33.473 33.473v33.473h66.993v-33.473zm-334.87 0c0-18.753-14.72-33.473-33.473-33.473s-33.52 14.72-33.52 33.473v33.473h66.993v-33.473zm468.81 33.52H716.4v100.465c0 18.753-14.72 33.473-33.472 33.473a33.145 33.145 0 01-33.473-33.473V143.657H381.53v100.465c0 18.753-14.72 33.473-33.473 33.473a33.145 33.145 0 01-33.473-33.473V143.657H180.6A134.314 134.314 0 0046.66 277.595v535.756A134.314 134.314 0 00180.6 947.289h669.74a134.36 134.36 0 00133.94-133.938V277.595a134.314 134.314 0 00-133.94-133.938zm33.473 267.877H147.126a33.145 33.145 0 01-33.473-33.473c0-18.752 14.72-33.473 33.473-33.473h736.687c18.752 0 33.472 14.72 33.472 33.473a33.145 33.145 0 01-33.472 33.473z"})));Re.displayName="CalendarIcon";const He=()=>(0,s.h)(r.A0,{name:"category"},(()=>(0,s.h)("path",{d:"M148.41 106.992h282.176c22.263 0 40.31 18.048 40.31 40.31V429.48c0 22.263-18.047 40.31-40.31 40.31H148.41c-22.263 0-40.311-18.047-40.311-40.31V147.302c0-22.263 18.048-40.31 40.311-40.31zM147.556 553.478H429.73c22.263 0 40.311 18.048 40.311 40.31v282.176c0 22.263-18.048 40.312-40.31 40.312H147.555c-22.263 0-40.311-18.049-40.311-40.312V593.79c0-22.263 18.048-40.311 40.31-40.311zM593.927 106.992h282.176c22.263 0 40.31 18.048 40.31 40.31V429.48c0 22.263-18.047 40.31-40.31 40.31H593.927c-22.263 0-40.311-18.047-40.311-40.31V147.302c0-22.263 18.048-40.31 40.31-40.31zM730.22 920.502H623.926c-40.925 0-74.22-33.388-74.22-74.425V623.992c0-41.038 33.387-74.424 74.425-74.424h222.085c41.038 0 74.424 33.226 74.424 74.067v114.233c0 10.244-8.304 18.548-18.547 18.548s-18.548-8.304-18.548-18.548V623.635c0-20.388-16.746-36.974-37.33-36.974H624.13c-20.585 0-37.331 16.747-37.331 37.33v222.086c0 20.585 16.654 37.331 37.126 37.331H730.22c10.243 0 18.547 8.304 18.547 18.547 0 10.244-8.304 18.547-18.547 18.547z"})));He.displayName="CategoryIcon";const $e=()=>(0,s.h)(r.A0,{name:"eye"},(()=>(0,s.h)("path",{d:"M992 512.096c0-5.76-.992-10.592-1.28-11.136-.192-2.88-1.152-8.064-2.08-10.816-.256-.672-.544-1.376-.832-2.08-.48-1.568-1.024-3.104-1.6-4.32C897.664 290.112 707.104 160 512 160c-195.072 0-385.632 130.016-473.76 322.592-1.056 2.112-1.792 4.096-2.272 5.856a55.512 55.512 0 00-.64 1.6c-1.76 5.088-1.792 8.64-1.632 7.744-.832 3.744-1.568 11.168-1.568 11.168-.224 2.272-.224 4.032.032 6.304 0 0 .736 6.464 1.088 7.808.128 1.824.576 4.512 1.12 6.976h-.032c.448 2.08 1.12 4.096 1.984 6.08.48 1.536.992 2.976 1.472 4.032C126.432 733.856 316.992 864 512 864c195.136 0 385.696-130.048 473.216-321.696 1.376-2.496 2.24-4.832 2.848-6.912.256-.608.48-1.184.672-1.728 1.536-4.48 1.856-8.32 1.728-8.32l-.032.032c.608-3.104 1.568-7.744 1.568-13.28zM512 672c-88.224 0-160-71.776-160-160s71.776-160 160-160 160 71.776 160 160-71.776 160-160 160z"})));$e.displayName="EyeIcon";const Ne=()=>(0,s.h)(r.A0,{name:"fire"},(()=>(0,s.h)("path",{d:"M726.4 201.6c-12.8-9.6-28.8-6.4-38.4 0-9.6 9.6-16 25.6-9.6 38.4 6.4 12.8 9.6 28.8 12.8 44.8C604.8 83.2 460.8 38.4 454.4 35.2c-9.6-3.2-22.4 0-28.8 6.4-9.6 6.4-12.8 19.2-9.6 28.8 12.8 86.4-25.6 188.8-115.2 310.4-6.4-25.6-16-51.2-32-80-9.6-9.6-22.4-16-35.2-12.8-16 3.2-25.6 12.8-25.6 28.8-3.2 48-25.6 92.8-51.2 140.8C134.4 499.2 112 544 102.4 592c-32 150.4 99.2 329.6 233.6 380.8 9.6 3.2 19.2 6.4 32 9.6-25.6-19.2-41.6-51.2-48-96C294.4 691.2 505.6 640 515.2 460.8c153.6 105.6 224 336 137.6 505.6 3.2 0 6.4-3.2 9.6-3.2 0 0 3.2 0 3.2-3.2 163.2-89.6 252.8-208 259.2-345.6 16-211.2-163.2-390.4-198.4-412.8z"})));Ne.displayName="FireIcon";const De=()=>(0,s.h)(r.A0,{name:"print"},(()=>(0,s.h)("path",{d:"M819.2 364.8h-44.8V128c0-17.067-14.933-32-32-32H281.6c-17.067 0-32 14.933-32 32v236.8h-44.8C145.067 364.8 96 413.867 96 473.6v192c0 59.733 49.067 108.8 108.8 108.8h44.8V896c0 17.067 14.933 32 32 32h460.8c17.067 0 32-14.933 32-32V774.4h44.8c59.733 0 108.8-49.067 108.8-108.8v-192c0-59.733-49.067-108.8-108.8-108.8zM313.6 160h396.8v204.8H313.6V160zm396.8 704H313.6V620.8h396.8V864zM864 665.6c0 25.6-19.2 44.8-44.8 44.8h-44.8V588.8c0-17.067-14.933-32-32-32H281.6c-17.067 0-32 14.933-32 32v121.6h-44.8c-25.6 0-44.8-19.2-44.8-44.8v-192c0-25.6 19.2-44.8 44.8-44.8h614.4c25.6 0 44.8 19.2 44.8 44.8v192z"})));De.displayName="PrintIcon";const je=()=>(0,s.h)(r.A0,{name:"tag"},(()=>(0,s.h)("path",{d:"M939.902 458.563L910.17 144.567c-1.507-16.272-14.465-29.13-30.737-30.737L565.438 84.098h-.402c-3.215 0-5.726 1.005-7.634 2.913l-470.39 470.39a10.004 10.004 0 000 14.164l365.423 365.424c1.909 1.908 4.42 2.913 7.132 2.913s5.223-1.005 7.132-2.913l470.39-470.39c2.01-2.11 3.014-5.023 2.813-8.036zm-240.067-72.121c-35.458 0-64.286-28.828-64.286-64.286s28.828-64.285 64.286-64.285 64.286 28.828 64.286 64.285-28.829 64.286-64.286 64.286z"})));je.displayName="TagIcon";const Ve=()=>(0,s.h)(r.A0,{name:"timer"},(()=>(0,s.h)("path",{d:"M799.387 122.15c4.402-2.978 7.38-7.897 7.38-13.463v-1.165c0-8.933-7.38-16.312-16.312-16.312H256.33c-8.933 0-16.311 7.38-16.311 16.312v1.165c0 5.825 2.977 10.874 7.637 13.592 4.143 194.44 97.22 354.963 220.201 392.763-122.204 37.542-214.893 196.511-220.2 389.397-4.661 5.049-7.638 11.651-7.638 19.03v5.825h566.49v-5.825c0-7.379-2.849-13.981-7.509-18.9-5.049-193.016-97.867-351.985-220.2-389.527 123.24-37.67 216.446-198.453 220.588-392.892zM531.16 450.445v352.632c117.674 1.553 211.787 40.778 211.787 88.676H304.097c0-48.286 95.149-87.382 213.728-88.676V450.445c-93.077-3.107-167.901-81.297-167.901-177.093 0-8.803 6.99-15.793 15.793-15.793 8.803 0 15.794 6.99 15.794 15.793 0 80.261 63.69 145.635 142.01 145.635s142.011-65.374 142.011-145.635c0-8.803 6.99-15.793 15.794-15.793s15.793 6.99 15.793 15.793c0 95.019-73.789 172.82-165.96 177.093z"})));Ve.displayName="TimerIcon";const Be=()=>(0,s.h)(r.A0,{name:"word"},(()=>[(0,s.h)("path",{d:"M518.217 432.64V73.143A73.143 73.143 0 01603.43 1.097a512 512 0 01419.474 419.474 73.143 73.143 0 01-72.046 85.212H591.36a73.143 73.143 0 01-73.143-73.143z"}),(0,s.h)("path",{d:"M493.714 566.857h340.297a73.143 73.143 0 0173.143 85.577A457.143 457.143 0 11371.566 117.76a73.143 73.143 0 0185.577 73.143v339.383a36.571 36.571 0 0036.571 36.571z"})]));Be.displayName="WordIcon";const ze=()=>{const e=g();return(0,s.Fl)((()=>e.value.metaLocales))};var Ue=(0,s.aZ)({name:"AuthorInfo",inheritAttrs:!1,props:{author:{type:Array,required:!0},pure:Boolean},setup(e){const t=ze();return()=>e.author.length?(0,s.h)("span",{class:"page-author-info","aria-label":`${t.value.author}${e.pure?"":"🖊"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(Pe),(0,s.h)("span",e.author.map((e=>e.url?(0,s.h)("a",{class:"page-author-item",href:e.url,target:"_blank",rel:"noopener noreferrer"},e.name):(0,s.h)("span",{class:"page-author-item"},e.name)))),(0,s.h)("span",{property:"author",content:e.author.map((e=>e.name)).join(", ")})]):null}}),qe=(0,s.aZ)({name:"CategoryInfo",inheritAttrs:!1,props:{category:{type:Array,required:!0},pure:Boolean},setup(e){const t=(0,o.tv)(),n=(0,u.Vi)(),l=ze();return()=>e.category.length?(0,s.h)("span",{class:"page-category-info","aria-label":`${l.value.category}${e.pure?"":"🌈"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(He),e.category.map((({name:o,path:l})=>(0,s.h)("span",{class:["page-category-item",{[`category${(0,r.ai)(o,9)}`]:!e.pure,clickable:l}],role:l?"navigation":"",onClick:e=>((e,o="")=>{o&&n.value.path!==o&&(e.preventDefault(),t.push(o))})(e,l)},o))),(0,s.h)("meta",{property:"articleSection",content:e.category.map((({name:e})=>e)).join(",")})]):null}}),Ze=(0,s.aZ)({name:"DateInfo",inheritAttrs:!1,props:{date:{type:Object,default:null},localizedDate:{type:String,default:""},pure:Boolean},setup(e){const t=(0,u.Ym)(),n=ze();return()=>e.date?(0,s.h)("span",{class:"page-date-info","aria-label":`${n.value.date}${e.pure?"":"📅"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(Re),(0,s.h)("span",(0,s.h)(u.qx,(()=>e.localizedDate||e.date.toLocaleDateString(t.value)))),(0,s.h)("meta",{property:"datePublished",content:e.date.toISOString()||""})]):null}}),Je=(0,s.aZ)({name:"OriginalInfo",inheritAttrs:!1,props:{isOriginal:Boolean},setup(e){const t=ze();return()=>e.isOriginal?(0,s.h)("span",{class:"page-original-info"},t.value.origin):null}}),Ye=((0,s.aZ)({name:"PageViewInfo",inheritAttrs:!1,props:{pageview:{type:[Boolean,String],default:!1},pure:Boolean},setup(e){const t=(0,o.yj)(),n=ze(),a=(0,i.XI)(),c=(0,i.iH)(0);return(0,l.Iyq)(a,(()=>{const e=a.value.textContent;e&&!isNaN(Number(e))&&(c.value=Number(e))}),{childList:!0}),()=>e.pageview?(0,s.h)("span",{class:"page-pageview-info","aria-label":`${n.value.views}${e.pure?"":"🔢"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(c.value<1e3?$e:Ne),(0,s.h)("span",{ref:a,id:"ArtalkPV",class:"waline-pageview-count","data-path":(0,r.HD)(e.pageview)?e.pageview:t.path},"...")]):null}}),(0,s.aZ)({name:"ReadingTimeInfo",inheritAttrs:!1,props:{readingTime:{type:Object,default:()=>null},readingTimeLocale:{type:Object,default:()=>null},pure:Boolean},setup(e){const t=ze(),n=(0,s.Fl)((()=>{if(!e.readingTime)return null;const{minutes:t}=e.readingTime;return t<1?"PT1M":`PT${Math.round(t)}M`}));return()=>e.readingTimeLocale?.time?(0,s.h)("span",{class:"page-reading-time-info","aria-label":`${t.value.readingTime}${e.pure?"":"⌛"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(Ve),(0,s.h)("span",e.readingTimeLocale?.time),(0,s.h)("meta",{property:"timeRequired",content:n.value})]):null}})),We=(0,s.aZ)({name:"TagInfo",inheritAttrs:!1,props:{tag:{type:Array,default:()=>[]},pure:Boolean},setup(e){const t=(0,o.tv)(),n=(0,u.Vi)(),l=ze();return()=>e.tag.length?(0,s.h)("span",{class:"page-tag-info","aria-label":`${l.value.tag}${e.pure?"":"🏷"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(je),e.tag.map((({name:o,path:l})=>(0,s.h)("span",{class:["page-tag-item",{[`tag${(0,r.ai)(o,9)}`]:!e.pure,clickable:l}],role:l?"navigation":"",onClick:e=>((e,o="")=>{o&&n.value.path!==o&&(e.preventDefault(),t.push(o))})(e,l)},o))),(0,s.h)("meta",{property:"keywords",content:e.tag.map((({name:e})=>e)).join(",")})]):null}}),Ge=(0,s.aZ)({name:"ReadTimeInfo",inheritAttrs:!1,props:{readingTime:{type:Object,default:()=>null},readingTimeLocale:{type:Object,default:()=>null},pure:Boolean},setup(e){const t=ze();return()=>e.readingTimeLocale?.words?(0,s.h)("span",{class:"page-word-info","aria-label":`${t.value.words}${e.pure?"":"🔠"}`,...e.pure?{}:{"data-balloon-pos":"down"}},[(0,s.h)(Be),(0,s.h)("span",e.readingTimeLocale?.words),(0,s.h)("meta",{property:"wordCount",content:e.readingTime?.words})]):null}}),Ke=(0,s.aZ)({name:"PageInfo",components:{AuthorInfo:Ue,CategoryInfo:qe,DateInfo:Ze,OriginalInfo:Je,PageViewInfo:()=>null,ReadingTimeInfo:Ye,TagInfo:We,WordInfo:Ge},props:{items:{type:[Array,Boolean],default:()=>["Author","Original","Date","PageView","ReadingTime","Category","Tag"]},info:{type:Object,required:!0}},setup(e){const t=y();return()=>e.items?(0,s.h)("div",{class:"page-info"},e.items.map((n=>(0,s.h)((0,s.up)(`${n}Info`),{...e.info,pure:t.value})))):null}}),Xe=(0,s.aZ)({name:"PrintButton",setup(){const e=m(),t=g();return()=>!1===e.value.print?null:(0,s.h)("button",{type:"button",class:"print-button",title:t.value.metaLocales.print,onClick:()=>{window.print()}},(0,s.h)(De))}});const Qe=({title:e,level:t,slug:n})=>(0,s.h)(r.RG,{to:`#${n}`,class:["toc-link",`level${t}`]},(()=>e)),et=(e,t)=>{const n=(0,o.yj)();return e.length&&t>0?(0,s.h)("ul",{class:"toc-list"},e.map((e=>{const o=et(e.children,t-1);return[(0,s.h)("li",{class:["toc-item",{active:n.hash===`#${e.slug}`}]},Qe(e)),o?(0,s.h)("li",o):null]}))):null};var tt=(0,s.aZ)({name:"TOC",props:{items:{type:Array,default:()=>[]},headerDepth:{type:Number,default:2}},slots:Object,setup(e,{slots:t}){const n=(0,o.yj)(),r=(0,u.Vi)(),l=ze(),a=(0,i.XI)(),c=(0,i.iH)("-1.7rem"),p=e=>{a.value?.scrollTo({top:e,behavior:"smooth"})},d=()=>{if(a.value){const e=document.querySelector(".toc-item.active");c.value=e?`${e.getBoundingClientRect().top-a.value.getBoundingClientRect().top+a.value.scrollTop}px`:"-1.7rem"}else c.value="-1.7rem"};return(0,s.bv)((()=>{(0,s.YP)((()=>n.hash),(e=>{if(a.value){const t=document.querySelector(`#toc a.toc-link[href$="${e}"]`);if(!t)return;const{top:n,height:o}=a.value.getBoundingClientRect(),{top:r,height:l}=t.getBoundingClientRect();rn+o&&p(a.value.scrollTop+r+l-n-o)}})),(0,s.YP)((()=>n.fullPath),d,{flush:"post",immediate:!0})})),()=>{const n=e.items.length?et(e.items,e.headerDepth):r.value.headers?et(r.value.headers,e.headerDepth):null;return n?(0,s.h)("div",{class:"toc-place-holder"},[(0,s.h)("aside",{id:"toc"},[t.before?.(),(0,s.h)("div",{class:"toc-header"},[l.value.toc,(0,s.h)(Xe)]),(0,s.h)("div",{class:"toc-wrapper",ref:a},[n,(0,s.h)("div",{class:"toc-marker",style:{top:c.value}})]),t.after?.()])]):null}}}),nt=(0,s.aZ)({name:"SkipLink",props:{content:{type:String,default:"main-content"}},setup(e){const t=(0,u.Vi)(),n=g(),o=(0,i.XI)(),r=({target:e})=>{const t=document.querySelector(e.hash);if(t){const e=()=>{t.removeAttribute("tabindex"),t.removeEventListener("blur",e)};t.setAttribute("tabindex","-1"),t.addEventListener("blur",e),t.focus(),window.scrollTo(0,0)}};return(0,s.bv)((()=>{(0,s.YP)((()=>t.value.path),(()=>o.value.focus()))})),()=>[(0,s.h)("span",{ref:o,tabindex:"-1"}),(0,s.h)("a",{href:`#${e.content}`,class:"vp-skip-link sr-only",onClick:r},n.value.routeLocales.skipToContent)]}});let ot=null,rt=null;const lt={wait:()=>ot,pending:()=>{ot=new Promise((e=>rt=e))},resolve:()=>{rt?.(),ot=null,rt=null}},at=()=>lt;var st=(0,s.aZ)({name:"FadeSlideY",slots:Object,setup(e,{slots:t}){const{resolve:n,pending:o}=at();return()=>(0,s.h)(c.uT,{name:"fade-slide-y",mode:"out-in",onBeforeEnter:n,onBeforeLeave:o},(()=>t.default?.()))}});const it=(e,{slots:t})=>{const{bgImage:n,bgImageDark:o,bgImageStyle:l,color:a,description:i,image:c,imageDark:p,header:d,features:h=[]}=e;return(0,s.h)("div",{class:"vp-feature-wrapper"},[n?(0,s.h)("div",{class:["vp-feature-bg",{light:o}],style:[{"background-image":`url(${n})`},l]}):null,o?(0,s.h)("div",{class:"vp-feature-bg dark",style:[{"background-image":`url(${o})`},l]}):null,(0,s.h)("div",{class:"vp-feature",style:a?{color:a}:{}},[t.image?.(e)||[c?(0,s.h)("img",{class:["vp-feature-image",{light:p}],src:(0,u.pJ)(c),alt:""}):null,p?(0,s.h)("img",{class:"vp-feature-image dark",src:(0,u.pJ)(p),alt:""}):null],t.info?.(e)||[d?(0,s.h)("h2",{class:"vp-feature-header"},d):null,i?(0,s.h)("p",{class:"vp-feature-description",innerHTML:i}):null],h.length?(0,s.h)("div",{class:"vp-features"},h.map((({icon:e,title:t,details:n,link:o})=>{const l=[(0,s.h)("h3",{class:"vp-feature-title"},[(0,s.h)(C,{icon:e}),(0,s.h)("span",{innerHTML:t})]),(0,s.h)("p",{class:"vp-feature-details",innerHTML:n})];return o?(0,r.tm)(o)?(0,s.h)("a",{class:"vp-feature-item link",href:o,"aria-label":t,target:"_blank"},l):(0,s.h)(r.RG,{class:"vp-feature-item link",to:o,"aria-label":t},(()=>l)):(0,s.h)("div",{class:"vp-feature-item"},l)}))):null])])};it.displayName="FeaturePanel";var ct=it,ut=(0,s.aZ)({name:"HeroInfo",slots:Object,setup(e,{slots:t}){const n=(0,u.I2)(),o=(0,u.I5)(),l=(0,s.Fl)((()=>n.value.heroFullScreen??!1)),a=(0,s.Fl)((()=>{const{heroText:e,tagline:t}=n.value;return{text:e??o.value.title??"Hello",tagline:t??o.value.description??"",isFullScreen:l.value}})),i=(0,s.Fl)((()=>{const{heroText:e,heroImage:t,heroImageDark:o,heroAlt:r,heroImageStyle:a}=n.value;return{image:t?(0,u.pJ)(t):null,imageDark:o?(0,u.pJ)(o):null,heroStyle:a,alt:r||e||"",isFullScreen:l.value}})),c=(0,s.Fl)((()=>{const{bgImage:e,bgImageDark:t,bgImageStyle:o}=n.value;return{image:(0,r.HD)(e)?(0,u.pJ)(e):null,imageDark:(0,r.HD)(t)?(0,u.pJ)(t):null,bgStyle:o,isFullScreen:l.value}})),p=(0,s.Fl)((()=>n.value.actions??[]));return()=>(0,s.h)("header",{class:["vp-hero-info-wrapper",{fullscreen:l.value}]},[t.heroBg?.(c.value)||[c.value.image?(0,s.h)("div",{class:["vp-hero-mask",{light:c.value.imageDark}],style:[{"background-image":`url(${c.value.image})`},c.value.bgStyle]}):null,c.value.imageDark?(0,s.h)("div",{class:"vp-hero-mask dark",style:[{"background-image":`url(${c.value.imageDark})`},c.value.bgStyle]}):null],(0,s.h)("div",{class:"vp-hero-info"},[t.heroImage?.(i.value)||(0,s.h)(Le,{appear:!0,type:"group"},(()=>[i.value.image?(0,s.h)("img",{key:"light",class:["vp-hero-image",{light:i.value.imageDark}],style:i.value.heroStyle,src:i.value.image,alt:i.value.alt}):null,i.value.imageDark?(0,s.h)("img",{key:"dark",class:"vp-hero-image dark",style:i.value.heroStyle,src:i.value.imageDark,alt:i.value.alt}):null])),t.heroInfo?.(a.value)??(0,s.h)("div",{class:"vp-hero-infos"},[a.value.text?(0,s.h)(Le,{appear:!0,delay:.04},(()=>(0,s.h)("h1",{id:"main-title"},a.value.text))):null,a.value.tagline?(0,s.h)(Le,{appear:!0,delay:.08},(()=>(0,s.h)("p",{id:"main-description",innerHTML:a.value.tagline}))):null,p.value.length?(0,s.h)(Le,{appear:!0,delay:.12},(()=>(0,s.h)("p",{class:"vp-hero-actions"},p.value.map((e=>(0,s.h)(P,{class:["vp-hero-action",e.type||"default"],config:e,noExternalLinkIcon:!0},e.icon?{before:()=>(0,s.h)(C,{icon:e.icon})}:{})))))):null])])])}});const pt=(e,{slots:t})=>{const{bgImage:n,bgImageDark:o,bgImageStyle:l,color:a,description:i,image:c,imageDark:p,header:d,highlights:h=[],type:f="un-order"}=e;return(0,s.h)("div",{class:"vp-highlight-wrapper",style:a?{color:a}:{}},[n?(0,s.h)("div",{class:["vp-highlight-bg",{light:o}],style:[{"background-image":`url(${n})`},l]}):null,o?(0,s.h)("div",{class:"vp-highlight-bg dark",style:[{"background-image":`url(${o})`},l]}):null,(0,s.h)("div",{class:"vp-highlight"},[t.image?.(e)||[c?(0,s.h)("img",{class:["vp-highlight-image",{light:p}],src:(0,u.pJ)(c),alt:""}):null,p?(0,s.h)("img",{class:"vp-highlight-image dark",src:(0,u.pJ)(p),alt:""}):null],t.info?.(e)||[(0,s.h)("div",{class:"vp-highlight-info-wrapper"},(0,s.h)("div",{class:"vp-highlight-info"},[d?(0,s.h)("h2",{class:"vp-highlight-header",innerHTML:d}):null,i?(0,s.h)("p",{class:"vp-highlight-description",innerHTML:i}):null,t.highlights?.(h)||(0,s.h)("order"===f?"ol":"no-order"===f?"dl":"ul",{class:"vp-highlights"},h.map((({icon:e,title:t,details:n,link:o})=>{const l=[(0,s.h)("no-order"===f?"dt":"h3",{class:"vp-highlight-title"},[e?(0,s.h)(C,{class:"vp-highlight-icon",icon:e}):null,(0,s.h)("span",{innerHTML:t})]),n?(0,s.h)("no-order"===f?"dd":"p",{class:"vp-highlight-details",innerHTML:n}):null];return(0,s.h)("no-order"===f?"div":"li",{class:["vp-highlight-item-wrapper",{link:o}]},o?(0,r.tm)(o)?(0,s.h)("a",{class:"vp-highlight-item link",href:o,"aria-label":t,target:"_blank"},l):(0,s.h)(r.RG,{class:"vp-highlight-item link",to:o,"aria-label":t},(()=>l)):(0,s.h)("div",{class:"vp-highlight-item"},l))})))]))]])])};pt.displayName="HighlightPanel";var dt=pt,ht=(0,s.aZ)({name:"HomePage",slots:Object,setup(e,{slots:t}){const n=y(),o=(0,u.I2)(),l=(0,s.Fl)((()=>{const{features:e}=o.value;return(0,r.kJ)(e)?e:null})),a=(0,s.Fl)((()=>{const{highlights:e}=o.value;return(0,r.kJ)(e)?e:null}));return()=>(0,s.h)("main",{id:"main-content",class:["vp-project-home ",{pure:n.value}],"aria-labelledby":null===o.value.heroText?"":"main-title"},[t.top?.(),(0,s.h)(ut),a.value?.map((e=>"features"in e?(0,s.h)(ct,e):(0,s.h)(dt,e)))||(l.value?(0,s.h)(Le,{appear:!0,delay:.24},(()=>(0,s.h)(ct,{features:l.value}))):null),t.center?.(),(0,s.h)(Le,{appear:!0,delay:.32},(()=>(0,s.h)(Me))),t.bottom?.()])}}),ft=(0,s.aZ)({name:"BreadCrumb",setup(){const e=(0,o.tv)(),t=(0,u.Vi)(),n=(0,u.I)(),l=(0,u.I2)(),a=g(),c=(0,i.XI)([]),p=(0,s.Fl)((()=>(l.value.breadcrumb||!1!==l.value.breadcrumb&&!1!==a.value.breadcrumb)&&c.value.length>1)),d=(0,s.Fl)((()=>l.value.breadcrumbIcon||!1!==l.value.breadcrumbIcon&&!1!==a.value.breadcrumbIcon)),h=()=>{const o=e.getRoutes(),l=((e,t)=>{const n=e.replace(t,"/").split("/"),o=[];let l=(0,r.U1)(t);return n.forEach(((e,t)=>{t!==n.length-1?(l+=`${e}/`,o.push({link:l,name:e||"Home"})):""!==e&&(l+=e,o.push({link:l,name:e}))})),o})(t.value.path,n.value).map((({link:t,name:n})=>{const l=o.find((e=>e.path===t));if(l){const{meta:t,path:o}=(0,r.Zr)(e,l.path);return{title:t[D.shortTitle]||t[D.title]||n,icon:t[D.icon],path:o}}return null})).filter((e=>null!==e));l.length>1&&(c.value=l)};return(0,s.bv)((()=>{(0,s.YP)((()=>t.value.path),h,{immediate:!0})})),()=>(0,s.h)("nav",{class:["vp-breadcrumb",{disable:!p.value}]},p.value?(0,s.h)("ol",{vocab:"https://schema.org/",typeof:"BreadcrumbList"},c.value.map(((e,t)=>(0,s.h)("li",{class:{"is-active":c.value.length-1===t},property:"itemListElement",typeof:"ListItem"},[(0,s.h)(r.RG,{to:e.path,property:"item",typeof:"WebPage"},(()=>[d.value?(0,s.h)(C,{icon:e.icon}):null,(0,s.h)("span",{property:"name"},e.title||"Unknown")])),(0,s.h)("meta",{property:"position",content:t+1})])))):[])}});const vt=(e,t)=>!1!==t&&((0,r.HD)(t)?B(e,t,!0):(0,r.PO)(t)?t:null),mt=(e,t,n)=>{const o=e.findIndex((e=>e.link===t));if(-1!==o){const t=e[o+n];return t?.link?t:null}for(const o of e)if(o.children){const e=mt(o.children,t,n);if(e)return e}return null};var gt=(0,s.aZ)({name:"PageNav",setup(){const e=g(),t=(0,u.I2)(),n=J(),a=(0,u.Vi)(),i=(0,o.tv)(),c=(()=>{const e=(0,o.tv)(),t=(0,o.yj)();return n=>{if(n)if((0,r.sD)(n))t.path!==n&&e.push(n);else if((0,r.PF)(n))window&&window.open(n);else{const o=t.path.slice(0,t.path.lastIndexOf("/"));e.push(`${o}/${encodeURI(n)}`)}}})(),p=(0,s.Fl)((()=>{const o=vt(i,t.value.prev);return!1===o?null:o||(!1===e.value.prevLink?null:mt(n.value,a.value.path,-1))})),d=(0,s.Fl)((()=>{const o=vt(i,t.value.next);return!1===o?null:o||(!1===e.value.nextLink?null:mt(n.value,a.value.path,1))}));return(0,l.ORN)("keydown",(e=>{e.altKey&&("ArrowRight"===e.key?d.value&&(c(d.value.link),e.preventDefault()):"ArrowLeft"===e.key&&p.value&&(c(p.value.link),e.preventDefault()))})),()=>p.value||d.value?(0,s.h)("nav",{class:"vp-page-nav"},[p.value?(0,s.h)(P,{class:"prev",config:p.value},(()=>[(0,s.h)("div",{class:"hint"},[(0,s.h)("span",{class:"arrow start"}),e.value.metaLocales.prev]),(0,s.h)("div",{class:"link"},[(0,s.h)(C,{icon:p.value?.icon}),p.value?.text])])):null,d.value?(0,s.h)(P,{class:"next",config:d.value},(()=>[(0,s.h)("div",{class:"hint"},[e.value.metaLocales.next,(0,s.h)("span",{class:"arrow end"})]),(0,s.h)("div",{class:"link"},[d.value?.text,(0,s.h)(C,{icon:d.value?.icon})])])):null]):null}});const yt={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"};var bt=(0,s.aZ)({name:"PageTitle",setup(){const e=(0,u.Vi)(),t=(0,u.I2)(),n=g(),{info:o,items:l}=(()=>{const e=g(),t=(0,u.Vi)(),n=(0,u.I2)(),o=x(),l=(()=>{const e=(0,u.I2)();return(0,s.Fl)((()=>(0,r.n3)(e.value.category).map((e=>({name:e,path:""})))))})(),a=(()=>{const e=(0,u.I2)();return(0,s.Fl)((()=>(0,r.h1)(e.value.tag).map((e=>({name:e,path:""})))))})(),i=(()=>{const e=(0,u.I2)(),t=(0,u.Vi)();return(0,s.Fl)((()=>{const n=(0,r._3)(e.value.date);if(n)return n;const{createdTime:o}=t.value.git||{};return o?new Date(o):null}))})(),c=p(),d=f();return{info:(0,s.Fl)((()=>({author:o.value,category:l.value,date:i.value,localizedDate:t.value.localizedDate,tag:a.value,isOriginal:n.value.isOriginal||!1,readingTime:c.value,readingTimeLocale:d.value,pageview:!("pageview"in n.value)||n.value.pageview}))),items:(0,s.Fl)((()=>"pageInfo"in n.value?n.value.pageInfo:"pageInfo"in e.value?e.value.pageInfo:null))}})();return()=>(0,s.h)("div",{class:"vp-page-title"},[(0,s.h)("h1",[!1===n.value.titleIcon?null:(0,s.h)(C,{icon:t.value.icon}),e.value.title]),(0,s.h)(Ke,{info:o.value,...null===l.value?{}:{items:l.value}}),(0,s.h)("hr")])}});const wt=()=>(0,s.h)(r.A0,{name:"edit"},(()=>[(0,s.h)("path",{d:"M430.818 653.65a60.46 60.46 0 0 1-50.96-93.281l71.69-114.012 7.773-10.365L816.038 80.138A60.46 60.46 0 0 1 859.225 62a60.46 60.46 0 0 1 43.186 18.138l43.186 43.186a60.46 60.46 0 0 1 0 86.373L588.879 565.55l-8.637 8.637-117.466 68.234a60.46 60.46 0 0 1-31.958 11.229z"}),(0,s.h)("path",{d:"M728.802 962H252.891A190.883 190.883 0 0 1 62.008 771.98V296.934a190.883 190.883 0 0 1 190.883-192.61h267.754a60.46 60.46 0 0 1 0 120.92H252.891a69.962 69.962 0 0 0-69.098 69.099V771.98a69.962 69.962 0 0 0 69.098 69.098h475.911A69.962 69.962 0 0 0 797.9 771.98V503.363a60.46 60.46 0 1 1 120.922 0V771.98A190.883 190.883 0 0 1 728.802 962z"})]));wt.displayName="EditIcon";var kt=(0,s.aZ)({name:"PageMeta",setup(){const e=g(),t=(()=>{const e=g(),t=(0,u.Vi)(),n=(0,u.I2)();return(0,s.Fl)((()=>{const{repo:o,docsRepo:l=o,docsBranch:a="main",docsDir:s="",editLink:i,editLinkPattern:c=""}=e.value;if(!(n.value.editLink??i??1)||!l)return null;const u=(({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:o,editLinkPattern:l})=>{if(!o)return null;const a=(0,r.c9)(e);let s;return l?s=l:null!==a&&(s=yt[a]),s?s.replace(/:repo/,(0,r.ak)(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,(0,r.FY)(`${(0,r.U1)(n)}/${o}`)):null})({docsRepo:l,docsBranch:a,docsDir:s,editLinkPattern:c,filePathRelative:t.value.filePathRelative});return u?{text:e.value.metaLocales.editLink,link:u}:null}))})(),n=(()=>{const e=(0,u.I5)(),t=g(),n=(0,u.Vi)(),o=(0,u.I2)();return(0,s.Fl)((()=>(o.value.lastUpdated??t.value.lastUpdated??1)&&n.value.git?.updatedTime?new Date(n.value.git?.updatedTime).toLocaleString(e.value.lang):null))})(),o=(()=>{const e=g(),t=(0,u.Vi)(),n=(0,u.I2)();return(0,s.Fl)((()=>n.value.contributors??e.value.contributors??1?t.value.git?.contributors??null:null))})();return()=>{const{metaLocales:r}=e.value;return(0,s.h)("footer",{class:"page-meta"},[t.value?(0,s.h)("div",{class:"meta-item edit-link"},(0,s.h)(P,{class:"label",config:t.value},{before:()=>(0,s.h)(wt)})):null,(0,s.h)("div",{class:"meta-item git-info"},[n.value?(0,s.h)("div",{class:"update-time"},[(0,s.h)("span",{class:"label"},`${r.lastUpdated}: `),(0,s.h)(u.qx,(()=>(0,s.h)("span",{class:"info"},n.value)))]):null,o.value&&o.value.length?(0,s.h)("div",{class:"contributors"},[(0,s.h)("span",{class:"label"},`${r.contributors}: `),o.value.map((({email:e,name:t},n)=>[(0,s.h)("span",{class:"contributor",title:`email: ${e}`},t),n!==o.value.length-1?",":""]))]):null])])}}}),_t=(0,s.aZ)({name:"NormalPage",slots:Object,setup(e,{slots:t}){const n=(0,u.I2)(),{isDarkmode:o}=L(),l=g(),a=(0,s.Fl)((()=>n.value.toc||!1!==n.value.toc&&!1!==l.value.toc));return()=>(0,s.h)("main",{id:"main-content",class:"vp-page"},(0,s.h)((0,r.li)("LocalEncrypt")?(0,s.up)("LocalEncrypt"):r.R8,(()=>[t.top?.(),n.value.cover?(0,s.h)("div",{class:"page-cover"},(0,s.h)("img",{src:(0,u.pJ)(n.value.cover),alt:"","no-view":""})):null,(0,s.h)(ft),(0,s.h)(bt),a.value?(0,s.h)(tt,{headerDepth:n.value.headerDepth??l.value.headerDepth??2},{before:()=>t.tocBefore?.(),after:()=>t.tocAfter?.()}):null,t.contentBefore?.(),(0,s.h)(Me),t.contentAfter?.(),(0,s.h)(kt),(0,s.h)(gt),(0,r.li)("CommentService")?(0,s.h)((0,s.up)("CommentService"),{darkmode:o.value}):null,t.bottom?.()])))}}),St=(0,s.aZ)({name:"Layout",slots:Object,setup(e,{slots:t}){m(),g();const n=(0,u.Vi)(),o=(0,u.I2)(),{isMobile:r}=A(),l=(0,s.Fl)((()=>"none"));return()=>[(0,s.h)(nt),(0,s.h)(Fe,{},{default:()=>t.default?.()||(o.value.home?(0,s.h)(ht):(0,s.h)(st,(()=>(0,s.h)(_t,{key:n.value.path},{top:()=>t.top?.(),bottom:()=>t.bottom?.(),contentBefore:()=>t.contentBefore?.(),contentAfter:()=>t.contentAfter?.(),tocBefore:()=>t.tocBefore?.(),tocAfter:()=>t.tocAfter?.()})))),..."none"!==l.value?{navScreenBottom:()=>(0,s.h)((0,s.up)("BloggerInfo"))}:{},...r.value||"always"!==l.value?{}:{sidebar:()=>(0,s.h)((0,s.up)("BloggerInfo"))}})]}}),Ct=(0,s.aZ)({name:"NotFoundHint",setup(){const e=g(),t=()=>{const t=e.value.routeLocales.notFoundMsg;return t[Math.floor(Math.random()*t.length)]};return()=>(0,s.h)("div",{class:"not-found-hint"},[(0,s.h)("p",{class:"error-code"},"404"),(0,s.h)("h1",{class:"error-title"},e.value.routeLocales.notFoundTitle),(0,s.h)("p",{class:"error-hint"},t())])}}),xt=(0,s.aZ)({name:"NotFound",slots:Object,setup(e,{slots:t}){const n=(0,u.I)(),r=g(),{navigate:l}=(0,o.nB)({to:r.value.home??n.value});return()=>[(0,s.h)(nt),(0,s.h)(Fe,{noSidebar:!0},(()=>(0,s.h)("main",{id:"main-content",class:"vp-page not-found"},t.default?.()||[(0,s.h)(Ct),(0,s.h)("div",{class:"actions"},[(0,s.h)("button",{type:"button",class:"action-button",onClick:()=>{window.history.go(-1)}},r.value.routeLocales.back),(0,s.h)("button",{type:"button",class:"action-button",onClick:()=>l()},r.value.routeLocales.home)])])))]}})},8102:(e,t,n)=>{n.d(t,{qx:()=>o.qx,VY:()=>o.VY,r$:()=>o.r$,C3:()=>o.C3,Vi:()=>o.Vi,I2:()=>o.I2,Ym:()=>o.Ym,I:()=>o.I,WF:()=>o.WF,I5:()=>o.I5,pJ:()=>o.pJ});var o=n(9e3)}}]);
\ No newline at end of file
diff --git a/assets/js/883.e417b611.js.LICENSE.txt b/assets/js/883.e417b611.js.LICENSE.txt
new file mode 100644
index 00000000..028dfd88
--- /dev/null
+++ b/assets/js/883.e417b611.js.LICENSE.txt
@@ -0,0 +1,36 @@
+/*!
+ * vue-router v4.2.5
+ * (c) 2023 Eduardo San Martin Morote
+ * @license MIT
+ */
+
+/*! #__NO_SIDE_EFFECTS__ */
+
+/**
+ * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
+ * @license MIT
+ */
+
+/**
+* @vue/reactivity v3.4.15
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+
+/**
+* @vue/runtime-core v3.4.15
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+
+/**
+* @vue/runtime-dom v3.4.15
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+
+/**
+* @vue/shared v3.4.15
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
diff --git a/assets/js/app.7e3973f0.js b/assets/js/app.7e3973f0.js
new file mode 100644
index 00000000..08742001
--- /dev/null
+++ b/assets/js/app.7e3973f0.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2143],{2291:(e,t,d)=>{d.d(t,{W:()=>k});var n=d(8102),a=d(5682),i=d(6252),s=d(3349),h=d(3340),o=d(2378);const c=(0,n.r$)({enhance:({app:e})=>{(0,a.li)("Badge")||e.component("Badge",s.Z),(0,a.li)("FontIcon")||e.component("FontIcon",h.Z)},setup:()=>{},rootComponents:[()=>(0,i.h)(o.Z,{})]});var v=d(4906),r=d(5529),l=d(7102),b=d(5281),m=d(7699),p=d(2453),y=d(2369);const u=(0,n.r$)({enhance:({app:e})=>{},setup:()=>{(0,y.U)()}});var g=d(7909),f=d(9526),R=d(6291);(0,d(1370)._V)((e=>{const t=e.t,d=!1!==e.I,n=e.i;return d?{title:t,content:n?()=>[(0,i.h)(R.eF,{icon:n}),t]:null,order:e.O,index:e.I}:null}));const C=(0,n.r$)({enhance:({app:e,router:t})=>{const{scrollBehavior:d}=t.options;t.options.scrollBehavior=async(...e)=>(await(0,R.P$)().wait(),d(...e)),(0,R.bc)(e),e.component("HopeIcon",R.eF),e.component("VPLink",a.RG)},setup:()=>{(0,R.KT)(),(0,R.fR)()},layouts:{Layout:R.Ar,NotFound:R.TX}}),k=[{},c,v.Z,r.Z,l.Z,b.Z,m.Z,p.Z,u,g.Z,f.Z,C]},5214:(e,t,d)=>{d.d(t,{b:()=>a});var n=d(6252);const a={"v-8daa1a0e":(0,n.RC)((()=>d.e(2509).then(d.bind(d,8586)))),"v-74379e72":(0,n.RC)((()=>d.e(5548).then(d.bind(d,1845)))),"v-744497ce":(0,n.RC)((()=>d.e(5671).then(d.bind(d,4272)))),"v-1a155670":(0,n.RC)((()=>d.e(2448).then(d.bind(d,3693)))),"v-82f2a624":(0,n.RC)((()=>d.e(7138).then(d.bind(d,9464)))),"v-7445cd33":(0,n.RC)((()=>d.e(2368).then(d.bind(d,2121)))),"v-0a853913":(0,n.RC)((()=>d.e(9580).then(d.bind(d,2471)))),"v-5c0c76d7":(0,n.RC)((()=>d.e(732).then(d.bind(d,4660)))),"v-19b5347a":(0,n.RC)((()=>d.e(8408).then(d.bind(d,8371)))),"v-1c6d3a3e":(0,n.RC)((()=>d.e(4280).then(d.bind(d,4464)))),"v-55131a51":(0,n.RC)((()=>d.e(9236).then(d.bind(d,4945)))),"v-5ddc85e1":(0,n.RC)((()=>d.e(4377).then(d.bind(d,5067)))),"v-147825fb":(0,n.RC)((()=>d.e(8814).then(d.bind(d,3865)))),"v-67d16688":(0,n.RC)((()=>d.e(3325).then(d.bind(d,3748)))),"v-d67234a8":(0,n.RC)((()=>d.e(5895).then(d.bind(d,2299)))),"v-6dd45d9b":(0,n.RC)((()=>d.e(6165).then(d.bind(d,8432)))),"v-16bdf429":(0,n.RC)((()=>d.e(3925).then(d.bind(d,9150)))),"v-a08ef0ec":(0,n.RC)((()=>d.e(288).then(d.bind(d,8817)))),"v-669bced4":(0,n.RC)((()=>d.e(4833).then(d.bind(d,4062)))),"v-fa72264c":(0,n.RC)((()=>d.e(8886).then(d.bind(d,6843)))),"v-52692a96":(0,n.RC)((()=>d.e(4374).then(d.bind(d,7621)))),"v-3096c190":(0,n.RC)((()=>d.e(6399).then(d.bind(d,3389)))),"v-fe9aee22":(0,n.RC)((()=>d.e(5872).then(d.bind(d,192)))),"v-fdd5d9ea":(0,n.RC)((()=>d.e(2689).then(d.bind(d,3186)))),"v-4def954c":(0,n.RC)((()=>d.e(1672).then(d.bind(d,5850)))),"v-6b4a62ea":(0,n.RC)((()=>d.e(6599).then(d.bind(d,6817)))),"v-68002798":(0,n.RC)((()=>d.e(5287).then(d.bind(d,6145)))),"v-6d3257b0":(0,n.RC)((()=>d.e(578).then(d.bind(d,4121)))),"v-0a40e55e":(0,n.RC)((()=>d.e(5071).then(d.bind(d,4182)))),"v-cceda784":(0,n.RC)((()=>d.e(9142).then(d.bind(d,7020)))),"v-2250b6d9":(0,n.RC)((()=>d.e(6331).then(d.bind(d,7814)))),"v-023b4bae":(0,n.RC)((()=>d.e(2441).then(d.bind(d,314)))),"v-69f3a96a":(0,n.RC)((()=>d.e(726).then(d.bind(d,197)))),"v-1bffc66e":(0,n.RC)((()=>d.e(4718).then(d.bind(d,7624)))),"v-4e9d6767":(0,n.RC)((()=>d.e(7193).then(d.bind(d,2535)))),"v-666426ae":(0,n.RC)((()=>d.e(9932).then(d.bind(d,8213)))),"v-62edc12e":(0,n.RC)((()=>d.e(1438).then(d.bind(d,2832)))),"v-0566f368":(0,n.RC)((()=>d.e(7433).then(d.bind(d,5577)))),"v-5e09d0a1":(0,n.RC)((()=>d.e(598).then(d.bind(d,7638)))),"v-1d7ad3e6":(0,n.RC)((()=>d.e(830).then(d.bind(d,9308)))),"v-dc52bc6a":(0,n.RC)((()=>d.e(2132).then(d.bind(d,2021)))),"v-07f380c3":(0,n.RC)((()=>d.e(5004).then(d.bind(d,4850)))),"v-51b3f914":(0,n.RC)((()=>d.e(299).then(d.bind(d,4700)))),"v-3706649a":(0,n.RC)((()=>d.e(88).then(d.bind(d,9927)))),"v-723d0d85":(0,n.RC)((()=>d.e(8421).then(d.bind(d,8976))))}},5719:(e,t,d)=>{d.d(t,{T:()=>n});const n={"v-8daa1a0e":()=>d.e(2509).then(d.bind(d,4958)).then((({data:e})=>e)),"v-74379e72":()=>d.e(5548).then(d.bind(d,999)).then((({data:e})=>e)),"v-744497ce":()=>d.e(5671).then(d.bind(d,7579)).then((({data:e})=>e)),"v-1a155670":()=>d.e(2448).then(d.bind(d,8886)).then((({data:e})=>e)),"v-82f2a624":()=>d.e(7138).then(d.bind(d,4624)).then((({data:e})=>e)),"v-7445cd33":()=>d.e(2368).then(d.bind(d,7402)).then((({data:e})=>e)),"v-0a853913":()=>d.e(9580).then(d.bind(d,3972)).then((({data:e})=>e)),"v-5c0c76d7":()=>d.e(732).then(d.bind(d,483)).then((({data:e})=>e)),"v-19b5347a":()=>d.e(8408).then(d.bind(d,3694)).then((({data:e})=>e)),"v-1c6d3a3e":()=>d.e(4280).then(d.bind(d,8992)).then((({data:e})=>e)),"v-55131a51":()=>d.e(9236).then(d.bind(d,7185)).then((({data:e})=>e)),"v-5ddc85e1":()=>d.e(4377).then(d.bind(d,5958)).then((({data:e})=>e)),"v-147825fb":()=>d.e(8814).then(d.bind(d,6872)).then((({data:e})=>e)),"v-67d16688":()=>d.e(3325).then(d.bind(d,1517)).then((({data:e})=>e)),"v-d67234a8":()=>d.e(5895).then(d.bind(d,8857)).then((({data:e})=>e)),"v-6dd45d9b":()=>d.e(6165).then(d.bind(d,627)).then((({data:e})=>e)),"v-16bdf429":()=>d.e(3925).then(d.bind(d,7688)).then((({data:e})=>e)),"v-a08ef0ec":()=>d.e(288).then(d.bind(d,2560)).then((({data:e})=>e)),"v-669bced4":()=>d.e(4833).then(d.bind(d,1459)).then((({data:e})=>e)),"v-fa72264c":()=>d.e(8886).then(d.bind(d,9758)).then((({data:e})=>e)),"v-52692a96":()=>d.e(4374).then(d.bind(d,9690)).then((({data:e})=>e)),"v-3096c190":()=>d.e(6399).then(d.bind(d,2602)).then((({data:e})=>e)),"v-fe9aee22":()=>d.e(5872).then(d.bind(d,636)).then((({data:e})=>e)),"v-fdd5d9ea":()=>d.e(2689).then(d.bind(d,2405)).then((({data:e})=>e)),"v-4def954c":()=>d.e(1672).then(d.bind(d,6240)).then((({data:e})=>e)),"v-6b4a62ea":()=>d.e(6599).then(d.bind(d,9485)).then((({data:e})=>e)),"v-68002798":()=>d.e(5287).then(d.bind(d,4791)).then((({data:e})=>e)),"v-6d3257b0":()=>d.e(578).then(d.bind(d,1952)).then((({data:e})=>e)),"v-0a40e55e":()=>d.e(5071).then(d.bind(d,8903)).then((({data:e})=>e)),"v-cceda784":()=>d.e(9142).then(d.bind(d,5649)).then((({data:e})=>e)),"v-2250b6d9":()=>d.e(6331).then(d.bind(d,6910)).then((({data:e})=>e)),"v-023b4bae":()=>d.e(2441).then(d.bind(d,7528)).then((({data:e})=>e)),"v-69f3a96a":()=>d.e(726).then(d.bind(d,8689)).then((({data:e})=>e)),"v-1bffc66e":()=>d.e(4718).then(d.bind(d,6344)).then((({data:e})=>e)),"v-4e9d6767":()=>d.e(7193).then(d.bind(d,8781)).then((({data:e})=>e)),"v-666426ae":()=>d.e(9932).then(d.bind(d,7985)).then((({data:e})=>e)),"v-62edc12e":()=>d.e(1438).then(d.bind(d,9883)).then((({data:e})=>e)),"v-0566f368":()=>d.e(7433).then(d.bind(d,4179)).then((({data:e})=>e)),"v-5e09d0a1":()=>d.e(598).then(d.bind(d,4685)).then((({data:e})=>e)),"v-1d7ad3e6":()=>d.e(830).then(d.bind(d,6494)).then((({data:e})=>e)),"v-dc52bc6a":()=>d.e(2132).then(d.bind(d,3231)).then((({data:e})=>e)),"v-07f380c3":()=>d.e(5004).then(d.bind(d,4426)).then((({data:e})=>e)),"v-51b3f914":()=>d.e(299).then(d.bind(d,3635)).then((({data:e})=>e)),"v-3706649a":()=>d.e(88).then(d.bind(d,8624)).then((({data:e})=>e)),"v-723d0d85":()=>d.e(8421).then(d.bind(d,3963)).then((({data:e})=>e))}},2456:(e,t,d)=>{d.d(t,{g:()=>n});const n=[["v-8daa1a0e","/",{y:"h",t:""},["/README.md"]],["v-74379e72","/FAQ/",{y:"a",t:"常见问题集合"},["/FAQ/README.md"]],["v-744497ce","/api/",{y:"a",t:"API"},["/api/README.md"]],["v-1a155670","/api/judge.html",{y:"a",t:"评测端通信协议"},[":md"]],["v-82f2a624","/dev/PERM_PRIV.html",{y:"a",t:"权限节点"},[":md"]],["v-7445cd33","/dev/",{y:"a",t:"开发环境部署"},["/dev/README.md"]],["v-0a853913","/dev/db-layout.html",{y:"a",t:"数据库结构"},[":md"]],["v-5c0c76d7","/dev/frontend-modify.html",{y:"a",t:"前端修改"},[":md"]],["v-19b5347a","/dev/hook.html",{y:"a",t:"使用 TypeScript 编写插件"},[":md"]],["v-1c6d3a3e","/dev/naming.html",{y:"a",t:"命名规则"},[":md"]],["v-55131a51","/dev/third-party-auth.html",{y:"a",t:"接入第三方账号系统"},[":md"]],["v-5ddc85e1","/dev/typescript.html",{y:"a",t:"使用 TypeScript 编写插件"},[":md"]],["v-147825fb","/docs/",{y:"a",t:"介绍"},["/docs/README.md"]],["v-67d16688","/plugins/",{y:"a",t:"插件"},["/plugins/README.md"]],["v-d67234a8","/plugins/elastic.html",{y:"a",t:"Elastic search"},[":md"]],["v-6dd45d9b","/plugins/fps-importer.html",{y:"a",t:"fps-importer"},[":md"]],["v-16bdf429","/plugins/geoip.html",{y:"a",t:"GeoIP"},[":md"]],["v-a08ef0ec","/plugins/hydrojudge.html",{y:"a",t:"hydrojudge"},[":md"]],["v-669bced4","/plugins/migrate.html",{y:"a",t:"migrate"},[":md"]],["v-fa72264c","/plugins/recaptcha.html",{y:"a",t:"recaptcha"},[":md"]],["v-52692a96","/plugins/sonic.html",{y:"a",t:"Sonic"},[":md"]],["v-3096c190","/plugins/vjudge.html",{y:"a",t:"VJudge"},[":md"]],["v-fe9aee22","/docs/install/",{y:"a",t:"部署 Hydro"},["/docs/install/README.md"]],["v-fdd5d9ea","/docs/install/compiler.html",{y:"a",t:"编译器"},[":md"]],["v-4def954c","/docs/install/proxy.html",{y:"a",t:"反向代理 / SSL 配置"},[":md"]],["v-6b4a62ea","/docs/install/s3.html",{y:"a",t:"存储"},[":md"]],["v-68002798","/docs/install/smtp.html",{y:"a",t:"SMTP"},[":md"]],["v-6d3257b0","/docs/system/FAQ.html",{y:"a",t:"常见问题"},[":md"]],["v-0a40e55e","/docs/system/cdn.html",{y:"a",t:"使用内容分发网络"},[":md"]],["v-cceda784","/docs/system/cli.html",{y:"a",t:"Hydro Cli"},[":md"]],["v-2250b6d9","/docs/system/database.html",{y:"a",t:"数据库备份和恢复"},[":md"]],["v-023b4bae","/docs/system/frontend-modify.html",{y:"a",t:"前端修改"},[":md"]],["v-69f3a96a","/docs/system/import-user.html",{y:"a",t:"导入用户"},[":md"]],["v-1bffc66e","/docs/system/maintain.html",{y:"a",t:"维护"},[":md"]],["v-4e9d6767","/docs/system/onsite-contest.html",{y:"a",t:"现场赛指南"},[":md"]],["v-666426ae","/docs/user/",{y:"a",t:"用户文档"},["/docs/user/README.md"]],["v-62edc12e","/docs/user/copy-problem.html",{y:"a",t:"复制题目"},[":md"]],["v-0566f368","/docs/user/domain.html",{y:"a",t:"域"},[":md"]],["v-5e09d0a1","/docs/user/permission.html",{y:"a",t:"权限系统"},[":md"]],["v-1d7ad3e6","/docs/user/problem-create.html",{y:"a",t:"Hydro常见题型的制做心得"},[":md"]],["v-dc52bc6a","/docs/user/problem-format.html",{y:"a",t:"Hydro Problem Format"},[":md"]],["v-07f380c3","/docs/user/problem.html",{y:"a",t:"题目"},[":md"]],["v-51b3f914","/docs/user/testdata.html",{y:"a",t:"测试数据格式"},[":md"]],["v-3706649a","/404.html",{y:"p",t:""},[]],["v-723d0d85","/docs/system/",{y:"p",t:"System"},[]]]},4995:(e,t,d)=>{d.d(t,{H:()=>n});const n=JSON.parse('{"base":"/","lang":"en-US","title":"Hydro","description":"","head":[["link",{"rel":"icon","href":"/hydro.png"}],["link",{"rel":"stylesheet","href":"/twoslash.css"}],["meta",{"name":"theme-color","content":"#ffeded"}],["script",{},"var _paq=window._paq=[[\'trackPageView\'],[\'enableLinkTracking\']];(function(){var u=\\"//analytics.hydro.ac/\\";_paq.push([\'setTrackerUrl\',u+\'mt\']);_paq.push([\'setSiteId\',\'2\']);var d=document,g=d.createElement(\'script\'),s=d.getElementsByTagName(\'script\')[0];g.async=true;g.src=u+\'m.js\';s.parentNode.insertBefore(g,s);})();"]],"locales":{}}')},8417:(e,t,d)=>{d.d(t,{f:()=>n});const n=JSON.parse('{"encrypt":{},"logo":"/favicon.ico","repo":"hydro-dev/Hydro","pageInfo":false,"docsRepo":"hydro-dev/hydro-dev.github.io","docsBranch":"docs","editLink":true,"locales":{"/":{"lang":"en-US","navbarLocales":{"langName":"English","selectLangAriaLabel":"Select language"},"metaLocales":{"author":"Author","date":"Writing Date","origin":"Original","views":"Page views","category":"Category","tag":"Tag","readingTime":"Reading Time","words":"Words","toc":"On This Page","prev":"Prev","next":"Next","lastUpdated":"Last update","contributors":"Contributors","editLink":"Edit this page","print":"Print"},"outlookLocales":{"themeColor":"Theme Color","darkmode":"Theme Mode","fullscreen":"Full Screen"},"routeLocales":{"skipToContent":"Skip to main content","notFoundTitle":"Page not found","notFoundMsg":["There’s nothing here.","How did we get here?","That’s a Four-Oh-Four.","Looks like we\'ve got some broken links."],"back":"Go back","home":"Take me home","openInNewWindow":"Open in new window"},"navbar":[{"text":"文档","link":"/docs/"},{"text":"常见问题解答","link":"/FAQ/"},{"text":"常用教程","link":"https://hydro.ac/d/faqs/p"},{"text":"开发","link":"/dev/"},{"text":"API","link":"/api/"},{"text":"插件","link":"/plugins/"}],"sidebar":{"/index":[{"text":"常见问题","children":["/FAQ/"]}],"/docs/":[{"text":"总览","children":["/docs/"]},{"text":"部署","children":["/docs/install/","/docs/install/s3","/docs/install/proxy","/docs/install/compiler"]},{"text":"站点管理员文档","children":["/docs/system/maintain","/docs/system/cli","/docs/system/import-user","/docs/system/cdn","/docs/system/database","/docs/system/frontend-modify","/docs/system/onsite-contest","/docs/system/FAQ"]},{"text":"用户文档","children":["/docs/user/","/docs/user/domain","/docs/user/permission","/docs/user/problem","/docs/user/testdata","/docs/user/problem-format","/docs/user/copy-problem"]}],"/dev/":[{"text":"开发","children":["/dev/","/dev/naming","/dev/db-layout","/dev/PERM_PRIV","/dev/typescript","/dev/hook","/dev/frontend-modify","/dev/third-party-auth"]}],"/api/":[{"text":"API","children":["/api/","/api/judge"]}],"/plugins/":[{"text":"插件","children":["/plugins/","/plugins/fps-importer","/plugins/hydrojudge","/plugins/migrate","/plugins/elastic","/plugins/recaptcha","/plugins/sonic","/plugins/vjudge","/plugins/geoip"]}]}}}}')},1246:(e,t,d)=>{d.d(t,{G:()=>n});const n={}}},e=>{e.O(0,[8365,883],(()=>(6669,e(e.s=6669)))),e.O()}]);
\ No newline at end of file
diff --git a/assets/js/runtime~app.83aec47e.js b/assets/js/runtime~app.83aec47e.js
new file mode 100644
index 00000000..27ea7c0e
--- /dev/null
+++ b/assets/js/runtime~app.83aec47e.js
@@ -0,0 +1 @@
+(()=>{"use strict";var e,a,r,t={},d={};function o(e){var a=d[e];if(void 0!==a)return a.exports;var r=d[e]={exports:{}};return t[e](r,r.exports,o),r.exports}o.m=t,e=[],o.O=(a,r,t,d)=>{if(!r){var n=1/0;for(i=0;i=d)&&Object.keys(o.O).every((e=>o.O[e](r[c])))?r.splice(c--,1):(f=!1,d0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[r,t,d]},o.d=(e,a)=>{for(var r in a)o.o(a,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((a,r)=>(o.f[r](e,a),a)),[])),o.u=e=>"assets/js/"+({88:"v-3706649a",288:"v-a08ef0ec",299:"v-51b3f914",578:"v-6d3257b0",598:"v-5e09d0a1",726:"v-69f3a96a",732:"v-5c0c76d7",830:"v-1d7ad3e6",1438:"v-62edc12e",1672:"v-4def954c",2132:"v-dc52bc6a",2368:"v-7445cd33",2441:"v-023b4bae",2448:"v-1a155670",2509:"v-8daa1a0e",2689:"v-fdd5d9ea",3325:"v-67d16688",3925:"v-16bdf429",4280:"v-1c6d3a3e",4374:"v-52692a96",4377:"v-5ddc85e1",4718:"v-1bffc66e",4833:"v-669bced4",5004:"v-07f380c3",5071:"v-0a40e55e",5287:"v-68002798",5548:"v-74379e72",5671:"v-744497ce",5872:"v-fe9aee22",5895:"v-d67234a8",6165:"v-6dd45d9b",6331:"v-2250b6d9",6399:"v-3096c190",6599:"v-6b4a62ea",7138:"v-82f2a624",7193:"v-4e9d6767",7433:"v-0566f368",8408:"v-19b5347a",8421:"v-723d0d85",8814:"v-147825fb",8886:"v-fa72264c",9142:"v-cceda784",9236:"v-55131a51",9580:"v-0a853913",9932:"v-666426ae"}[e]||e)+"."+{88:"ed629ea9",288:"f3aa503a",299:"2d7711f4",512:"f2344d7f",578:"dcf0a34f",598:"ee71b259",726:"e1c9e854",732:"1a454107",830:"0f664ae6",1438:"96d9657a",1672:"07c04fc7",2132:"f1e022c2",2368:"0ffdbf65",2441:"e128be14",2448:"b762e846",2509:"ad9d63c1",2689:"dcd6ea9f",2837:"ff9e30ad",3325:"5d7ae5cd",3925:"24c74640",4280:"f9e063ae",4374:"a101ca00",4377:"42ddd734",4718:"b1c6e466",4833:"97a368ad",5004:"6e738dcc",5071:"7b66dbe1",5287:"0f857d0c",5548:"33637c2c",5671:"0a587faa",5826:"60cb8e45",5872:"85842b44",5895:"1e5b1169",6165:"8633ef99",6331:"21117f9e",6399:"3bc59592",6599:"a445dff7",6968:"202faa66",7138:"4ca6060e",7193:"d988335f",7433:"e6eee5d8",7622:"fc53ae23",8408:"a216bc48",8421:"37d33c3e",8814:"875fdfbc",8886:"c4725840",9142:"fdb7d9d8",9236:"ec71e52c",9580:"cc59ad03",9932:"a77f2425"}[e]+".js",o.miniCssF=e=>"assets/css/"+e+".styles."+{6968:"202faa66",7622:"fc53ae23"}[e]+".css",o.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),a={},r="hydro-dev.github.io:",o.l=(e,t,d,n)=>{if(a[e])a[e].push(t);else{var f,c;if(void 0!==d)for(var v=document.getElementsByTagName("script"),i=0;i{f.onerror=f.onload=null,clearTimeout(u);var d=a[e];if(delete a[e],f.parentNode&&f.parentNode.removeChild(f),d&&d.forEach((e=>e(t))),r)return r(t)},u=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),c&&document.head.appendChild(f)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.p="/",(()=>{if("undefined"!=typeof document){var e={523:0};o.f.miniCss=(a,r)=>{e[a]?r.push(e[a]):0!==e[a]&&{6968:1,7622:1}[a]&&r.push(e[a]=(e=>new Promise(((a,r)=>{var t=o.miniCssF(e),d=o.p+t;if(((e,a)=>{for(var r=document.getElementsByTagName("link"),t=0;t{var o=document.createElement("link");o.rel="stylesheet",o.type="text/css",o.onerror=o.onload=r=>{if(o.onerror=o.onload=null,"load"===r.type)t();else{var n=r&&r.type,f=r&&r.target&&r.target.href||a,c=new Error("Loading CSS chunk "+e+" failed.\n("+n+": "+f+")");c.name="ChunkLoadError",c.code="CSS_CHUNK_LOAD_FAILED",c.type=n,c.request=f,o.parentNode&&o.parentNode.removeChild(o),d(c)}},o.href=a,document.head.appendChild(o)})(e,d,0,a,r)})))(a).then((()=>{e[a]=0}),(r=>{throw delete e[a],r})))}}})(),(()=>{var e={523:0,8365:0};o.f.j=(a,r)=>{var t=o.o(e,a)?e[a]:void 0;if(0!==t)if(t)r.push(t[2]);else if(/^(523|6968|7622|8365)$/.test(a))e[a]=0;else{var d=new Promise(((r,d)=>t=e[a]=[r,d]));r.push(t[2]=d);var n=o.p+o.u(a),f=new Error;o.l(n,(r=>{if(o.o(e,a)&&(0!==(t=e[a])&&(e[a]=void 0),t)){var d=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;f.message="Loading chunk "+a+" failed.\n("+d+": "+n+")",f.name="ChunkLoadError",f.type=d,f.request=n,t[1](f)}}),"chunk-"+a,a)}},o.O.j=a=>0===e[a];var a=(a,r)=>{var t,d,[n,f,c]=r,v=0;if(n.some((a=>0!==e[a]))){for(t in f)o.o(f,t)&&(o.m[t]=f[t]);if(c)var i=c(o)}for(a&&a(r);v{a.r(t),a.d(t,{data:()=>o});const o=JSON.parse('{"key":"v-023b4bae","path":"/docs/system/frontend-modify.html","title":"前端修改","lang":"en-US","frontmatter":{"description":"此指南将教您修改前端文件。 如果您正在使用开发者模式,请直接修改 packages/ui-default/templates 下的文件。 如果您使用安装脚本部署: 请先使用 hydrooj addon create 创建一个本地插件(如果之前没有做过的话)。 修改页面翻译或是添加新语言: 修改翻译:在 zh.yaml (https://github.c...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/frontend-modify.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"前端修改"}],["meta",{"property":"og:description","content":"此指南将教您修改前端文件。 如果您正在使用开发者模式,请直接修改 packages/ui-default/templates 下的文件。 如果您使用安装脚本部署: 请先使用 hydrooj addon create 创建一个本地插件(如果之前没有做过的话)。 修改页面翻译或是添加新语言: 修改翻译:在 zh.yaml (https://github.c..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2022-02-25T15:35:42.000Z"}],["meta",{"property":"article:modified_time","content":"2022-02-25T15:35:42.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"前端修改\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2022-02-25T15:35:42.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"修改页面翻译或是添加新语言:","slug":"修改页面翻译或是添加新语言","link":"#修改页面翻译或是添加新语言","children":[]},{"level":2,"title":"修改页面模板:","slug":"修改页面模板","link":"#修改页面模板","children":[]}],"git":{"createdTime":1627709441000,"updatedTime":1645803342000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":3},{"name":"Macesuted","email":"macesuted@qq.com","commits":1}]},"readingTime":{"minutes":1.04,"words":312},"filePathRelative":"docs/system/frontend-modify.md","localizedDate":"July 31, 2021","autoDesc":true,"excerpt":""}')},314:(e,t,a)=>{a.r(t),a.d(t,{default:()=>U});var o=a(6252);const l=(0,o.uE)('此指南将教您修改前端文件。
如果您正在使用开发者模式,请直接修改 packages/ui-default/templates
下的文件。
如果您使用安装脚本部署:
请先使用 hydrooj addon create
创建一个本地插件(如果之前没有做过的话)。
',6),r={href:"https://github.com/hydro-dev/Hydro/blob/master/packages/ui-default/locales/zh.yaml",target:"_blank",rel:"noopener noreferrer"},n=(0,o._)("strong",null,"其所在行而非整个文件",-1),d=(0,o._)("code",null,"~/addon/locales/zh.yaml",-1),c={href:"https://github.com/hydro-dev/Hydro/blob/master/packages/ui-default/locales/zh.yaml",target:"_blank",rel:"noopener noreferrer"},s=(0,o._)("h2",{id:"修改页面模板",tabindex:"-1"},[(0,o._)("a",{class:"header-anchor",href:"#修改页面模板"},[(0,o._)("span",null,"修改页面模板:")])],-1),i=(0,o._)("code",null,"view-source:",-1),p=(0,o._)("code",null,"view-source:https://hydro.ac",-1),u=(0,o._)("code",null,'',-1),m=(0,o._)("code",null,"data-page",-1),h=(0,o._)("code",null,"main.html",-1),y={href:"https://github.com/hydro-dev/Hydro/tree/master/packages/ui-default/templates",target:"_blank",rel:"noopener noreferrer"},_=(0,o._)("strong",null,"文件的全部内容",-1),k=(0,o._)("code",null,"~/addon/templates/",-1),g=(0,o._)("p",null,[(0,o.Uk)("特别的,创建题目时的默认模板位于 "),(0,o._)("code",null,"partials/problem_default.md"),(0,o.Uk)(",创建训练计划时的默认模板位于 "),(0,o._)("code",null,"partials/training_default.json"),(0,o.Uk)(",修改方式同上。")],-1),f=(0,o._)("p",null,"以上所有更改均会在重启 Hydro 后生效。",-1),b={},U=(0,a(3744).Z)(b,[["render",function(e,t){const a=(0,o.up)("ExternalLinkIcon");return(0,o.wg)(),(0,o.iD)("div",null,[l,(0,o._)("ul",null,[(0,o._)("li",null,[(0,o.Uk)("修改翻译:在 "),(0,o._)("a",r,[(0,o.Uk)("zh.yaml"),(0,o.Wm)(a)]),(0,o.Uk)(" 内搜索您需要修改的翻译内容,并将 "),n,(0,o.Uk)(" 修改后添加至 "),d,(0,o.Uk)(" 。")]),(0,o._)("li",null,[(0,o.Uk)("添加语言:可参照 "),(0,o._)("a",c,[(0,o.Uk)("zh.yaml"),(0,o.Wm)(a)]),(0,o.Uk)(" 格式创建一个新文件。欢迎社区参与多国化翻译工作。")])]),s,(0,o._)("p",null,[(0,o.Uk)("通常的,在您访问的 url 前加上 "),i,(0,o.Uk)("(如 "),p,(0,o.Uk)(" 即可查看页面源代码,在第二行的 "),u,(0,o.Uk)(" 中 "),m,(0,o.Uk)(" 值即为页面名(首页例外,为 "),h,(0,o.Uk)(")。 在 "),(0,o._)("a",y,[(0,o.Uk)("默认 templates"),(0,o.Wm)(a)]),(0,o.Uk)(" 中找到对应文件,将"),_,(0,o.Uk)(" 复制到 "),k,(0,o.Uk)(" 文件夹下后进行修改即可。")]),g,f])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const a=e.__vccOpts||e;for(const[e,o]of t)a[e]=o;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-0566f368.e6eee5d8.js b/assets/js/v-0566f368.e6eee5d8.js
new file mode 100644
index 00000000..12f4b7ba
--- /dev/null
+++ b/assets/js/v-0566f368.e6eee5d8.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[7433],{4179:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-0566f368","path":"/docs/user/domain.html","title":"域","lang":"en-US","frontmatter":{"description":"简介 域功能类似团队,允许在一套系统中创建多个环境(如不同班级,或是不同功能,等等) 用户可以创建多个域。(需要用户有 PRIVCREATEDOMAIN 权限,默认仅开放给管理员账户)。 域间数据完全独立,仅用户信息相通(注册账户后,在该实例的所有域中均有效)。 创建域 登录账号后,在“我的”选项卡中找到“我的域”,并点击“创建域”,填入以下信息: I...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/domain.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"域"}],["meta",{"property":"og:description","content":"简介 域功能类似团队,允许在一套系统中创建多个环境(如不同班级,或是不同功能,等等) 用户可以创建多个域。(需要用户有 PRIVCREATEDOMAIN 权限,默认仅开放给管理员账户)。 域间数据完全独立,仅用户信息相通(注册账户后,在该实例的所有域中均有效)。 创建域 登录账号后,在“我的”选项卡中找到“我的域”,并点击“创建域”,填入以下信息: I..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-03-20T01:53:27.000Z"}],["meta",{"property":"article:modified_time","content":"2023-03-20T01:53:27.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"域\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-03-20T01:53:27.000Z\\",\\"author\\":[]}"]]},"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":[]},{"level":2,"title":"创建比赛/作业","slug":"创建比赛-作业","link":"#创建比赛-作业","children":[]},{"level":2,"title":"创建训练","slug":"创建训练","link":"#创建训练","children":[]}],"git":{"createdTime":1628829220000,"updatedTime":1679277207000,"contributors":[{"name":"(Macesuted)","email":"1912192337@qq.com","commits":2},{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"Macesuted","email":"macesuted@qq.com","commits":1},{"name":"juruo888","email":"95965215+juruo888@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":3.13,"words":940},"filePathRelative":"docs/user/domain.md","localizedDate":"August 13, 2021","autoDesc":true,"excerpt":""}')},5577:(s,n,a)=>{a.r(n),a.d(n,{default:()=>p});var l=a(6252);const e=[(0,l.uE)('域功能类似团队,允许在一套系统中创建多个环境(如不同班级,或是不同功能,等等) 用户可以创建多个域。(需要用户有 PRIV_CREATE_DOMAIN 权限,默认仅开放给管理员账户)。 域间数据完全独立,仅用户信息相通(注册账户后,在该实例的所有域中均有效)。
登录账号后,在“我的”选项卡中找到“我的域”,并点击“创建域”,填入以下信息:
ID: 每个域有一个唯一的 ID,将会在域 URL 中体现。创建后无法修改。 名称: 域的名字,创建后可以更改。 公告: 域主页上显示的公告,创建后可以更改。 avatar: 域头像,与用户头像同理,可以使用 gravatar:email
或 qq:id
或 github:name
或 url:link
的格式添加。将会在“我的域”界面内显示。 创建域后,您将在此域中拥有管理员权限,可以在域内进行添加题目/创建比赛等操作。
您可以在“管理域”选项卡中点击“初始化讨论节点”按钮初始化讨论节点。
未登录用户将默认使用 guest
权限,登录用户将默认使用 default
权限。 (所以将登陆用户设为 default
权限后并不会显示在“管理用户”页内,这也表示所有用户默认不会出现在管理列表中) 所以将一个用户的权限设为 default
和将用户移出该域是等价的。
对于不在列表中的用户,点击右上角“添加用户”,在左侧选中用户,右侧选择权限组,再点击“确定”即可。
若您想要创建比赛/作业,您可以在“比赛”或“作业”选项卡中,在页面右侧找到“创建”按钮, 题目一栏支持根据题目ID或是题目名自动筛选。设置完后可点击“创建”按钮创建比赛(描述这类的框不知道写啥就随便填,不能留空)。
Tips
若因为删除作业/比赛内题目导致无法打开,可以通过 /contest/<id>/edit
或 /homework/<id>/edit
(即在无法打开的页面页面后加上 /edit
)直接访问编辑页并修正。
若您想要创建训练,您可以在“训练” 项卡中点击“新建训练计划”,填写以下信息:
标题:该训练的标题; 简介:该训练的简介,会与标题同时显示在列表页面中; 说明:该训练的详细信息; 计划:该训练的具体题目及计划信息,其格式如下: [ \n {章节详细信息}, \n {章节详细信息}, \n ... \n {章节详细信息} \n] \n
其中,“章节详细信息”的包含以下部分:
_id
:章节数字编号;title
:章节标题;requireNids
:训练此章节之前需要完成的章节数字编号,若无要求则留空,若有多个则使用逗号分隔;pids
:此章节中包含的题目的 ID ,若有多个则使用逗号分隔。举例 :若要在训练中创建三个章节,章节中分别有 ID 为 1,2,3 的题目。其中章节一、二无前置条件,章节三需要同时完成章节一、二后才能进行,则格式如下:
[ \n { \n " _id " : 1 , \n " title " : " 入门 " , \n " requireNids " : [], \n " pids " : [ 1 ] \n }, \n { \n " _id " : 2 , \n " title " : " 精通 " , \n " requireNids " : [], \n " pids " : [ 2 ] \n }, \n { \n " _id " : 3 , \n " title " : " 大师 " , \n " requireNids " : [ 1 , 2 ], \n " pids " : [ 3 ] \n } \n] \n
Tips
若因为删除训练计划内题目导致训练计划无法打开,可以通过 /training/<id>/edit
(即训练计划页面后加上 /edit
)直接访问训练计划编辑页并修正配置文件。
',24)],o={},p=(0,a(3744).Z)(o,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,e)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-07f380c3.6e738dcc.js b/assets/js/v-07f380c3.6e738dcc.js
new file mode 100644
index 00000000..fe60ee80
--- /dev/null
+++ b/assets/js/v-07f380c3.6e738dcc.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5004],{4426:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-07f380c3","path":"/docs/user/problem.html","title":"题目","lang":"en-US","frontmatter":{"description":"创建题目 拥有 PERMCREATEPROBLEM 的用户均可以新建题目。 请点击题库页面右下角的 创建题目 按钮。 题目 ID 不能全为数字。若留空则使用自动分配的数字题号。 详见下方题面编辑部分,以及 laomai 编写的说明 (./problem-create.md) 导入题目 从 Hydro 导入 上传 Hydro 导出的题目压缩包即可。 如果...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/problem.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"题目"}],["meta",{"property":"og:description","content":"创建题目 拥有 PERMCREATEPROBLEM 的用户均可以新建题目。 请点击题库页面右下角的 创建题目 按钮。 题目 ID 不能全为数字。若留空则使用自动分配的数字题号。 详见下方题面编辑部分,以及 laomai 编写的说明 (./problem-create.md) 导入题目 从 Hydro 导入 上传 Hydro 导出的题目压缩包即可。 如果..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-06-29T14:11:03.000Z"}],["meta",{"property":"article:modified_time","content":"2024-06-29T14:11:03.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"题目\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-29T14:11:03.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"创建题目","slug":"创建题目","link":"#创建题目","children":[]},{"level":2,"title":"导入题目","slug":"导入题目","link":"#导入题目","children":[{"level":3,"title":"从 Hydro 导入","slug":"从-hydro-导入","link":"#从-hydro-导入","children":[]},{"level":3,"title":"从 SYZOJ 导入","slug":"从-syzoj-导入","link":"#从-syzoj-导入","children":[]},{"level":3,"title":"从 FPS 文件导入","slug":"从-fps-文件导入","link":"#从-fps-文件导入","children":[]},{"level":3,"title":"从 QDUOJ 导入","slug":"从-qduoj-导入","link":"#从-qduoj-导入","children":[]}]},{"level":2,"title":"编辑","slug":"编辑","link":"#编辑","children":[{"level":3,"title":"题面","slug":"题面","link":"#题面","children":[]},{"level":3,"title":"标签","slug":"标签","link":"#标签","children":[]}]},{"level":2,"title":"文件","slug":"文件","link":"#文件","children":[]},{"level":2,"title":"客观题","slug":"客观题","link":"#客观题","children":[{"level":3,"title":"题面","slug":"题面-1","link":"#题面-1","children":[]},{"level":3,"title":"测试数据","slug":"测试数据","link":"#测试数据","children":[]}]}],"git":{"createdTime":1628828001000,"updatedTime":1719670263000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":6},{"name":"Macesuted","email":"macesuted@qq.com","commits":4},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":3}]},"readingTime":{"minutes":2.7,"words":810},"filePathRelative":"docs/user/problem.md","localizedDate":"August 13, 2021","autoDesc":true,"excerpt":""}')},4850:(s,n,a)=>{a.r(n),a.d(n,{default:()=>E});var l=a(6252);const e=(0,l.uE)('拥有 PERM_CREATE_PROBLEM 的用户均可以新建题目。 请点击题库页面右下角的 创建题目
按钮。
Tips
题目 ID 不能全为数字。若留空则使用自动分配的数字题号。
',4),p=(0,l.uE)('上传 Hydro 导出的题目压缩包即可。
如果您的压缩包较大无法上传我们也提供cli导入方法:
hydrooj cli problem import <domainId> <file/path> # 将 <file(压缩文件)/path(解压后的文件夹)> 的Hydro格式题目包导入至 <domainId> 域中。 \n
',6),o={href:"https://github.com/hydro-dev/loj-download",target:"_blank",rel:"noopener noreferrer"},t=(0,l._)("br",null,null,-1),r=(0,l._)("h3",{id:"从-fps-文件导入",tabindex:"-1"},[(0,l._)("a",{class:"header-anchor",href:"#从-fps-文件导入"},[(0,l._)("span",null,"从 FPS 文件导入")])],-1),c=(0,l.uE)('见插件 import-qduoj。
题面使用 Markdown 语法,并进行了部分扩展。
支持对样例数据分组显示:
```input1\n1 2\n```\n\n```output1\n3\n```
后接的数字为测试点编号,将自动合并,并左右分栏显示。
支持从附加文件引用资源。(您可以先创建题目,上传相关文件后再编辑该题目)
附加文件下载链接: [file](file://input.in)
从附加文件引用一张图片: ![img](file://foo.jpg)
从附加文件引用 pdf 作为题面:@[pdf](file://foo.pdf)
(部分情况下若无法使用,请尝试 @[pdf](file://foo.pdf?noDisposition=1)
) 从附加文件引用 word 文档作为题面: @[doc](file://foo.docx)
(依赖 onlyoffice 插件) Tips
如果您在使用外部的存储服务,部分服务商可能会强制发送 Content-Disposition
导致文件直接被下载而非预览。详询对应服务商。
https://cloud.tencent.com/document/product/436/96243 https://help.aliyun.com/zh/oss/user-guide/how-to-ensure-an-object-is-previewed-when-you-access-the-object 题面支持合并表格:
| 1 | 1 | 3 | 4 | 5 | \n| --- | --- | --- | --- | --- | \n| 1 | 1 | 2 | 2 | 6 | \n| 1 | 1 | 2 | 2 | 7 | \n| 1 | 4 | 3 | 5 | 5 | \n
将被渲染为:
支持内嵌 HTML:(用来对付部分 Markdown 搞不定的东西)
<span bgcolor="red">foo</span> \n
可点击右侧分类面板快速添加标签,也可以用英文半角逗号分隔多个标签。
您可以在题目右侧“文件”面板上传测试数据和附加文件。(支持拖拽文件至相应位置进行上传)测试数据格式 。
1. 填空题 \n \n1+1 = {{ input(1) }} \n \n2. 选择题 \n \n{{ select(2) }} \n- 1+1=2 \n- 1+1=3 \n- 1+1=4 \n \n3. 多选题 \n \n{{ multiselect(3) }} \n- A \n- B \n- C \n
仅需要配置 config.yaml 即可,不需要上传其他文件。
type : objective # 表明该题为客观题 \nanswers : # 列举出每一题的正确选项与对应的得分 \n ' 1 ' : [ ' 2 ' , 50 ] # 填空题/选择题,单答案 \n ' 2 ' : # 填空题/选择题,多答案,不同答案对应不同分数,注意空格缩进 \n ' A ' : 30 # 也可以使用相同分数,即同时存在多个正确答案 \n ' B ' : 10 \n ' 3 ' : [[ ' A ' , ' B ' ], 20 ] # 多选题答案为数组,有部分分 \n
',27),i={},E=(0,a(3744).Z)(i,[["render",function(s,n){const a=(0,l.up)("RouterLink"),i=(0,l.up)("ExternalLinkIcon");return(0,l.wg)(),(0,l.iD)("div",null,[e,(0,l._)("p",null,[(0,l.Uk)("详见下方题面编辑部分,以及 "),(0,l.Wm)(a,{to:"/docs/user/problem-create.html"},{default:(0,l.w5)((()=>[(0,l.Uk)("laomai 编写的说明")])),_:1})]),p,(0,l._)("p",null,[(0,l.Uk)("Hydro 提供了一个小工具 "),(0,l._)("a",o,[(0,l.Uk)("loj-download"),(0,l.Wm)(i)]),(0,l.Uk)(",可从基于原版 SYZOJ/SYZOJ-NG 搭建的源站下载到符合Hydro格式的题目压缩包。"),t,(0,l.Uk)(" 工具使用方法请前往使用教程查看,自行摸索并确保在网络通畅的环境下使用。")]),r,(0,l._)("p",null,[(0,l.Uk)("见插件 "),(0,l.Wm)(a,{to:"/plugins/fps-importer/"},{default:(0,l.w5)((()=>[(0,l.Uk)("fps-importer")])),_:1}),(0,l.Uk)("。")]),c])}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-0a40e55e.7b66dbe1.js b/assets/js/v-0a40e55e.7b66dbe1.js
new file mode 100644
index 00000000..eb408a9c
--- /dev/null
+++ b/assets/js/v-0a40e55e.7b66dbe1.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5071],{8903:(t,e,d)=>{d.r(e),d.d(e,{data:()=>r});const r=JSON.parse('{"key":"v-0a40e55e","path":"/docs/system/cdn.html","title":"使用内容分发网络","lang":"en-US","frontmatter":{"description":"如您希望改善 Hydro 的访问质量,在您的服务器带宽较小的情况下,您可以考虑使用内容分发网络,即 CDN ,通常情况下您仅需设置资源 CDN 即可大幅度改善访问质量,关于如何使用内容分发网络和使用中的任何问题请联系各大云厂商。 资源 CDN 创建并配置好资源 CDN ,在控制面板中将 server.cdn 设置项修改为 CDN 域名。(如 https...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/cdn.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"使用内容分发网络"}],["meta",{"property":"og:description","content":"如您希望改善 Hydro 的访问质量,在您的服务器带宽较小的情况下,您可以考虑使用内容分发网络,即 CDN ,通常情况下您仅需设置资源 CDN 即可大幅度改善访问质量,关于如何使用内容分发网络和使用中的任何问题请联系各大云厂商。 资源 CDN 创建并配置好资源 CDN ,在控制面板中将 server.cdn 设置项修改为 CDN 域名。(如 https..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-05-17T15:15:27.000Z"}],["meta",{"property":"article:modified_time","content":"2023-05-17T15:15:27.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"使用内容分发网络\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-05-17T15:15:27.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"资源 CDN","slug":"资源-cdn","link":"#资源-cdn","children":[]},{"level":2,"title":"全站 CDN","slug":"全站-cdn","link":"#全站-cdn","children":[]}],"git":{"createdTime":1628908242000,"updatedTime":1684336527000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":3},{"name":"sosyz","email":"30596875+sosyz@users.noreply.github.com","commits":2},{"name":"Macesuted","email":"macesuted@qq.com","commits":1},{"name":"MasterYuan418","email":"58651976+MasterYuan418@users.noreply.github.com","commits":1},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":1.35,"words":405},"filePathRelative":"docs/system/cdn.md","localizedDate":"August 14, 2021","autoDesc":true,"excerpt":""}')},4182:(t,e,d)=>{d.r(e),d.d(e,{default:()=>n});var r=d(6252);const a=[(0,r.uE)('如您希望改善 Hydro 的访问质量,在您的服务器带宽较小的情况下,您可以考虑使用内容分发网络,即 CDN ,通常情况下您仅需设置资源 CDN 即可大幅度改善访问质量,关于如何使用内容分发网络和使用中的任何问题请联系各大云厂商。
创建并配置好资源 CDN ,在控制面板中将 server.cdn
设置项修改为 CDN 域名。(如 https://cdn.hydro.ac/
,以 /
结尾)。
如果您预算充足,可以使用全站 CDN。
Warning
全站 CDN 配置较为繁琐,如您没有相关使用经验请仅建立并配置资源 CDN ,配置资源 CDN 在大部分情况下即可大幅度改善访问质量。 因各服务商全站 CDN 配置方法不同,配置过程不同,需要配置的内容较多,以下仅为参考配置且配置补全 ,如果有任何问题建议先查阅云服务商文档及咨询云服务商工程师。
缓存设置可以参考以下设置:
类型 内容 缓存行为 全部文件 全部文件 遵循源站 文件后缀 jpg,js,png,css,gif 缓存一天
同时设置添加回源HTTP请求头
头部参数 头部取值 X-Forward-For 参考所使用服务商CDN文档来设置用户来源IP
且您应当修改系统设置中的 server.xff
值为 X-Forwarded-For
,该设置是为了能够让系统正确获取到用户的IP地址。
',12)],o={},n=(0,d(3744).Z)(o,[["render",function(t,e){return(0,r.wg)(),(0,r.iD)("div",null,a)}]])},3744:(t,e)=>{e.Z=(t,e)=>{const d=t.__vccOpts||t;for(const[t,r]of e)d[t]=r;return d}}}]);
\ No newline at end of file
diff --git a/assets/js/v-0a853913.cc59ad03.js b/assets/js/v-0a853913.cc59ad03.js
new file mode 100644
index 00000000..9d5d9c45
--- /dev/null
+++ b/assets/js/v-0a853913.cc59ad03.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[9580],{3972:(e,t,a)=>{a.r(t),a.d(t,{data:()=>n});const n=JSON.parse('{"key":"v-0a853913","path":"/dev/db-layout.html","title":"数据库结构","lang":"en-US","frontmatter":{"description":"document 基础列:(domainId, docId, docType), owner, title, content 存储所有文档,包括题目,比赛,训练等等,使用 docType 字段区分文档类型,docType 的定义可参照 packages/hydrooj/src/model/document.ts 。 document.status 基础...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/db-layout.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"数据库结构"}],["meta",{"property":"og:description","content":"document 基础列:(domainId, docId, docType), owner, title, content 存储所有文档,包括题目,比赛,训练等等,使用 docType 字段区分文档类型,docType 的定义可参照 packages/hydrooj/src/model/document.ts 。 document.status 基础..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-29T15:46:47.000Z"}],["meta",{"property":"article:modified_time","content":"2024-02-29T15:46:47.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"数据库结构\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-02-29T15:46:47.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"document","slug":"document","link":"#document","children":[]},{"level":2,"title":"document.status","slug":"document-status","link":"#document-status","children":[]},{"level":2,"title":"record","slug":"record","link":"#record","children":[]},{"level":2,"title":"user","slug":"user","link":"#user","children":[]},{"level":2,"title":"oplog","slug":"oplog","link":"#oplog","children":[]},{"level":2,"title":"blacklist","slug":"blacklist","link":"#blacklist","children":[]},{"level":2,"title":"system","slug":"system","link":"#system","children":[]},{"level":2,"title":"task","slug":"task","link":"#task","children":[]},{"level":2,"title":"event","slug":"event","link":"#event","children":[]},{"level":2,"title":"schedule","slug":"schedule","link":"#schedule","children":[]},{"level":2,"title":"opcount","slug":"opcount","link":"#opcount","children":[]},{"level":2,"title":"token","slug":"token","link":"#token","children":[]}],"git":{"createdTime":1709221607000,"updatedTime":1709221607000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":0.7,"words":209},"filePathRelative":"dev/db-layout.md","localizedDate":"February 29, 2024","autoDesc":true,"excerpt":""}')},2471:(e,t,a)=>{a.r(t),a.d(t,{default:()=>s});var n=a(6252);const o=[(0,n.uE)('基础列:(domainId, docId, docType), owner, title, content 存储所有文档,包括题目,比赛,训练等等,使用 docType 字段区分文档类型,docType 的定义可参照 packages/hydrooj/src/model/document.ts 。
基础列:(domainId, docId, docType, uid), owner, title, content 存储用户在对应文档下留下的信息,如题目的提交状态,比赛的成绩等等。
基础列:((_id), domainId), uid, code, lang, score, status 存储用户的提交记录。
基础列:(_id), uname, unameLower, mail, mailLower, priv 在系统中的所有用户。
存储系统日志。
用于提交队列等。
用于处理 Hydro 的内部事件通讯,请勿手动操作。
定时任务相关。
用于记录用户的访问情况,作频率限制用
存储临时信息,如登陆状态,注册验证码等
',23)],d={},s=(0,a(3744).Z)(d,[["render",function(e,t){return(0,n.wg)(),(0,n.iD)("div",null,o)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const a=e.__vccOpts||e;for(const[e,n]of t)a[e]=n;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-147825fb.875fdfbc.js b/assets/js/v-147825fb.875fdfbc.js
new file mode 100644
index 00000000..bfe5e132
--- /dev/null
+++ b/assets/js/v-147825fb.875fdfbc.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[8814],{6872:(t,e,n)=>{n.r(e),n.d(e,{data:()=>a});const a=JSON.parse('{"key":"v-147825fb","path":"/docs/","title":"介绍","lang":"en-US","frontmatter":{"description":"为什么使用 Hydro? 安全:使用 Linux 容器技术(只读文件系统,命名空间和 cgroup )进行隔离,杜绝卡评测;; 高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;; 扩展:Hydro 支持安装额外模块进行扩展;; 强大:配合 Judge 模块(或 HydroJudge 独立评测机),可支持 spj,交互题,提交答案题,文件IO ...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"介绍"}],["meta",{"property":"og:description","content":"为什么使用 Hydro? 安全:使用 Linux 容器技术(只读文件系统,命名空间和 cgroup )进行隔离,杜绝卡评测;; 高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;; 扩展:Hydro 支持安装额外模块进行扩展;; 强大:配合 Judge 模块(或 HydroJudge 独立评测机),可支持 spj,交互题,提交答案题,文件IO ..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://hydro.js.org/"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-12T12:11:12.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"介绍"}],["meta",{"property":"article:modified_time","content":"2024-04-12T12:11:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"介绍\\",\\"image\\":[\\"https://hydro.js.org/\\"],\\"dateModified\\":\\"2024-04-12T12:11:12.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"功能对比","slug":"功能对比","link":"#功能对比","children":[]},{"level":2,"title":"截图","slug":"截图","link":"#截图","children":[]},{"level":2,"title":"现在开始","slug":"现在开始","link":"#现在开始","children":[]}],"git":{"createdTime":1611599229000,"updatedTime":1712923872000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":14},{"name":"Macesuted","email":"macesuted@qq.com","commits":5},{"name":"(Macesuted)","email":"macesuted@foxmail.com","commits":2},{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":1},{"name":"criyle","email":"gaoyang4425@gmail.com","commits":1},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":2.52,"words":756},"filePathRelative":"docs/README.md","localizedDate":"January 25, 2021","autoDesc":true,"excerpt":""}')},3865:(t,e,n)=>{n.r(e),n.d(e,{default:()=>x});var a=n(6252);const l=n.p+"assets/img/pict1.648ac21a.png",o=n.p+"assets/img/pict2.da01d875.png",s=n.p+"assets/img/pict3.f80950a4.png",d=n.p+"assets/img/pict4.c80cad4f.png",r=n.p+"assets/img/pict5.5b00151d.png",i=n.p+"assets/img/pict6.241e3a35.png",c=n.p+"assets/img/pict7.13f6d1d4.png",g=n.p+"assets/img/pict8.dc7fa749.png",p=(0,a.uE)('为什么使用 Hydro?
安全:使用 Linux 容器技术(只读文件系统,命名空间和 cgroup )进行隔离,杜绝卡评测;
高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;
扩展:Hydro 支持安装额外模块进行扩展;
强大:配合 Judge 模块(或 HydroJudge 独立评测机),可支持 spj,交互题,提交答案题,文件IO 等多种特性;
自定:所有权限节点均可自由设置;
易上手:无需改动源代码,系统设置中预留了大量可自行修改的内容;管理逻辑简洁;
社区:Hydro 正在持续维护中;
如果您正在使用 HustOJ,可以导出题目为 FPS 文件后使用 fps-importer 插件 直接导入 Hydro。
如果您正在使用 QDUOJ, 可以导出题目为 QDUOJ-zip 格式后使用 import-qduoj 插件直接导入 Hydro。
如果您正在使用 Vijos / SYZOJ / HustOJ / UniversalOJ, 可以直接使用 migrate 插件 导入所有数据至 Hydro。
Hydro 支持很多其他系统无法支持的题型,可在 https://hydro.ac/d/system_test/p 中查看并免费下载使用样例。(需要登录) 下方对比了 Hydro 与其他主流 OJ 系统的功能。(只进行在不修改源代码情况下的对比)
+:支持 \n=:部分支持 \n?: 未知 \n-:不支持 \n
功能 Hydro HustOJ SYZOJ QDUOJ Vijos 安装 一键脚本 一键脚本 手动搭建 docker docker 数据库 MongoDB MySQL MariaDB Postgres MongoDB 测试数据存储 本地/S3 本地 本地 本地 数据库 多评测机 + = = = + 测试数据同步 按需抓取 全量同步 全量同步 全量同步 按需抓取 比赛 ACM/OI/IOI/乐多 ACM/OI ACM/OI/IOI ACM/OI/IOI ACM/OI 封榜 + + - - - 作业功能 + + - - + 修改编译命令/添加语言 + = - - + 权限系统 + = - - + 训练计划(题单) + + - - + 团队 + - - - + Hack + - - - - SpecialJudge + + + - = Subtask + - + - - 交互题 + - + - - RemoteJudge CF/SPOJ/UOJ/POJ/Luogu HDU/PKU - - - 题目导入 fps/syzoj/qduoj/hydro fps/qduoj syzoj fps/qduoj -
',10),y=(0,a.uE)('',2),f={},x=(0,n(3744).Z)(f,[["render",function(t,e){const n=(0,a.up)("RouterLink");return(0,a.wg)(),(0,a.iD)("div",null,[p,(0,a._)("p",null,[(0,a.Uk)("点击 "),(0,a.Wm)(n,{to:"/docs/install/"},{default:(0,a.w5)((()=>[(0,a.Uk)("部署")])),_:1}),(0,a.Uk)(" ,开始部署您的 OJ 吧!")]),y])}]])},3744:(t,e)=>{e.Z=(t,e)=>{const n=t.__vccOpts||t;for(const[t,a]of e)n[t]=a;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-16bdf429.24c74640.js b/assets/js/v-16bdf429.24c74640.js
new file mode 100644
index 00000000..d1e7a41a
--- /dev/null
+++ b/assets/js/v-16bdf429.24c74640.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[3925],{7688:(e,t,o)=>{o.r(t),o.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-16bdf429","path":"/plugins/geoip.html","title":"GeoIP","lang":"en-US","frontmatter":{"description":"插件需要 MaxMind 的 Geolite2-City.mmdb 支持,在安装插件后需要将mmdb拷贝至插件同一目录下方可启用,如果你不知道这是什么,请勿安装。","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/geoip.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"GeoIP"}],["meta",{"property":"og:description","content":"插件需要 MaxMind 的 Geolite2-City.mmdb 支持,在安装插件后需要将mmdb拷贝至插件同一目录下方可启用,如果你不知道这是什么,请勿安装。"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-02-25T05:29:05.000Z"}],["meta",{"property":"article:modified_time","content":"2023-02-25T05:29:05.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"GeoIP\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-02-25T05:29:05.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1677302945000,"updatedTime":1677302945000,"contributors":[{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":0.16,"words":49},"filePathRelative":"plugins/geoip.md","localizedDate":"February 25, 2023","autoDesc":true,"excerpt":""}')},9150:(e,t,o)=>{o.r(t),o.d(t,{default:()=>a});var i=o(6252);const n=[(0,i._)("h1",{id:"geoip",tabindex:"-1"},[(0,i._)("a",{class:"header-anchor",href:"#geoip"},[(0,i._)("span",null,"GeoIP")])],-1),(0,i._)("p",null,[(0,i.Uk)("插件需要 MaxMind 的 "),(0,i._)("code",null,"Geolite2-City.mmdb"),(0,i.Uk)(" 支持,在安装插件后需要将mmdb拷贝至插件同一目录下方可启用,如果你不知道这是什么,请勿安装。")],-1)],r={},a=(0,o(3744).Z)(r,[["render",function(e,t){return(0,i.wg)(),(0,i.iD)("div",null,n)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,i]of t)o[e]=i;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-19b5347a.a216bc48.js b/assets/js/v-19b5347a.a216bc48.js
new file mode 100644
index 00000000..8b67a1c7
--- /dev/null
+++ b/assets/js/v-19b5347a.a216bc48.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[8408],{3694:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-19b5347a","path":"/dev/hook.html","title":"使用 TypeScript 编写插件","lang":"en-US","frontmatter":{"description":"请注意:在阅读本节之前,请确认您已阅读【使用 TypeScript 编写插件】一节并已完成了插件的创建。 示例","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/hook.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"使用 TypeScript 编写插件"}],["meta",{"property":"og:description","content":"请注意:在阅读本节之前,请确认您已阅读【使用 TypeScript 编写插件】一节并已完成了插件的创建。 示例"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-03T09:19:20.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-03T09:19:20.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"使用 TypeScript 编写插件\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-03T09:19:20.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"示例","slug":"示例","link":"#示例","children":[]}],"git":{"createdTime":1684507766000,"updatedTime":1712135960000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"Milmon","email":"115549630@qq.com","commits":1},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":0.75,"words":224},"filePathRelative":"dev/hook.md","localizedDate":"May 19, 2023","autoDesc":true,"excerpt":""}')},8371:(s,n,a)=>{a.r(n),a.d(n,{default:()=>e});var l=a(6252);const p=[(0,l.uE)('请注意:在阅读本节之前,请确认您已阅读【使用 TypeScript 编写插件】一节并已完成了插件的创建。
import { Context , Time } from ' hydrooj ' ; \n \nexport async function apply ( ctx : Context ) { \n // handler 表示路由事件 \n // after 表示在主逻辑完成后运行,同时支持 before, before-operation, 参照 【插件编写】 章节 【请求流程】 \n // RecordDetail 为需要捕获的路由名 \n // #get 表示仅捕获 GET 请求,若无此后缀表示捕获该路由的所有请求 \n ctx . on ( ' handler/after/RecordDetail#get ' , ( h ) => { // handler 系列钩子的一参数为对应的 Handler 实例 \n // 不允许查看 24 小时以前的提交记录 \n if ( h . rdoc . _id . getTimestamp () < new Date ( Date . now () - Time . day )) { \n h . rdoc . code = '' ; \n } \n } ) ; \n} \n
import { Context } from ' hydrooj ' ; \n \nasync function getAnnounce ( domainId : string , limit = 5 ) { \n // 获取公告... \n return adocs ; \n} \n \nexport async function apply ( ctx : Context ) { \n ctx . withHandlerClass ( ' HomeHandler ' , ( HomeHandler ) => { \n // 修改 HomeHandler 中的一个方法(添加公告) \n HomeHandler . prototype . getAnnounce = getAnnounce ; \n } ) ; \n} \n
',5)],o={},e=(0,a(3744).Z)(o,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,p)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-1a155670.b762e846.js b/assets/js/v-1a155670.b762e846.js
new file mode 100644
index 00000000..815de995
--- /dev/null
+++ b/assets/js/v-1a155670.b762e846.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2448],{8886:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-1a155670","path":"/api/judge.html","title":"评测端通信协议","lang":"en-US","frontmatter":{"description":"当前版本 v1 。 评测端交互流程 GET /judge/files (检查登陆状态是否有效,若无效则跳转登录逻辑,通常每六小时执行一次); WEBSOCKET /judge/conn (主交互通道); 若登录失效,则进行登录操作。 WebSocket 连接建立流程 连接建立后,评测端向 Web 汇报当前节点状态(可选) 注:下方信息仅作数据格式展示用...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/api/judge.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"评测端通信协议"}],["meta",{"property":"og:description","content":"当前版本 v1 。 评测端交互流程 GET /judge/files (检查登陆状态是否有效,若无效则跳转登录逻辑,通常每六小时执行一次); WEBSOCKET /judge/conn (主交互通道); 若登录失效,则进行登录操作。 WebSocket 连接建立流程 连接建立后,评测端向 Web 汇报当前节点状态(可选) 注:下方信息仅作数据格式展示用..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-11-23T03:00:48.000Z"}],["meta",{"property":"article:modified_time","content":"2023-11-23T03:00:48.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"评测端通信协议\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-23T03:00:48.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"评测端交互流程","slug":"评测端交互流程","link":"#评测端交互流程","children":[]},{"level":2,"title":"WebSocket 连接建立流程","slug":"websocket-连接建立流程","link":"#websocket-连接建立流程","children":[]},{"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":{"createdTime":1700615513000,"updatedTime":1700708448000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2}]},"readingTime":{"minutes":2.2,"words":661},"filePathRelative":"api/judge.md","localizedDate":"November 22, 2023","autoDesc":true,"excerpt":""}')},3693:(s,n,a)=>{a.r(n),a.d(n,{default:()=>C});var l=a(6252);const o=(0,l.uE)('当前版本 v1 。
GET /judge/files (检查登陆状态是否有效,若无效则跳转登录逻辑,通常每六小时执行一次) WEBSOCKET /judge/conn (主交互通道) 若登录失效,则进行登录操作。
POST /login \n \n{ " uname " : " USERNAME " , " password " : " PASSWORD " , " rememberme " : true } \n
WEBSOCKET /judge/conn \nAuthorization: Bearer COOKIE_SID \n
连接建立后,评测端向 Web 汇报当前节点状态(可选) 注:下方信息仅作数据格式展示用,不保证真实有效。
{ \n " key " : " status " , \n " info " : { \n " mid " : " MACHINE_ID " , \n " memory " : { \n " total " : 25189552128 , \n " free " : 660258800 , \n " used " : 24529293328 , \n " active " : 1558973164 , \n " available " : 23636676608 , \n " buffers " : 3075653000 , \n " cached " : 1000000000 , \n " slab " : 1000000000 , \n " buffcache " : 1000000000 , \n " swaptotal " : 0 , \n " swapused " : 0 , \n " swapfree " : 0 \n }, \n " cpu " : { \n " manufacturer " : " Intel " , \n " brand " : " Xeon® Platinum 8269CY " , \n " vendor " : " Intel " , \n " family " : " 6 " , \n " model " : " 85 " , \n " stepping " : " 7 " , \n " speed " : 2.5 , \n " cores " : 32 , \n " physicalCores " : 32 , \n " processors " : 2 , \n " flags " : " fpu vme de pse tsc ... " , \n " cache " : { \n " l1d " : 32768 , \n " l1i " : 32768 , \n " l2 " : 262144 , \n " l3 " : 6291456 \n } \n }, \n " load " : { \n " avgLoad " : 0.01 , \n " currentLoad " : 0.01 , \n " currentLoadUser " : 0.01 , \n " currentLoadSystem " : 0.01 , \n " currentLoadNice " : 0.01 , \n " currentLoadIdle " : 0.01 , \n " currentLoadIrq " : 0.01 \n }, \n " osinfo " : { \n " platform " : " linux " , \n " distro " : " Ubuntu " , \n " release " : " 22.04.2 LTS " , \n " codename " : " Jammy Jellyfish " , \n " kernel " : " 5.15.0-84-generic " , \n " arch " : " x64 " , \n " hostname " : " judge " , \n " codepage " : " UTF-8 " , \n } \n } \n} \n
建立连接后每隔 30s,评测端发送 {"key":"ping"}
。
在连接建立后,Web 端会向 Judge 分发服务端的语言设置。如果客户端需要进行特殊设置,可忽略此条消息。
Web 端会通过 WebSocket 向评测端推送评测任务。
{ \n " task " : { \n " type " : " judge " , \n " _id " : " RECORD_ID " , \n " lang " : " cc.cc11 " , \n " uid " : SUBMITTER_UID , \n " code " : " USER_SUBMITTED_CODE " , \n " domainId " : " SUBMISSION_DOMAIN_ID " , \n " pid " : PROBLEM_ID , \n " contest " : " CONTEST_ID (optional) " , \n " input " : " INPUT " , \n " source " : " SOURCE_ID " , \n " meta " : { \n " rejudge " : false , \n " problemOwner " : OWNER_UID \n }, \n " data " : [ \n { \n " name " : " FILE_NAME " , \n " size " : SIZE_IN_BYTES , \n " lastModified " : " 2023-11-15T08:14:57.535Z " , \n " etag " : " ETAG " \n } \n ] \n } \n} \n
注1:如果比赛 ID 为 000000000000000000000000
则表示此提交为自测提交,自测提交使用 input
字段值作为程序输入。 注2:source
字段为缓存 ID,同 source
字段的提交使用相同的缓存目录。 注3:source
字段包含且仅包含一个字符 /
,建议使用 domainId/pid
。 注4:测试数据的 etag 用来识别本地缓存的文件是否与云端一致,可使用 hash 或是修改时间的时间戳。
若推送的评测任务中使用了的测试数据缺失,Judge 端会向 Web 请求缺失或是修改的文件。
POST /d/:domainId/judge/files \nCookie: sid=COOKIE_SID \n \n{ " pid " : PROBLEM_ID , " files " :[ " a.in " , " a.out " ]} \n
服务端返回如下:
{ \n " links " : { \n " a.in " : " https://cdn.hydro.ac/d/DOMAIN_ID/pid/1/a.in " , \n " a.out " : " https://cdn.hydro.ac/d/DOMAIN_ID/pid/1/a.out " \n } \n} \n
{ \n " key " : " next/end " , \n " domainId " : " DOMAIN_ID " , \n " rid " : " RECORD_ID " , \n \n " message " : " JUDGE_MESSAGE " , \n " compilerText " : " COMPILER_OUTPUT " , \n " status " : STATUS_CODE , \n " score " : SCORE , \n " time " : TIME_IN_MS , \n " memory " : MEMORY_IN_KB , \n " progress " : PROGRESS_PERCENTAGE , \n " addProgress " : PROGRESS_PERCENTAGE , \n " case " : { \n " id " : ID , \n " subtaskId " : SUBTASK_ID , \n " score " : SCORE , \n " status " : STATUS_CODE , \n " message " : " CHECKER_MESSAGE " \n } \n} \n
',24),p=(0,l._)("code",null,"key",-1),e=(0,l._)("code",null,"domainId",-1),E=(0,l._)("code",null,"rid",-1),F=(0,l._)("code",null,"STATUS_CODE",-1),t={href:"https://github.com/hydro-dev/Hydro/blob/master/packages/utils/lib/status.ts",target:"_blank",rel:"noopener noreferrer"},c=(0,l._)("br",null,null,-1),r=(0,l._)("code",null,"key",-1),y=(0,l._)("code",null,"end",-1),i={},C=(0,a(3744).Z)(i,[["render",function(s,n){const a=(0,l.up)("ExternalLinkIcon");return(0,l.wg)(),(0,l.iD)("div",null,[o,(0,l._)("p",null,[(0,l.Uk)("除 "),p,(0,l.Uk)(", "),e,(0,l.Uk)(", "),E,(0,l.Uk)(" 三个字段外,其他字段均为可选。关于 "),F,(0,l.Uk)(" 含义请查看 "),(0,l._)("a",t,[(0,l.Uk)("hydro-dev/Hydro/packages/utils/lib/status"),(0,l.Wm)(a)]),(0,l.Uk)(" 。"),c,(0,l.Uk)(" 当 "),r,(0,l.Uk)(" 为 "),y,(0,l.Uk)(" 时表示评测任务已经完成,结果确定,Web 端可进行 AC 数计量,登记成绩表等操作。")])])}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-1bffc66e.b1c6e466.js b/assets/js/v-1bffc66e.b1c6e466.js
new file mode 100644
index 00000000..a88e2ac9
--- /dev/null
+++ b/assets/js/v-1bffc66e.b1c6e466.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[4718],{6344:(s,a,n)=>{n.r(a),n.d(a,{data:()=>e});const e=JSON.parse('{"key":"v-1bffc66e","path":"/docs/system/maintain.html","title":"维护","lang":"en-US","frontmatter":{"description":"PM2 使用一键安装脚本安装的 Hydro 使用 PM2 对进程进行管理。 进程名称 可以通过下面的指令查看当前 PM2 正在管理的所有进程。 一键安装脚本默认会创建下面几个进程: hydrooj: Hydro 主进程; hydro-sandbox: Hydro 评测沙箱; mongodb: MongoDB 数据库; caddy: 反向代理; 后文的指...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/maintain.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"维护"}],["meta",{"property":"og:description","content":"PM2 使用一键安装脚本安装的 Hydro 使用 PM2 对进程进行管理。 进程名称 可以通过下面的指令查看当前 PM2 正在管理的所有进程。 一键安装脚本默认会创建下面几个进程: hydrooj: Hydro 主进程; hydro-sandbox: Hydro 评测沙箱; mongodb: MongoDB 数据库; caddy: 反向代理; 后文的指..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-08-24T08:31:37.000Z"}],["meta",{"property":"article:modified_time","content":"2023-08-24T08:31:37.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"维护\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-08-24T08:31:37.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"PM2","slug":"pm2","link":"#pm2","children":[{"level":3,"title":"进程名称","slug":"进程名称","link":"#进程名称","children":[]},{"level":3,"title":"PM2 基本指令","slug":"pm2-基本指令","link":"#pm2-基本指令","children":[]}]},{"level":2,"title":"更新","slug":"更新","link":"#更新","children":[]},{"level":2,"title":"查看已安装版本","slug":"查看已安装版本","link":"#查看已安装版本","children":[]},{"level":2,"title":"清除缓存","slug":"清除缓存","link":"#清除缓存","children":[]}],"git":{"createdTime":1631785934000,"updatedTime":1692865897000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":7},{"name":"Macesuted","email":"macesuted@qq.com","commits":2}]},"readingTime":{"minutes":1.71,"words":514},"filePathRelative":"docs/system/maintain.md","localizedDate":"September 16, 2021","autoDesc":true,"excerpt":""}')},7624:(s,a,n)=>{n.r(a),n.d(a,{default:()=>p});var e=n(6252);const l=[(0,e.uE)('使用一键安装脚本安装的 Hydro 使用 PM2 对进程进行管理。
可以通过下面的指令查看当前 PM2 正在管理的所有进程。
一键安装脚本默认会创建下面几个进程:
hydrooj
: Hydro 主进程hydro-sandbox
: Hydro 评测沙箱mongodb
: MongoDB 数据库caddy
: 反向代理后文的指令中将用 <name>
替代此处的进程名称,用 <id>
替代进程 ID(进程 ID 可通过 pm2 ls
查看)。(尖括号同样需要替换)
pm2 ls # 查看进程列表 \npm2 start < i d > # 启动进程 \npm2 stop < i d > # 关闭进程 \npm2 restart < i d > # 重启进程 \npm2 del < i d > # 删除进程 \npm2 log < id/nam e > --lines=100 # 查看该进程的后 100 行日志 \npm2 attach < i d > # 与进程交互 \npm2 save # 保存对 PM2 进行的修改(在添加、修改、删除进程后需要执行该指令) \n
在部分环境(常见于 lxc 容器或是精简版系统)下,服务器重启后 Hydro 可能不能正常自启动,这时请使用 pm2 resurrect
手动载入进程列表。
如果手动修改进程列表且已经覆盖掉保存的原列表,请使用 pm2 stop all && pm2 del all
清空所有进程之后重新运行安装脚本。原有数据不会丢失。
Hydro 主进程同样支持多进程启动,但在中低端服务器(不超过4核)中没有必要使用多进程启动 Hydro,会降低性能且成倍提高内存占用。
pm2 start hydrooj -i < n > # 以 n 进程启动 Hydro 主进程 \n
Hydro 系统会不定期发布更新,可以使用下面的命令获取更新。
无特殊情况请 不要更新PM2 !此操作可能导致进程列表丢失!
yarn global upgrade-interactive --latest # 在交互式界面中选择想要更新的组件 \npm2 restart hydrooj # 更新完后需重启 hydrooj \n
cd `yarn global dir` && yarn list --pattern hydrooj \n
yarn cache clean && nix-collect-garbage \n
',23)],o={},p=(0,n(3744).Z)(o,[["render",function(s,a){return(0,e.wg)(),(0,e.iD)("div",null,l)}]])},3744:(s,a)=>{a.Z=(s,a)=>{const n=s.__vccOpts||s;for(const[s,e]of a)n[s]=e;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-1c6d3a3e.f9e063ae.js b/assets/js/v-1c6d3a3e.f9e063ae.js
new file mode 100644
index 00000000..ea088085
--- /dev/null
+++ b/assets/js/v-1c6d3a3e.f9e063ae.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[4280],{8992:(e,t,d)=>{d.r(t),d.d(t,{data:()=>o});const o=JSON.parse('{"key":"v-1c6d3a3e","path":"/dev/naming.html","title":"命名规则","lang":"en-US","frontmatter":{"description":"变量命名规则 在 Hydro 中的大部分变量有固定命名规则: pdoc: 题目; tdoc: 比赛/作业/训练; rdoc: 提交记录; ddoc: 讨论; drdoc: 讨论的回复; drrdoc: 讨论的二级回复; mdoc: 站内信息; psdoc: 题目的提交状态; tsdoc: 比赛/作业的提交状态; ... 以及它们的变种: pdocs: ...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/naming.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"命名规则"}],["meta",{"property":"og:description","content":"变量命名规则 在 Hydro 中的大部分变量有固定命名规则: pdoc: 题目; tdoc: 比赛/作业/训练; rdoc: 提交记录; ddoc: 讨论; drdoc: 讨论的回复; drrdoc: 讨论的二级回复; mdoc: 站内信息; psdoc: 题目的提交状态; tsdoc: 比赛/作业的提交状态; ... 以及它们的变种: pdocs: ..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-29T15:39:38.000Z"}],["meta",{"property":"article:modified_time","content":"2024-02-29T15:39:38.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"命名规则\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-02-29T15:39:38.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"变量命名规则","slug":"变量命名规则","link":"#变量命名规则","children":[]},{"level":2,"title":"函数命名规则","slug":"函数命名规则","link":"#函数命名规则","children":[]}],"git":{"createdTime":1709221178000,"updatedTime":1709221178000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":0.58,"words":173},"filePathRelative":"dev/naming.md","localizedDate":"February 29, 2024","autoDesc":true,"excerpt":""}')},4464:(e,t,d)=>{d.r(t),d.d(t,{default:()=>r});var o=d(6252);const i=[(0,o.uE)('在 Hydro 中的大部分变量有固定命名规则:
pdoc: 题目 tdoc: 比赛/作业/训练 rdoc: 提交记录 ddoc: 讨论 drdoc: 讨论的回复 drrdoc: 讨论的二级回复 mdoc: 站内信息 psdoc: 题目的提交状态 tsdoc: 比赛/作业的提交状态 ... 以及它们的变种:
pdocs: 包含若干题目的数组 pdict: 键为题目 id,题目详情为值的对象 ... 更多细节可在 packages/hydrooj/src/interface.ts 中找到。
get()
获取内容,返回对应值或 nullgetList()
获取内容,返回 dict 类对象getMulti()
获取数据库查询的指针edit()
更新内容 ',9)],c={},r=(0,d(3744).Z)(c,[["render",function(e,t){return(0,o.wg)(),(0,o.iD)("div",null,i)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const d=e.__vccOpts||e;for(const[e,o]of t)d[e]=o;return d}}}]);
\ No newline at end of file
diff --git a/assets/js/v-1d7ad3e6.0f664ae6.js b/assets/js/v-1d7ad3e6.0f664ae6.js
new file mode 100644
index 00000000..d5985cc5
--- /dev/null
+++ b/assets/js/v-1d7ad3e6.0f664ae6.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[830],{6494:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-1d7ad3e6","path":"/docs/user/problem-create.html","title":"Hydro常见题型的制做心得","lang":"en-US","frontmatter":{"description":"作者: laomai qq: 29985091 网址: http://82.157.98.222:8888/ 日期: 2022/03/16 本文为作者使用hydro时的实验记录,希望对大家有帮助.包括如下内容 零. hydro题目存储格式 一. 制做最简单的oj题 二. 含有自定义头文件的oj题,即函数交互式的题目 三. 半自动对拍的oj题,即不需要录...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/problem-create.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"Hydro常见题型的制做心得"}],["meta",{"property":"og:description","content":"作者: laomai qq: 29985091 网址: http://82.157.98.222:8888/ 日期: 2022/03/16 本文为作者使用hydro时的实验记录,希望对大家有帮助.包括如下内容 零. hydro题目存储格式 一. 制做最简单的oj题 二. 含有自定义头文件的oj题,即函数交互式的题目 三. 半自动对拍的oj题,即不需要录..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://hydro.js.org/"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-03T09:19:20.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"Hydro常见题型的制做心得"}],["meta",{"property":"article:modified_time","content":"2024-04-03T09:19:20.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Hydro常见题型的制做心得\\",\\"image\\":[\\"https://hydro.js.org/\\"],\\"dateModified\\":\\"2024-04-03T09:19:20.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"零. hydro题目存储格式","slug":"零-hydro题目存储格式","link":"#零-hydro题目存储格式","children":[]},{"level":2,"title":"一 制做最简单的OJ题目","slug":"一-制做最简单的oj题目","link":"#一-制做最简单的oj题目","children":[]},{"level":2,"title":"二、函数交互型题目","slug":"二、函数交互型题目","link":"#二、函数交互型题目","children":[]},{"level":2,"title":"三,半对拍-自己指定评测程序并修改测试输出格式","slug":"三-半对拍-自己指定评测程序并修改测试输出格式","link":"#三-半对拍-自己指定评测程序并修改测试输出格式","children":[]},{"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":{"createdTime":1647413236000,"updatedTime":1712135960000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"Milmon","email":"115549630@qq.com","commits":1},{"name":"laomai","email":"lmxin@tom.com","commits":1}]},"readingTime":{"minutes":8.77,"words":2631},"filePathRelative":"docs/user/problem-create.md","localizedDate":"March 16, 2022","autoDesc":true,"excerpt":""}')},9308:(s,n,a)=>{a.r(n),a.d(n,{default:()=>C});var l=a(6252);const p=a.p+"assets/img/pic1.e3e6035a.png",o=a.p+"assets/img/pic11.e88ce83a.png",e=a.p+"assets/img/pic10.1764ba03.png",c=a.p+"assets/img/pic8.527cc323.png",t=a.p+"assets/img/pic9.c3848a3f.png",r=a.p+"assets/img/pic6.595bd29d.png",E=a.p+"assets/img/pic5.8deeaff9.png",F=a.p+"assets/img/pic4.8d012475.png",i=a.p+"assets/img/pic3.1f747cd8.png",y=a.p+"assets/img/pic2.5393603a.png",d=[(0,l.uE)('作者: laomai qq: 29985091 网址: http://82.157.98.222:8888/ 日期: 2022/03/16
本文为作者使用hydro时的实验记录,希望对大家有帮助.包括如下内容
零. hydro题目存储格式 一. 制做最简单的oj题 二. 含有自定义头文件的oj题,即函数交互式的题目 三. 半自动对拍的oj题,即不需要录入预期输出的题 四. 完全对拍题,即不需要录入输入数据和输出数据的题 五. 指定输入文件和输出文件 六. 多个子任务 七. 客观题,即制做有标准答案的填空和选择题.
如果想在本地建立好题目,然后批量上传的话. 下面的格式应该对你有帮助 每个题目应自占一个目录,目录名为题目编号比如1 ,2,3,4等等. 每个题目目录下一般有下面的元素:problem_zh.md
这个文件是就是题目的内容,即题目的描述,是一个markdown格式的文档.probelm.yaml
文件.这个是题目的配置信息. 比如标题和标签等。 testdata 子目录,对应网站里的测试数据部分里的文件, 里面至少有一个config.yaml文件 用来说明测试的类型.具体内容见后面的例子 如果题目有测试用例,则每个用例至少要提供一个in文件和一个输出文件(但有些测试类型不用,详情见后) additional_file子目录用来存放给做题者用的额外文件,比如头文件,图片,pdf文档等,在题目的 markdown 文档中可以用下面的格式为这些文件提供下载链接:[提示文字](file://xxx.txt)
下面为手工录入各种题型的步骤,即在网站登录后点创建题目之后的操作.如下图所示
我们假定题目内容均为下面的markdown文档
# 要求\n\n输入两个整数,输出他们的和\n\n# 样例\n\n```input1\n123 500\n```\n\n```output1\n623\n```\n
题目网址: http://82.157.98.222:8888/p/P10000
新建题目之后编辑题目内容,输入题号和标题,然后点创建按钮。如下图所示. 此时出现下面的图,点创建文件,文件名为 1.in
, 表示用例 1 的输入 编辑 1.in
的内容为两个整数比如 2 和 3 ,空格分开,如下图所示,然后点确定 类似办法创建一个 1.out
文件,内容为 5 ,注意数字编号必须和 in 文件一致,创建之后的文件列表和下面类似.
这样第一个用例的输入和预期输出就录入完毕,现在可以做本题了 本题的 AC 代码为: # include < iostream > \nusing namespace std ; \nint main ( int argc , char* argv []){ \n int a , b ; \n cin >> a >> b ; \n cout << ( a + b ) ; \n return 0 ; \n} \n
题目网址: http://82.157.98.222:8888/p/P10001 本类型和类型一的区别在于出题者要向做题者提供一个额外的头文件,做题者的主函数里可以包含这个头文件以调用出题者提供的某些函数,或者实现头文件里指定的函数.
题目内容的录入以及测试数据的录入和类型一样 本题要额外上传两个文件.分别为 tools.h
和 config.yaml
,如下图所示
tools.h
的内容为
# include < iostream > \nusing namespace std ; \n \nint add ( int x , int y ) ; //留待做题者实现 \n \nint main ( int argc , char* argv []){ \n int a , b ; \n cin >> a >> b ; \n cout << add ( a , b ) ; \n return 0 ; \n} \n
这个头文件里实现了一个主函数,并且声明了需要做题者实现的函数add,当然,出题者应该在题目要求里写明这个函数的原型以及把tools.h文件上传到附加文件列表中,以方便做题者. 题面里可以用如下格式为用户提供下载链接,中括号内的内容可以自己写,[tools.h](file://tools.h) 如下面所示
config.yaml文件的内容为
type : default \nfilename : null \nuser_extra_files : \n - tools.h \n
本题的ac代码为
# include " tools.h " \nint add ( int x , int y ){ \n return x + y ; \n} \n
可见本类型的题目,做题者包含给定的头文件后,可以不需要自己实现主函数,只需要专心实现给定的函数即可.
例题网址:http://82.157.98.222:8888/p/P10002 本题型的特点是不需要手工给出每个用例的预期输出,但是要自己编写一个样本程序,测试时会把用户的输出和样本程序的输出进行对比。
仍以两数求和为例
题目内容和类型一类似 测试数据部分只需要提供1.in 编写一个样本程序 checker.cc
,内容如下: # include " testlib.h " \nint main ( int argc , char * argv []) { \n registerTestlibCmd ( argc , argv ) ; \n int a = inf . readInt () ; // 读取输入流的第一个整数 \n int b = inf . readInt () ; // 读取输入流的下一个整数 \n int d = a + b ; \n int c = ouf . readInt () ; // 读取输出流的下一个整数 \n if ( a + b != c ) \n quitf ( _wa , " %d + %d expected %d, found %d " , a , b , d , c ) ; //输出错误的具体信息,便于做题者调试 \n else \n quitf ( _ok , " answer of %d + %d is %d " , a , b , c ) ; \n} \n
config.yaml文件的内容如下: checker_type : testlib \nchecker : checker.cc \ncases : \n - input : 1.in \n output : /dev/null # 无输出 \n
最终的测试文件列表如下所示:
当程序有错误时,输出的效果如下
可见这里输出了错误细节,便于做题者调试
本题的ac代码和类型一的一样,内容为
# include < iostream > \nusing namespace std ; \nint main ( int argc , char* argv []){ \n int a , b ; \n cin >> a >> b ; \n cout << ( a + b ) ; \n return 0 ; \n} \n
如果不希望自己录入输入数据,而是在每次测试时自动动态生成的话,可以将题目类型设为interactive
,并提供一个对拍程序.仍以求和为例 例题网址: http://82.157.98.222:8888/p/P10005
最后测试数据部分的文件列表如下图所示
checker.cc
,内容为:# include " testlib.h " \n# include < iostream > \nusing namespace std ; \n \nint main ( int argc , char* argv []) { \n setName ( " Interactor A+B " ) ; \n registerInteraction ( argc , argv ) ; \n //自动生成两个随机整数 \n rnd . setSeed ( time ( NULL )) ; \n int a = rnd . next ( 1000 ) ; \n int b = rnd . next ( 1000 ) ; \n // 本程序的输出将作为用户程序的输入 \n cout << a << " " << b << endl ; \n int c ; \n // 用户程序的最后输出将作为本程序的输入 \n cin >> c ; \n //对比用户结果和预期结果 \n if ( a + b != c ) \n quitf ( _wa , " %d + %d expected %d, found %d " , a , b , a + b , c ) ; //输出错误的具体信息,便于做题者调试 \n else \n quitf ( _ok , " answer of %d + %d is %d " , a , b , c ) ; \n} \n
config.yaml
文件的内容为:type : interactive \ninteractor : checker.cc \ncases : \n- input : /dev/null # no input and no output, dynamic generated \n output : /dev/null \n- input : /dev/null # no input and no output, dynamic generated \n output : /dev/null \n
AC 代码和类型一中的相同
例题网址:http://82.157.98.222:8888/p/P10003 有时希望指定输入和输出文件,此时测试文件 1.in
和 1.out
和类型一类似, 但是要提供config.yaml文件,内容类似于下
则运行时测试环境会自动把每个输入文件复制到test.in中,输出内容和test.out的内容进行对比. ac的代码如下:
# include < fstream > \nusing namespace std ; \nint main ( int argc , char* argv []){ \n int a , b ; \n ifstream ifs ( " test.in " ) ; \n ifs >> a >> b ; \n ofstream ofs ( " test.out " ) ; \n ofs << ( a + b ) ; \n return 0 ; \n} \n
例题网址: https://hydro.ac/d/system_test/p/7
提供好题目和各个子任务的输入、输出文件 建议文件名格式为 data<id>-<数字>
id为子任务编号 config.yaml文件的内容参考如下 time : 100ms \nmemory : 8m \nsubtasks : \n - score : 20 \n id : 0 \n cases : \n - input : data1-1.in \n output : data1-1.ans \n - input : data1-2.in \n output : data1-2.ans \n - input : data1-3.in \n output : data1-3.ans \n - input : data1-4.in \n output : data1-4.ans \n - input : data1-5.in \n output : data1-5.ans \n - score : 20 \n id : 1 \n cases : \n - input : data2-1.in \n output : data2-1.ans \n - input : data2-2.in \n output : data2-2.ans \n - input : data2-3.in \n output : data2-3.ans \n - input : data2-4.in \n output : data2-4.ans \n - input : data2-5.in \n output : data2-5.ans \n - score : 20 \n id : 2 \n cases : \n - input : data3-1.in \n output : data3-1.ans \n - input : data3-2.in \n output : data3-2.ans \n - input : data3-3.in \n output : data3-3.ans \n - input : data3-4.in \n output : data3-4.ans \n - input : data3-5.in \n output : data3-5.ans \n - score : 20 \n id : 3 \n if : [ 2 ] \n cases : \n - input : data4-1.in \n output : data4-1.ans \n - input : data4-2.in \n output : data4-2.ans \n - input : data4-3.in \n output : data4-3.ans \n - input : data4-4.in \n output : data4-4.ans \n - input : data4-5.in \n output : data4-5.ans \n - score : 20 \n id : 4 \n if : [ 1 , 3 ] \n cases : \n - input : data5-1.in \n output : data5-1.ans \n - input : data5-2.in \n output : data5-2.ans \n - input : data5-3.in \n output : data5-3.ans \n - input : data5-4.in \n output : data5-4.ans \n - input : data5-5.in \n output : data5-5.ans \n
可以看出if 用来指定前置子任务. 此外,如果某个子任务没有提供cases部分时,测试时会自动寻找类似于 data<id>-x.in
和data<id>-x.out
的文件,id为子任务编号 上面的例子故意设计为子任务编号和用例文件中的编号不同,所有每个子任务都需要手工指定对应的cases.
注意新版的客观题,格式已经更新。
例题网址:http://82.157.98.222:8888/p/P10004 客观题只需要题面和config.yaml文件. 例子如下:
1. 填空题 \n \n1+1 = {{ input(1) }} \n \n2. 选择题 \n \n{{ select(2) }} \n- 1+1=2 \n- 1+1=3 \n- 1+1=4 \n \n3. 多选题 \n \n{{ multiselect(3) }} \n- A \n- B \n- C \n \n
上传的 config.yaml
内容为
type : objective # 表明该题为客观题 \nanswers : # 列举出每一题的正确选项与对应的得分 \n ' 1 ' : [ ' 2 ' , 50 ] \n ' 2 ' : [[ ' A ' , ' B ' ], 30 ] # 填空题支持多答案,满足其一得分 \n ' 3 ' : [[ ' A ' , ' B ' ], 20 ] # 多选题答案为数组,有部分分 \n \n
题目运行效果如下:
做完之后点提交,效果如下
可见评分结果正确.
对所有编程题目,题面是必须录入的,如果指定了测试程序时,可以不需要录入输出数据. 如果设置测试方式为interactive,输入数据也不需要手工录入. 想指特殊的测试方式时,一般需要上传一个config.yaml文件,并设置对应字段的值. 对编程题,本文档中用到的字段有
type字段一般为default, 对全自动对拍题,设为interactive
checker_type: testlib checker: checker.cc 用来指定自定义的测试程序,即对拍程序
filename: test用来指定对test.in文件和test.out文件进行读写.
cases:
用来指定测试用例.
更详细的介绍见 https://hydro.js.org/docs/user/testdata/
',87)],D={},C=(0,a(3744).Z)(D,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,d)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-2250b6d9.21117f9e.js b/assets/js/v-2250b6d9.21117f9e.js
new file mode 100644
index 00000000..b8e00e2e
--- /dev/null
+++ b/assets/js/v-2250b6d9.21117f9e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[6331],{6910:(e,t,o)=>{o.r(t),o.d(t,{data:()=>n});const n=JSON.parse('{"key":"v-2250b6d9","path":"/docs/system/database.html","title":"数据库备份和恢复","lang":"en-US","frontmatter":{"description":"进入数据库 非常不推荐直接操作数据库! 1. 当你改动一个字段的时候,可能与其相关的部分忘记修改,改完觉得好像没什么问题,过段时间发现了一些异常,根本不会想到是你这次改数据库导致的,之后又不会修。 2. 直接修改数据库后,可能没有通知主程序,缓存仍然存在,表现为修改不生效。 3. 直接操作数据库的权限过大,若操作失误带来的影响通常是灾难性的。 在绝大部...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/database.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"数据库备份和恢复"}],["meta",{"property":"og:description","content":"进入数据库 非常不推荐直接操作数据库! 1. 当你改动一个字段的时候,可能与其相关的部分忘记修改,改完觉得好像没什么问题,过段时间发现了一些异常,根本不会想到是你这次改数据库导致的,之后又不会修。 2. 直接修改数据库后,可能没有通知主程序,缓存仍然存在,表现为修改不生效。 3. 直接操作数据库的权限过大,若操作失误带来的影响通常是灾难性的。 在绝大部..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-03T09:17:20.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-03T09:17:20.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"数据库备份和恢复\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-03T09:17:20.000Z\\",\\"author\\":[]}"]]},"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":{"createdTime":1628908242000,"updatedTime":1712135840000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":4},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"Macesuted","email":"macesuted@qq.com","commits":1},{"name":"pt3155420267","email":"33685002+pt3155420267@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":1.79,"words":536},"filePathRelative":"docs/system/database.md","localizedDate":"August 14, 2021","autoDesc":true,"excerpt":""}')},7814:(e,t,o)=>{o.r(t),o.d(t,{default:()=>k});var n=o(6252);const a=(0,n.uE)('Warning
非常不推荐直接操作数据库!
当你改动一个字段的时候,可能与其相关的部分忘记修改,改完觉得好像没什么问题,过段时间发现了一些异常,根本不会想到是你这次改数据库导致的,之后又不会修。 直接修改数据库后,可能没有通知主程序,缓存仍然存在,表现为修改不生效。 直接操作数据库的权限过大,若操作失误带来的影响通常是灾难性的。 在绝大部分情况下均不需要/不可以直接操作数据库。若确需要,可使用 hydrooj db
命令打开数据库 shell,也可以从 ~/.hydro/config.json
查找数据库 connection string 并使用外部工具进行连接。
注:MongoDB 的用户是附加在特定数据库中的,使用外部工具连接请确保使用了正确的 authSource
选项。
为了保证数据安全,请定期备份。
若您使用自动脚本安装,可使用 hydrooj backup
快捷备份数据,备份完成后会在当前目录生成备份压缩包文件,您可使用 hydrooj restore <备份文件路径>
恢复之前备份的数据。
',9),r={href:"https://docs.mongodb.com/database-tools/mongodump/",target:"_blank",rel:"noopener noreferrer"},l=(0,n._)("code",null,"/data/file",-1),d=(0,n._)("p",null,[(0,n.Uk)("对于数据库,请"),(0,n._)("strong",null,"请不要在数据库运行时直接拷贝数据库文件夹"),(0,n.Uk)("。请每次备份后检查生成的备份文件的大小和内容,确保备份成功。"),(0,n._)("br"),(0,n.Uk)(" 请不要把备份数据和 Hydro 系统放在同一台机器上,这样数据丢失的风险仍然较高。")],-1),i=(0,n._)("h2",{id:"手动恢复备份",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#手动恢复备份"},[(0,n._)("span",null,"手动恢复备份")])],-1),s={href:"https://docs.mongodb.com/database-tools/mongorestore/",target:"_blank",rel:"noopener noreferrer"},c=(0,n._)("code",null,"/data/file",-1),p=(0,n._)("br",null,null,-1),h=(0,n._)("strong",null,"停止 Hydro 和 MongoDB 服务后",-1),m=(0,n._)("code",null,"/data/db",-1),u=(0,n._)("code",null,"/data/file",-1),g=(0,n._)("code",null,"/root/.hydro/config.json",-1),_={},k=(0,o(3744).Z)(_,[["render",function(e,t){const o=(0,n.up)("ExternalLinkIcon");return(0,n.wg)(),(0,n.iD)("div",null,[a,(0,n._)("p",null,[(0,n.Uk)("可使用 MongoDB 自带的 "),(0,n._)("a",r,[(0,n.Uk)("mongodump"),(0,n.Wm)(o)]),(0,n.Uk)(" 进行数据库备份。并将 "),l,(0,n.Uk)(" 文件夹备份即可。")]),d,i,(0,n._)("p",null,[(0,n.Uk)("使用 MongoDB 自带的 "),(0,n._)("a",s,[(0,n.Uk)("mongorestore"),(0,n.Wm)(o)]),(0,n.Uk)(" 导入备份的数据库文件,并还原 "),c,(0,n.Uk)(" 目录文件。"),p,(0,n.Uk)(" 如果只是想不同机器之间迁移部署,只需要在"),h,(0,n.Uk)("将相关文件夹(通常为 "),m,(0,n.Uk)(" 与 "),u,(0,n.Uk)(" 与 "),g,(0,n.Uk)(" )复制即可。")])])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,n]of t)o[e]=n;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-3096c190.3bc59592.js b/assets/js/v-3096c190.3bc59592.js
new file mode 100644
index 00000000..dd97eada
--- /dev/null
+++ b/assets/js/v-3096c190.3bc59592.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[6399],{2602:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-3096c190","path":"/plugins/vjudge.html","title":"VJudge","lang":"en-US","frontmatter":{"description":"此文档已过时,仅作留存使用,以下教程仅为示例,如想了解详细安装方法请前往 FAQS(常用教程) 查看具体使用指南。 部分支持的远程站点对提交数量/访问次数/访问来源有一定限制,Hydro 不保证 VJudge 的 100% 可用性。 Codeforces 安装插件后创建名为 codeforces 的域,进入数据库 db.domain.updateOne...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/vjudge.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"VJudge"}],["meta",{"property":"og:description","content":"此文档已过时,仅作留存使用,以下教程仅为示例,如想了解详细安装方法请前往 FAQS(常用教程) 查看具体使用指南。 部分支持的远程站点对提交数量/访问次数/访问来源有一定限制,Hydro 不保证 VJudge 的 100% 可用性。 Codeforces 安装插件后创建名为 codeforces 的域,进入数据库 db.domain.updateOne..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-22T01:00:23.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-22T01:00:23.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"VJudge\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-22T01:00:23.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"Codeforces","slug":"codeforces","link":"#codeforces","children":[]}],"git":{"createdTime":1624333296000,"updatedTime":1713747623000,"contributors":[{"name":"panda","email":"panda_dtdyy@outlook.com","commits":5},{"name":"undefined","email":"i@undefined.moe","commits":3},{"name":"Macesuted","email":"macesuted@qq.com","commits":1}]},"readingTime":{"minutes":1.76,"words":527},"filePathRelative":"plugins/vjudge.md","localizedDate":"June 22, 2021","autoDesc":true,"excerpt":""}')},3389:(s,n,a)=>{a.r(n),a.d(n,{default:()=>e});var l=a(6252);const p=[(0,l.uE)('Warning
此文档已过时,仅作留存使用,以下教程仅为示例,如想了解详细安装方法请前往 FAQS(常用教程) 查看具体使用指南。
部分支持的远程站点对提交数量/访问次数/访问来源有一定限制,Hydro 不保证 VJudge 的 100% 可用性。
安装插件后创建名为 codeforces 的域,进入数据库 db.domain.updateOne({_id:'codeforces'},{$set:{mount:'codeforces'}});
在 codeforces 的域设置中,将 allowedLangs
如下配置(在新版即在允许提交的语言中选中所有 codeforces
开头的语言):
codeforces,codeforces.43,codeforces.52,codeforces.50,codeforces.54,codeforces.59,codeforces.61,codeforces.65,codeforces.9,codeforces.28,codeforces.32,codeforces.12,codeforces.60,codeforces.36,codeforces.48,codeforces.19,codeforces.3,codeforces.4,codeforces.51,codeforces.13,codeforces.6,codeforces.7,codeforces.31,codeforces.40,codeforces.41,codeforces.67,codeforces.49,codeforces.20,codeforces.34,codeforces.55 \n
在 vjudge 表中插入如下条目:
{ type : ' codeforces ' , handle : ' <codeforces login handle> ' , password : ' <codeforces login password> ' } \n
将如下配置添加至 langs 设置末尾:
codeforces : \n execute : none \n display : Codeforces \n domain : \n - codeforces # Allow domain 'codeforces' to use these languages \ncodeforces.43 : \n highlight : cpp astyle-c \n monaco : cpp \n display : GNU GCC C11 5.1.0 \n comment : // \ncodeforces.52 : \n highlight : cpp astyle-c \n monaco : cpp \n display : Clang++17 Diagnostics \n comment : // \ncodeforces.50 : \n highlight : cpp astyle-c \n monaco : cpp \n display : GNU G++14 6.4.0 \n comment : // \ncodeforces.54 : \n highlight : cpp astyle-c \n monaco : cpp \n display : GNU G++17 7.3.0 \n comment : // \ncodeforces.59 : \n highlight : cpp astyle-c \n monaco : cpp \n display : Microsoft Visual C++ 2017 \n comment : // \ncodeforces.61 : \n highlight : cpp astyle-c \n monaco : cpp \n display : GNU G++17 9.2.0 (64 bit, msys 2) \n comment : // \ncodeforces.65 : \n highlight : cpp astyle-cs \n monaco : csharp \n display : C# 8, .NET Core 3.1 \n comment : // \ncodeforces.9 : \n highlight : cpp astyle-cs \n monaco : csharp \n display : C# Mono 6.8 \n comment : // \ncodeforces.28 : \n highlight : d \n monaco : plain \n display : D DMD32 v2.091.0 \n comment : // \ncodeforces.32 : \n highlight : go \n display : Go 1.15.6 \n comment : // \ncodeforces.12 : \n highlight : haskell \n display : Haskell GHC 8.10.1 \n comment : -- \ncodeforces.60 : \n highlight : java astyle-java \n monaco : java \n display : Java 11.0.6 \n comment : // \ncodeforces.36 : \n highlight : java astyle-java \n monaco : java \n display : Java 1.8.0_241 \n comment : // \ncodeforces.48 : \n highlight : kotlin \n display : Kotlin 1.4.0 \n comment : // \ncodeforces.19 : \n highlight : ocaml \n monaco : plain \n display : OCaml 4.02.1 \n comment : [ ' (* ' , ' *) ' ] \ncodeforces.3 : \n highlight : pascal \n display : Delphi 7 \n comment : // \ncodeforces.4 : \n highlight : pascal \n display : Free Pascal 3.0.2 \n comment : // \ncodeforces.51 : \n highlight : pascal \n display : PascalABC.NET 3.4.2 \n comment : // \ncodeforces.13 : \n highlight : perl \n display : Perl 5.20.1 \n comment : ' # ' \ncodeforces.6 : \n highlight : php \n display : PHP 7.2.13 \n comment : // \ncodeforces.7 : \n highlight : python \n display : Python 2.7.18 \n comment : ' # ' \ncodeforces.31 : \n highlight : python \n display : Python 3.9.1 \n comment : ' # ' \ncodeforces.40 : \n highlight : python \n display : PyPy 2.7 (7.3.0) \n comment : ' # ' \ncodeforces.41 : \n highlight : python \n display : PyPy 3.7 (7.3.0) \n comment : ' # ' \ncodeforces.67 : \n highlight : ruby \n display : Ruby 3.0.0 \n comment : ' # ' \ncodeforces.49 : \n highlight : rust \n display : Rust 1.49.0 \n comment : // \ncodeforces.20 : \n highlight : scala \n display : Scala 2.12.8 \n comment : // \ncodeforces.34 : \n highlight : javascript \n display : JavaScript V8 4.8.0 \n comment : // \ncodeforces.55 : \n highlight : javascript \n display : Node.js 12.6.3 \n comment : // \n
之后再重启 Hydro 即可。
',11)],o={},e=(0,a(3744).Z)(o,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,p)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-3706649a.ed629ea9.js b/assets/js/v-3706649a.ed629ea9.js
new file mode 100644
index 00000000..7d79dde9
--- /dev/null
+++ b/assets/js/v-3706649a.ed629ea9.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[88],{8624:(t,e,o)=>{o.r(e),o.d(e,{data:()=>r});const r=JSON.parse('{"key":"v-3706649a","path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound","description":"","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/404.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"en-US"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":0},"filePathRelative":null,"autoDesc":true,"excerpt":""}')},9927:(t,e,o)=>{o.r(e),o.d(e,{default:()=>a});var r=o(6252);const n={},a=(0,o(3744).Z)(n,[["render",function(t,e){return(0,r.wg)(),(0,r.iD)("div")}]])},3744:(t,e)=>{e.Z=(t,e)=>{const o=t.__vccOpts||t;for(const[t,r]of e)o[t]=r;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-4def954c.07c04fc7.js b/assets/js/v-4def954c.07c04fc7.js
new file mode 100644
index 00000000..4dfc5143
--- /dev/null
+++ b/assets/js/v-4def954c.07c04fc7.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[1672],{6240:(e,s,n)=>{n.r(s),n.d(s,{data:()=>a});const a=JSON.parse('{"key":"v-4def954c","path":"/docs/install/proxy.html","title":"反向代理 / SSL 配置","lang":"en-US","frontmatter":{"description":"2022/10/27 后使用脚本安装的实例已自动配置 Caddy 反向代理,请直接编辑位于 ~/.hydro/Caddyfile 的配置文件! 若使用反向代理,请注意系统设置中的 server.xff 和 server.xhost 设置项需要填写正确(小写),分别对应反向代理所添加的标头名(通常为 x-forwarded-for 和 x-forward...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/install/proxy.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"反向代理 / SSL 配置"}],["meta",{"property":"og:description","content":"2022/10/27 后使用脚本安装的实例已自动配置 Caddy 反向代理,请直接编辑位于 ~/.hydro/Caddyfile 的配置文件! 若使用反向代理,请注意系统设置中的 server.xff 和 server.xhost 设置项需要填写正确(小写),分别对应反向代理所添加的标头名(通常为 x-forwarded-for 和 x-forward..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-08-23T08:55:42.000Z"}],["meta",{"property":"article:modified_time","content":"2023-08-23T08:55:42.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"反向代理 / SSL 配置\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-08-23T08:55:42.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":3,"title":"2022/10/27 后使用脚本安装的实例已自动配置 Caddy 反向代理,请直接编辑位于 ~/.hydro/Caddyfile 的配置文件!","slug":"_2022-10-27-后使用脚本安装的实例已自动配置-caddy-反向代理-请直接编辑位于-hydro-caddyfile-的配置文件","link":"#_2022-10-27-后使用脚本安装的实例已自动配置-caddy-反向代理-请直接编辑位于-hydro-caddyfile-的配置文件","children":[]}],"git":{"createdTime":1629032113000,"updatedTime":1692780942000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":6},{"name":"Macesuted","email":"macesuted@qq.com","commits":2},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":1.2,"words":359},"filePathRelative":"docs/install/proxy.md","localizedDate":"August 15, 2021","autoDesc":true,"excerpt":""}')},5850:(e,s,n)=>{n.r(s),n.d(s,{default:()=>t});var a=n(6252);const d=(0,a.uE)('Warning
若使用反向代理,请注意系统设置中的 server.xff 和 server.xhost 设置项需要填写正确(小写),分别对应反向代理所添加的标头名(通常为 x-forwarded-for 和 x-forwarded-host,部分反代工具会使用 x-real-ip 替代 x-forwarded-for)。 server.xhost 设置项配置错误会导致用户无法登录等问题。(CsrfTokenError) server.xff 设置项配置错误会导致无法记录用户IP。
除一键安装脚本在安装 Caddy 后会自动配置设置项,其他工具请在使用工具前先配置好系统设置!否则将造成用户无法登录、无法记录用户IP等问题。
若您使用 Nginx,请注意配置 WebSocket 协议的反向代理,否则会导致评测状态无法自动刷新,在线 IDE 无法正常使用等问题。
',3),l={href:"https://github.com/hydro-dev/Hydro/tree/master/examples/reverse_proxy",target:"_blank",rel:"noopener noreferrer"},r={href:"https://caddyserver.com/",target:"_blank",rel:"noopener noreferrer"},i=(0,a.uE)('hydro.ac { \n log { \n output file /data/access.log { \n roll_size 1gb \n roll_keep_for 72h \n } \n format json \n } \n root * /root/.hydro/static \n @static { \n file { \n try_files {path} \n } \n } \n handle @static { \n file_server \n } \n handle { \n reverse_proxy http://127.0.0.1:8888 \n } \n} \n
',1),o={},t=(0,n(3744).Z)(o,[["render",function(e,s){const n=(0,a.up)("ExternalLinkIcon");return(0,a.wg)(),(0,a.iD)("div",null,[d,(0,a._)("p",null,[(0,a.Uk)("Hydro 支持使用 Caddy, HaProxy 等工具进行反向代理,"),(0,a._)("a",l,[(0,a.Uk)("此处"),(0,a.Wm)(n)]),(0,a.Uk)(" 提供了一些配置样例。")]),(0,a._)("p",null,[(0,a.Uk)("Hydro 推荐您使用 "),(0,a._)("a",r,[(0,a.Uk)("Caddy"),(0,a.Wm)(n)]),(0,a.Uk)("。以下为样例 Caddyfile。 提示:如果您的服务器位于国内,则需要进行备案后才能使用 80 和 443 端口。")]),i])}]])},3744:(e,s)=>{s.Z=(e,s)=>{const n=e.__vccOpts||e;for(const[e,a]of s)n[e]=a;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-4e9d6767.d988335f.js b/assets/js/v-4e9d6767.d988335f.js
new file mode 100644
index 00000000..ea01eb79
--- /dev/null
+++ b/assets/js/v-4e9d6767.d988335f.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[7193],{8781:(e,t,l)=>{l.r(t),l.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-4e9d6767","path":"/docs/system/onsite-contest.html","title":"现场赛指南","lang":"en-US","frontmatter":{"description":"本指南适用于希望进行线下赛,在内网部署评测设施的用户。 以下日期排期仅供参考,具体可根据实际情况自行安排。 本文部分内容同样适用于 DOMJudge。 Day -1 准备工作 请检查下述列表是否均按需求配置完成: 关于选手机设置: 选手机预装了 Linux 系统,并有对应的开发环境。; 推荐使用 CAICPC 作为安装镜像,直接选择第二项启动选项即可一...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/onsite-contest.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"现场赛指南"}],["meta",{"property":"og:description","content":"本指南适用于希望进行线下赛,在内网部署评测设施的用户。 以下日期排期仅供参考,具体可根据实际情况自行安排。 本文部分内容同样适用于 DOMJudge。 Day -1 准备工作 请检查下述列表是否均按需求配置完成: 关于选手机设置: 选手机预装了 Linux 系统,并有对应的开发环境。; 推荐使用 CAICPC 作为安装镜像,直接选择第二项启动选项即可一..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-07-13T14:37:53.000Z"}],["meta",{"property":"article:modified_time","content":"2024-07-13T14:37:53.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"现场赛指南\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-07-13T14:37:53.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"Day -1 准备工作","slug":"day-1-准备工作","link":"#day-1-准备工作","children":[]},{"level":2,"title":"Day 0 准备工作","slug":"day-0-准备工作","link":"#day-0-准备工作","children":[]},{"level":2,"title":"Day 1 热身赛","slug":"day-1-热身赛","link":"#day-1-热身赛","children":[]},{"level":2,"title":"Day 2 正式赛","slug":"day-2-正式赛","link":"#day-2-正式赛","children":[]}],"git":{"createdTime":1720881473000,"updatedTime":1720881473000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":3.02,"words":906},"filePathRelative":"docs/system/onsite-contest.md","localizedDate":"July 13, 2024","autoDesc":true,"excerpt":""}')},2535:(e,t,l)=>{l.r(t),l.d(t,{default:()=>p});var i=l(6252);const a=(0,i.uE)('本指南适用于希望进行线下赛,在内网部署评测设施的用户。 以下日期排期仅供参考,具体可根据实际情况自行安排。
本文部分内容同样适用于 DOMJudge。
请检查下述列表是否均按需求配置完成:
关于选手机设置:
选手机预装了 Linux 系统,并有对应的开发环境。 推荐使用 CAICPC 作为安装镜像,直接选择第二项启动选项即可一键安装。 选手机均连接到内网,且选手机之间无法互相访问,但可以访问公网服务器(若使用的路由器不支持该功能可以在选手机使用 iptables 拦截其他流量)。 可使用 DHCP 配置选手机网络,但需保证地址租期足够长(推荐七天)。 关于服务器设置:
',8),o=(0,i._)("li",null,"服务器使用固定 IP,并可以访问内网中任何设备(含选手机);",-1),n={href:"https://blog.taoky.moe/2023-12-02/icpc-2023-hefei-judgehosts-scale.html",target:"_blank",rel:"noopener noreferrer"},d=(0,i.uE)('关于 CAICPC 镜像:
本镜像基于标准 ICPC 镜像修改而来。 添加了状态上报,用于统一监测服务器状态; 支持调用 VLC 截取屏幕和摄像头流供 live 模块使用; 支持批量下发管理命令(一键锁屏/解锁/重启/显示座位号等等); 使用安装脚本安装 Hydro。 导入所需的比赛用户。 安装 @hydrooj/onsite-toolkit
插件。 参照 https://github.com/hydro-dev/xcpc-tools
说明安装独立模块。 由志愿者打开所有选手机桌面上的 seat.txt 文件,填入座位号,保存,后台所见座位号应当同步刷新; 如果需要根据座位号自动登录,此时导出 IP/队伍 表,在 onsite-toolkit 设置中填入。 准备完成后,批量修改选手机为强密码!!! // TODO: tools 配置
关于打印:
打印功能在 xcpc-tools
中配置。 在 server 端新建一个打印机 token,在赛场旁摆放一台电脑,安装对应的打印机驱动,以 client 模式运行 xcpc-tools
,填入 token,即可连接。 xcpc-tools
会自动抓取打印任务自动打印,默认每个文件最多打印五页,队伍名称和座位号会在纸张顶部。关于气球:
气球通常由小票机进行打印。每当有队伍通过题目时,会打印一张小票; 小票内含队伍名,座位号,气球颜色,该队伍当前的所有气球颜色等信息,志愿者拿到小票后根据其上内容分发气球。 关于自动登录:
启用后,在地址列表的用户均会自动登录上指定的对应账户,用户不可重新登录,不可登出,不可在其他 IP 登录。 操作前请确认列表中不含管理员账号和管理员所使用的机器 IP !
可选:
安装 grafana 和 netdata 用于监测服务器运行状态 以及给领导展示 ; 热身赛通常使用至少一道可以反复提交爆破的题目,引导选手大量提交,测试服务器负载情况。
如果需要发气球请提早给气球打气(通常比赛的前一小时气球组会非常忙) 记得给打印机补纸,小票机同理。 // TODO: 滚榜设置
',18),r={},p=(0,l(3744).Z)(r,[["render",function(e,t){const l=(0,i.up)("ExternalLinkIcon");return(0,i.wg)(),(0,i.iD)("div",null,[a,(0,i._)("ul",null,[o,(0,i._)("li",null,[(0,i.Uk)("服务器安装了较新内核的 Linux 系统。已知旧版本的内核在高负载的情况下可能出现锁死的问题 "),(0,i._)("a",n,[(0,i.Uk)("详情"),(0,i.Wm)(l)]),(0,i.Uk)(";")])]),d])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const l=e.__vccOpts||e;for(const[e,i]of t)l[e]=i;return l}}}]);
\ No newline at end of file
diff --git a/assets/js/v-51b3f914.2d7711f4.js b/assets/js/v-51b3f914.2d7711f4.js
new file mode 100644
index 00000000..23c3cea4
--- /dev/null
+++ b/assets/js/v-51b3f914.2d7711f4.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[299],{3635:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-51b3f914","path":"/docs/user/testdata.html","title":"测试数据格式","lang":"en-US","frontmatter":{"description":"自动模式 您可以直接选择文件(支持多选)上传或将文件拖拽至相应位置上传。 若上传文件为 zip 格式,将会自动进行解压操作。 对于一般的题目,您只需提供 .in 和 .out/.ans 文件,以下是一个例子。 请务必确保文件名中含有数字。形如 sample.in 的文件是不会被自动识别的。 测试数据将被自动识别,并使用 1S 256MB 的限制。 使用...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/testdata.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"测试数据格式"}],["meta",{"property":"og:description","content":"自动模式 您可以直接选择文件(支持多选)上传或将文件拖拽至相应位置上传。 若上传文件为 zip 格式,将会自动进行解压操作。 对于一般的题目,您只需提供 .in 和 .out/.ans 文件,以下是一个例子。 请务必确保文件名中含有数字。形如 sample.in 的文件是不会被自动识别的。 测试数据将被自动识别,并使用 1S 256MB 的限制。 使用..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-05-12T03:18:30.000Z"}],["meta",{"property":"article:modified_time","content":"2023-05-12T03:18:30.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"测试数据格式\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-05-12T03:18:30.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"自动模式","slug":"自动模式","link":"#自动模式","children":[]},{"level":2,"title":"使用配置文件","slug":"使用配置文件","link":"#使用配置文件","children":[]}],"git":{"createdTime":1631785934000,"updatedTime":1683861510000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":2},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"laomai","email":"lmxin@tom.com","commits":1}]},"readingTime":{"minutes":3.3,"words":989},"filePathRelative":"docs/user/testdata.md","localizedDate":"September 16, 2021","autoDesc":true,"excerpt":""}')},4700:(s,n,a)=>{a.r(n),a.d(n,{default:()=>i});var l=a(6252);const e=(0,l.uE)('Tips
您可以直接选择文件(支持多选)上传或将文件拖拽至相应位置上传。 若上传文件为 zip 格式,将会自动进行解压操作。
对于一般的题目,您只需提供 .in
和 .out/.ans
文件,以下是一个例子。 请务必确保文件名中含有数字。形如 sample.in
的文件是不会被自动识别的。
喵? tree \n. \n├── a1.in \n├── a1.out \n├── a2.in \n├── a2.out \n├── a3.in \n└── a3.out \n
测试数据将被自动识别,并使用 1S 256MB 的限制。
Tips
推荐您通过 评测设置 在线编辑题目配置,可以拥有更好的编辑体验。
上传 config.yaml
文件即可,文件格式如下(下方所有样例均为可选项,若无说明则预填写的内容即为默认值):
# 题目类型,可以为 default(比对输出,可以含spj), objective(客观题), interactive(交互题) \ntype : default \n \n# 全局时空限制(此处的限制优先级低于测试点的限制) \ntime : 1s \nmemory : 128m \n \n# 输入输出文件名(例:使用 foo.in 和 foo.out),若使用标准 IO 删除此配置项即可 \nfilename : foo \n \n# 此部分设置当题目类型为 default 时生效 \n# 比较器类型,支持的值有 default(直接比对,忽略行末空格和文件末换行), ccr, cena, hustoj, lemon, qduoj, syzoj, testlib(比较常用) \nchecker_type : default \n# 比较器文件(当比较器类型不为 default 时填写) \n# 文件路径(位于压缩包中的路径) \n# 将通过扩展名识别语言,与编译命令处一致。在默认配置下,C++ 扩展名应为 .cc 而非 .cpp \nchecker : chk.cc \n \n# 此部分设置当题目类型为interactive时生效 \n# 交互器路径(位于压缩包中的路径) \ninteractor : interactor.cc \n \n# Extra files 额外文件 \n# These files will be copied to the working directory 这些文件将被复制到工作目录。 \n# 提示:您无需手动上传 testlib.h。 \nuser_extra_files : \n - extra_input.txt \njudge_extra_files : \n - extra_file.txt \n \n# Test Cases 测试数据列表 \n# If neither CASES or SUBTASKS are set(or config.yaml doesn't exist), judge will try to locate them automaticly. \n# 如果 CASES 和 SUBTASKS 都没有设置或 config.yaml 不存在, 系统会自动尝试识别数据点。 \n# We support these names for auto mode: 自动识别支持以下命名方式: \n# 1. [name(optional)][number].(in/out/ans) RegExp: /^([a-zA-Z]*)([0-9]+).in$/ \n# examples: \n# - c1.in / c1.out \n# - 1.in / 1.out \n# - c1.in / c1.ans \n# 2. input[number].txt / output[number].txt RegExp: /^(input)([0-9]+).txt$/ \n# - example: input1.txt / input2.txt \n# \n# The CASES option has higher priority than the SUBTASKS option! \n# 在有 CASES 设置项时,不会读取 SUBTASKS 设置项! \n# \n# The CASES option has been deprecated in the new version, please use the more personalized SUBTASKS! \n# CASES 已于新版本中被废弃,请使用个性化程度更高的SUBTASKS! \n# score: 50 # 单个测试点分数 \n# time: 1s # 时间限制 \n# memory: 256m # 内存限制 \n# cases: \n# - input: abc.in \n# output: def.out \n# - input: ghi.in \n# output: jkl.out \n# 或使用Subtask项: \nsubtasks : \n - score : 30 \n type : min # 可选 min/max/sum,分别表示取所有测试点最小值、所有测试点最大值、所有测试点之和 \n time : 1s \n memory : 64m \n cases : \n - time : 0.5s \n memory : 32m # 可对单个测试点单独设置时间限制和内存限制 \n input : a.in \n output : a.out \n - input : b.in \n output : b.out \n - score : 70 \n time : 0.5s \n memory : 32m \n if : [ 0 ] # 可选,传入数组,表示仅在subtask0通过时此subtask才计分 \n cases : \n - input : c.in \n output : c.out \n - input : d.in \n output : d.out \n \n# 提交语言限制 \n# 列举出所有本题允许使用的语言对应的代码(需要和评测机 lang.yaml 内的语言代码相同) \n# 使用语言ID而非名称!对于有子类的选项,请详细至子分类! \nlangs : \n - c \n - cc \n - cc.cc11o2 \n - pas \n \n# 时间内存倍率 \n# 对某语言设置时间或内存倍率(需要和评测机 lang.yaml 内的语言代码相同) \n# 部分语言默认已存在倍率,请前往控制面板中查看! \n# 使用语言ID而非名称!对于有子类的选项,请详细至子分类! \ntime_limit_rate : \n py.py3 : 2 \nmemory_limit_rate : \n java : 1.5 \n
',10),p={href:"https://hydro.ac/d/system_test/",target:"_blank",rel:"noopener noreferrer"},o={},i=(0,a(3744).Z)(o,[["render",function(s,n){const a=(0,l.up)("ExternalLinkIcon");return(0,l.wg)(),(0,l.iD)("div",null,[e,(0,l._)("p",null,[(0,l.Uk)("可以在 "),(0,l._)("a",p,[(0,l.Uk)("此题库"),(0,l.Wm)(a)]),(0,l.Uk)(" 中找到各种类型题目的配置示例。")])])}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-52692a96.a101ca00.js b/assets/js/v-52692a96.a101ca00.js
new file mode 100644
index 00000000..f749bc43
--- /dev/null
+++ b/assets/js/v-52692a96.a101ca00.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[4374],{9690:(s,n,e)=>{e.r(n),e.d(n,{data:()=>a});const a=JSON.parse('{"key":"v-52692a96","path":"/plugins/sonic.html","title":"Sonic","lang":"en-US","frontmatter":{"description":"安装 安装 sonic-server (https://github.com/valeriansaliou/sonic) 使用 root 用户执行如下命令: 安装 sonic 插件 使用 root 用户执行如下命令: 启动 在 /root/.sonic/config.cfg(没有的自行建立,也可以换成其他的你喜欢的路径)按照以下配置示例写入配置。 配置...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/sonic.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"Sonic"}],["meta",{"property":"og:description","content":"安装 安装 sonic-server (https://github.com/valeriansaliou/sonic) 使用 root 用户执行如下命令: 安装 sonic 插件 使用 root 用户执行如下命令: 启动 在 /root/.sonic/config.cfg(没有的自行建立,也可以换成其他的你喜欢的路径)按照以下配置示例写入配置。 配置..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-02-25T05:29:05.000Z"}],["meta",{"property":"article:modified_time","content":"2023-02-25T05:29:05.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Sonic\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-02-25T05:29:05.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"安装","slug":"安装","link":"#安装","children":[{"level":3,"title":"安装 sonic-server","slug":"安装-sonic-server","link":"#安装-sonic-server","children":[]},{"level":3,"title":"安装 sonic 插件","slug":"安装-sonic-插件","link":"#安装-sonic-插件","children":[]}]},{"level":2,"title":"启动","slug":"启动","link":"#启动","children":[]},{"level":2,"title":"配置","slug":"配置","link":"#配置","children":[{"level":3,"title":"后端地址配置","slug":"后端地址配置","link":"#后端地址配置","children":[]},{"level":3,"title":"重启 HydroOJ","slug":"重启-hydrooj","link":"#重启-hydrooj","children":[]},{"level":3,"title":"重建题目索引","slug":"重建题目索引","link":"#重建题目索引","children":[]}]},{"level":2,"title":"FAQ","slug":"faq","link":"#faq","children":[{"level":3,"title":"安装后题目搜索不正常","slug":"安装后题目搜索不正常","link":"#安装后题目搜索不正常","children":[]}]}],"git":{"createdTime":1621263423000,"updatedTime":1677302945000,"contributors":[{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"立言","email":"liyanqwq@duianit.cn","commits":2}]},"readingTime":{"minutes":1.11,"words":333},"filePathRelative":"plugins/sonic.md","localizedDate":"May 17, 2021","autoDesc":true,"excerpt":""}')},7621:(s,n,e)=>{e.r(n),e.d(n,{default:()=>t});var a=e(6252);const l=(0,a._)("h1",{id:"sonic",tabindex:"-1"},[(0,a._)("a",{class:"header-anchor",href:"#sonic"},[(0,a._)("span",null,"Sonic")])],-1),i=(0,a._)("h2",{id:"安装",tabindex:"-1"},[(0,a._)("a",{class:"header-anchor",href:"#安装"},[(0,a._)("span",null,"安装")])],-1),d={id:"安装-sonic-server",tabindex:"-1"},p={class:"header-anchor",href:"#安装-sonic-server"},o={href:"https://github.com/valeriansaliou/sonic",target:"_blank",rel:"noopener noreferrer"},c=(0,a.uE)('使用 root 用户执行如下命令:
nix-env -iA nixpkgs.sonic-server \n
使用 root 用户执行如下命令:
yarn global add @hydrooj/sonic \nhydrooj addon add @hydrooj/sonic \n
在 /root/.sonic/config.cfg
(没有的自行建立,也可以换成其他的你喜欢的路径)按照以下配置示例写入配置。
配置示例:
# Sonic \n# Fast, lightweight and schema-less search backend \n# Configuration file \n# Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg \n \n \n[server] \n \nlog_level = "error" \n \n \n[channel] \n \ninet = "127.0.0.1:1491" # 默认监听本机 \ntcp_timeout = 300 \n \nauth_password = "SecretPassword" \n \n[channel.search] \n \nquery_limit_default = 10 \nquery_limit_maximum = 100 \nquery_alternates_try = 4 \n \nsuggest_limit_default = 5 \nsuggest_limit_maximum = 20 \n \n \n[store] \n \n[store.kv] \n \npath = "/data/sonic/store/kv/" \n \nretain_word_objects = 1000 \n \n[store.kv.pool] \n \ninactive_after = 1800 \n \n[store.kv.database] \n \nflush_after = 900 \n \ncompress = true \nparallelism = 2 \nmax_files = 100 \nmax_compactions = 1 \nmax_flushes = 1 \nwrite_buffer = 16384 \nwrite_ahead_log = true \n \n[store.fst] \n \npath = "/data/sonic/store/fst/" \n \n[store.fst.pool] \n \ninactive_after = 300 \n \n[store.fst.graph] \n \nconsolidate_after = 180 \n \nmax_size = 2048 \nmax_words = 250000 \n
执行如下命令:
pm2 start sonic -- -c /root/.sonic/config.cfg \npm2 save \n
进入 HydroOJ 控制面板,配置 sonic 后端地址。
如果您直接复制配置示例,那么按照以下内容配置:
host: 127.0.0.1
port: 1491
auth: SecretPassword
修改完成后,重启 HydroOJ。
执行命令 pm2 restart hydrooj
。
进入 HydroOJ 控制面板,在脚本管理中找到重建题目索引,点击运行,参数留空即可。
至此,搜索功能应当可以正常使用。
请更新到 HydroOJ 最新版本后,再运行重建题目索引。
',25),r={},t=(0,e(3744).Z)(r,[["render",function(s,n){const e=(0,a.up)("ExternalLinkIcon");return(0,a.wg)(),(0,a.iD)("div",null,[l,i,(0,a._)("h3",d,[(0,a._)("a",p,[(0,a._)("span",null,[(0,a.Uk)("安装 "),(0,a._)("a",o,[(0,a.Uk)("sonic-server"),(0,a.Wm)(e)])])])]),c])}]])},3744:(s,n)=>{n.Z=(s,n)=>{const e=s.__vccOpts||s;for(const[s,a]of n)e[s]=a;return e}}}]);
\ No newline at end of file
diff --git a/assets/js/v-55131a51.ec71e52c.js b/assets/js/v-55131a51.ec71e52c.js
new file mode 100644
index 00000000..9b4b03ad
--- /dev/null
+++ b/assets/js/v-55131a51.ec71e52c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[9236],{7185:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-55131a51","path":"/dev/third-party-auth.html","title":"接入第三方账号系统","lang":"en-US","frontmatter":{"description":"Hydro 支持接入第三方的账号系统,并且有以下内置模块可用: @hydrooj/login-with-github; @hydrooj/login-with-google; 对接其他平台 在阅读本节之前,请确保你已阅读 【插件开发】 章节。 以 Github 登录为例:","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/third-party-auth.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"接入第三方账号系统"}],["meta",{"property":"og:description","content":"Hydro 支持接入第三方的账号系统,并且有以下内置模块可用: @hydrooj/login-with-github; @hydrooj/login-with-google; 对接其他平台 在阅读本节之前,请确保你已阅读 【插件开发】 章节。 以 Github 登录为例:"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-12-26T15:12:47.000Z"}],["meta",{"property":"article:modified_time","content":"2023-12-26T15:12:47.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"接入第三方账号系统\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-12-26T15:12:47.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"对接其他平台","slug":"对接其他平台","link":"#对接其他平台","children":[]}],"git":{"createdTime":1703603464000,"updatedTime":1703603567000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2}]},"readingTime":{"minutes":1.76,"words":528},"filePathRelative":"dev/third-party-auth.md","localizedDate":"December 26, 2023","autoDesc":true,"excerpt":""}')},4945:(s,n,a)=>{a.r(n),a.d(n,{default:()=>e});var l=a(6252);const p=[(0,l.uE)('Hydro 支持接入第三方的账号系统,并且有以下内置模块可用:
@hydrooj/login-with-github @hydrooj/login-with-google 在阅读本节之前,请确保你已阅读 【插件开发】 章节。
以 Github 登录为例:
import { \n Context , ForbiddenError , Handler , superagent , SystemModel , \n TokenModel , UserFacingError , ValidationError , \n} from ' hydrooj ' ; \n \ndeclare module ' hydrooj ' { \n interface SystemKeys { \n ' login-with-github.id ' : string ; \n ' login-with-github.secret ' : string ; \n ' login-with-github.endpoint ' : string ; \n } \n} \n \n// 当用户点击 【使用 XX 登录】 按钮时,此函数会被执行 \nasync function get ( this: Handler ) { \n // 从系统设置中获取基础设置,并储存状态信息(完成登录逻辑后应该跳转到哪一页) \n const [ appid , [ state ]] = await Promise . all ([ \n SystemModel . get ( ' login-with-github.id ' ) , \n TokenModel . add ( TokenModel . TYPE_OAUTH , 600 , { redirect : this . request . referer } ) , \n ]) ; \n // 将用户重定向至第三方平台请求授权。 \n this . response . redirect = ` https://github.com/login/oauth/authorize?client_id= ${ appid } &state= ${ state } &scope=read:user,user:email ` ; \n} \n \n// 当用户在三方系统中完成授权,需要重定向到 /oauth/xxx/callback,这时所有返回的参数作为 callback 的一参数传入。 \nasync function callback ({ state , code }) { \n // 获取系统设置和之前的状态。 \n const [[ appid , secret , endpoint , url ], s ] = await Promise . all ([ \n SystemModel . getMany ([ \n ' login-with-github.id ' , \n ' login-with-github.secret ' , \n ' login-with-github.endpoint ' , \n ' server.url ' , \n ]) , \n TokenModel . get ( state , TokenModel . TYPE_OAUTH ) , \n ]) ; \n if ( ! s ) throw new ValidationError ( ' token ' ) ; \n // 使用从 url 中返回的 token 请求第三方的 API,获取用户信息,作为函数返回。 \n // 在 OAuth 协议中,需要使用 state 和 code 换取 access_token 再调用 API,这在不同系统中可能设计不同。 \n // 系统会根据返回的用户信息自动查找已有用户或是创建新用户。 \n const res = await superagent . post ( `${ endpoint || ' https://github.com '} /login/oauth/access_token ` ) \n . send ( { \n client_id : appid , \n client_secret : secret , \n code , \n redirect_uri : `${ url } oauth/github/callback ` , \n state , \n } ) \n . set ( ' accept ' , ' application/json ' ) ; \n if ( res . body . error ) { \n throw new UserFacingError ( \n res . body . error , res . body . error_description , res . body . error_uri , \n ) ; \n } \n const t = res . body . access_token ; \n const userInfo = await superagent . get ( `${ endpoint ? `${ endpoint } /api ` : ' https://api.github.com '} /user ` ) \n . set ( ' User-Agent ' , ' Hydro-OAuth ' ) \n . set ( ' Accept ' , ' application/vnd.github.v3+json ' ) \n . set ( ' Authorization ' , ` token ${ t }` ) ; \n const ret = { \n _id : `${ userInfo . body . id } @github.local ` , \n email : userInfo . body . email , \n bio : userInfo . body . bio , \n // 提供多个用户名,若需创建用户则从前往后尝试,直到用户名可用 \n uname : [ userInfo . body . name , userInfo . body . login ] . filter ( ( i ) => i ) , \n avatar : ` github: ${ userInfo . body . login }` , \n } ; \n await TokenModel . del ( s . _id , TokenModel . TYPE_OAUTH ) ; \n if ( ! ret . email ) throw new ForbiddenError ( " You don't have a verified email. " ) ; \n return ret ; \n} \n \n// 注册此模块。 \nexport function apply ( ctx : Context ) { \n ctx . provideModule ( ' oauth ' , ' github ' , { \n text : ' Login with Github ' , \n callback , \n get , \n } ) ; \n ctx . i18n . load ( ' zh ' , { \n ' Login With Github ' : ' 使用 Github 登录 ' , \n } ) ; \n} \n
',7)],o={},e=(0,a(3744).Z)(o,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,p)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-5c0c76d7.1a454107.js b/assets/js/v-5c0c76d7.1a454107.js
new file mode 100644
index 00000000..f67c7d99
--- /dev/null
+++ b/assets/js/v-5c0c76d7.1a454107.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[732],{483:(e,t,o)=>{o.r(t),o.d(t,{data:()=>n});const n=JSON.parse('{"key":"v-5c0c76d7","path":"/dev/frontend-modify.html","title":"前端修改","lang":"en-US","frontmatter":{"description":"参考 前端修改 (/docs/system/frontend-modify/)。","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/frontend-modify.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"前端修改"}],["meta",{"property":"og:description","content":"参考 前端修改 (/docs/system/frontend-modify/)。"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2021-08-13T04:13:21.000Z"}],["meta",{"property":"article:modified_time","content":"2021-08-13T04:13:21.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"前端修改\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2021-08-13T04:13:21.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1628828001000,"updatedTime":1628828001000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":1}]},"readingTime":{"minutes":0.04,"words":12},"filePathRelative":"dev/frontend-modify.md","localizedDate":"August 13, 2021","autoDesc":true,"excerpt":""}')},4660:(e,t,o)=>{o.r(t),o.d(t,{default:()=>a});var n=o(6252);const r=(0,n._)("h1",{id:"前端修改",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#前端修改"},[(0,n._)("span",null,"前端修改")])],-1),d={},a=(0,o(3744).Z)(d,[["render",function(e,t){const o=(0,n.up)("RouterLink");return(0,n.wg)(),(0,n.iD)("div",null,[r,(0,n._)("p",null,[(0,n.Uk)("参考 "),(0,n.Wm)(o,{to:"/docs/system/frontend-modify/"},{default:(0,n.w5)((()=>[(0,n.Uk)("前端修改")])),_:1}),(0,n.Uk)("。")])])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,n]of t)o[e]=n;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-5ddc85e1.42ddd734.js b/assets/js/v-5ddc85e1.42ddd734.js
new file mode 100644
index 00000000..4657dc6a
--- /dev/null
+++ b/assets/js/v-5ddc85e1.42ddd734.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[4377],{5958:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-5ddc85e1","path":"/dev/typescript.html","title":"使用 TypeScript 编写插件","lang":"en-US","frontmatter":{"description":"前置条件:NodeJS>=18 此教程将以编写剪贴板插件为例进行说明。 Step1 初始化项目 使用 hydrooj addon create 快速在 /root/addon 下初始化一个插件或是在一个空文件夹中运行 yarn init 并按照提示填写相关信息。 可选:在本机环境编写插件 有时我们希望使用本机的 IDE 编写插件上传到服务器(我们也推荐...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/typescript.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"使用 TypeScript 编写插件"}],["meta",{"property":"og:description","content":"前置条件:NodeJS>=18 此教程将以编写剪贴板插件为例进行说明。 Step1 初始化项目 使用 hydrooj addon create 快速在 /root/addon 下初始化一个插件或是在一个空文件夹中运行 yarn init 并按照提示填写相关信息。 可选:在本机环境编写插件 有时我们希望使用本机的 IDE 编写插件上传到服务器(我们也推荐..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-03-02T07:55:17.000Z"}],["meta",{"property":"article:modified_time","content":"2024-03-02T07:55:17.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"使用 TypeScript 编写插件\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-03-02T07:55:17.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"Step1 初始化项目","slug":"step1-初始化项目","link":"#step1-初始化项目","children":[]},{"level":2,"title":"可选:在本机环境编写插件","slug":"可选-在本机环境编写插件","link":"#可选-在本机环境编写插件","children":[]},{"level":2,"title":"Step2 准备编写组件","slug":"step2-准备编写组件","link":"#step2-准备编写组件","children":[]},{"level":2,"title":"Step4 template","slug":"step4-template","link":"#step4-template","children":[]},{"level":2,"title":"Step5 locale","slug":"step5-locale","link":"#step5-locale","children":[]}],"git":{"createdTime":1612251809000,"updatedTime":1709366117000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":5},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":1},{"name":"无限UCW","email":"45730483+wuxianucw@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":4.04,"words":1213},"filePathRelative":"dev/typescript.md","localizedDate":"February 2, 2021","autoDesc":true,"excerpt":""}')},5067:(s,n,a)=>{a.r(n),a.d(n,{default:()=>e});var l=a(6252);const p=[(0,l.uE)('前置条件:NodeJS>=18 此教程将以编写剪贴板插件为例进行说明。
使用 hydrooj addon create
快速在 /root/addon
下初始化一个插件或是在一个空文件夹中运行 yarn init
并按照提示填写相关信息。
# 使用 yarn init 的样例 \n/workspace/hydro-plugin $ yarn init \nyarn init v1.22.4 \nquestion name (hydro-plugin): @hydrooj/pastebin \nquestion version (1.0.0): 0.0.1 \nquestion description: HydroOJ的剪贴板组件 \nquestion entry point (index.js): index.ts \nquestion repository url: https://github.com/hydro-dev/pastebin.git \nquestion author: undefined < i@undefined.mo e > \nquestion license (MIT): MIT \nquestion private: \nsuccess Saved package.json \n
有时我们希望使用本机的 IDE 编写插件上传到服务器(我们也推荐这么做,编辑器提供的代码补全可以很大程度简化开发流程),可以进行如下操作:
在本机安装 NodeJS 和 yarn 。 参照步骤 1 使用 yarn init
创建一个项目。 使用 VSCode 打开插件文件夹。 使用 yarn add hydrooj -D
安装相关开发组件。 参照下文进行插件开发工作 将本地的文件夹上传至服务器,并使用 hydrooj addon add 插件绝对路径
启用上传的插件。 分析:剪贴板组件需要以下功能:
与数据库交互来存储/检索相应文档。 提供 /paste/create 路由以创建新文档。 提供 /paste/show/:ID 来查看已创建的文档。 根据用户ID进行鉴权,允许将文档设置为私密以防止他人查看。 在路由中定义所有的函数应均为异步函数,支持的函数有:prepare, get, post, post[Operation], cleanup 具体流程如下:
先执行 prepare(args) (如果存在) \nargs 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数, \n再执行 prepare(args) (如果存在) \n检查请求类型: \n \n为 GET ? \n -> 执行 get(args) \n为 POST ? \n -> 执行 post(args) \n -> 含有 operation 字段? \n -> 执行 post[Operation] \n \n执行 cleanup() \n
如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。
在表单提交时的 operation 字段使用下划线,函数名使用驼峰命名。 如 <input type="hidden" name="operation" value="confirm_delete">
对应 postConfirmDelete
函数。
应当提供 apply
函数,并与定义的 Handler 一同挂载到 global.Hydro.handler[模块名]
位置。 apply
函数将在初始化阶段被调用。
// @noErrors \n// @module: esnext \n// @filename: index.ts \nimport { \n db , definePlugin , Handler , NotFoundError , param , PermissionError , PRIV , Types , \n} from ' hydrooj ' ; \n \nconst coll = db . collection ( ' paste ' ) ; \n \ninterface Paste { \n _id : string ; \n owner : number ; \n content : string ; \n isPrivate : boolean ; \n} \n \ndeclare module ' hydrooj ' { \n interface Model { \n pastebin : typeof pastebinModel ; \n } \n interface Collections { \n paste : Paste ; // 声明数据表类型 \n } \n} \n \nasync function add ( userId : number , content : string , isPrivate : boolean ) : Promise < string > { \n const pasteId = String . random ( 16 ) ; // Hydro 提供了此方法,创建一个长度为16的随机字符串 \n // 使用 mongodb 为数据库驱动,相关操作参照其文档 \n const result = await coll . insertOne ( { \n _id : pasteId , \n owner : userId , \n content , \n isPrivate , \n } ) ; \n return result . insertedId ; // 返回插入的文档ID \n} \n \nasync function get ( pasteId : string ) : Promise < Paste > { \n return await coll . findOne ( { _id : pasteId } ) ; \n} \n \n// 暴露这些接口,使得 cli 也能够正常调用这些函数; \nconst pastebinModel = { add , get } ; \nglobal . Hydro . model . pastebin = pastebinModel ; \n \n// 创建新路由 \nclass PasteCreateHandler extends Handler { \n // Get请求时触发该函数 \n async get () { \n // 检查用户是否登录,此处为多余(因为底部注册路由时已声明所需权限) \n // 此方法适用于权限的动态检查 \n // this.checkPriv(PRIV.PRIV_USER_PROFILE); \n this . response . template = ' paste_create.html ' ; // 返回此页面 \n } \n \n // 使用 Types.Content 检查输入 \n @param ( ' content ' , Types . Content ) \n @param ( ' private ' , Types . Boolean ) \n // 从用户提交的表单中取出content和private字段 \n // domainId 为固定传入参数 \n async post ( domainId : string , content : string , isPrivate = false ) { \n // 在HTML表单提交的多选框中,选中值为 'on',未选中则为空,需要进行转换 \n const pasteid = await pastebinModel . add ( this . user . _id , content , !! isPrivate ) ; \n // 将用户重定向到创建完成的url \n this . response . redirect = this . url ( ' paste_show ' , { id : pasteid } ) ; \n // 相应的,提供了 this.back() 方法用于将用户重定向至前一个地址(通常用于 Ajax 或是部分更新操作) \n } \n} \n \nclass PasteShowHandler extends Handler { \n @param ( ' id ' , Types . String ) \n async get ( domainId : string , id : string ) { \n const doc = await pastebin . get ( id ) ; \n if ( ! doc ) throw new NotFoundError ( id ) ; \n if ( doc . isPrivate && this . user . _id !== doc . owner ) { \n throw new PermissionError () ; \n } \n this . response . body = { doc } ; \n this . response . template = ' paste_show.html ' ; \n } \n \n @param ( ' id ' , Types . String ) \n async postDelete ( domainId : string , id : string ) { \n // 当提交表单并存在 operation 值为 delete 时执行。 \n // 本例中未实现删除功能,仅作为说明。 \n } \n} \n \n// Hydro会在服务初始化完成后调用该函数。 \nexport async function apply () { \n // 注册一个名为 paste_create 的路由,匹配 '/paste/create', \n // 使用PasteCreateHandler处理,访问改路由需要PRIV.PRIV_USER_PROFILE权限 \n // 提示:路由匹配基于 path-to-regexp \n ctx . Route ( ' paste_create ' , ' /paste/create ' , PasteCreateHandler , PRIV . PRIV_USER_PROFILE ) ; \n ctx . Route ( ' paste_show ' , ' /paste/show/:id ' , PasteShowHandler ) ; \n} \n \n
模板采用 nunjucks 语法。放置于 templates/
文件夹下。 会在请求结束时根据 response.template
的值选择模板,并使用 response.body
的值进行渲染,存入 response.body
中。 若 response.template
为空或 request.headers['accept'] == 'application/json'
,则跳过渲染步骤。
用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。
',23)],o={},e=(0,a(3744).Z)(o,[["render",function(s,n){return(0,l.wg)(),(0,l.iD)("div",null,p)}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-5e09d0a1.ee71b259.js b/assets/js/v-5e09d0a1.ee71b259.js
new file mode 100644
index 00000000..5f09d7d9
--- /dev/null
+++ b/assets/js/v-5e09d0a1.ee71b259.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[598],{4685:(e,t,r)=>{r.r(t),r.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-5e09d0a1","path":"/docs/user/permission.html","title":"权限系统","lang":"en-US","frontmatter":{"description":"Hydro 的权限系统使用双层结构,分别为 Privilege (PRIV) 和 Permission (PERM)。 权限在系统内部使用位运算表示,具体的定义与数值可以查看 源代码 (https://github.com/hydro-dev/Hydro/blob/master/packages/hydrooj/src/model/builtin.ts...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/permission.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"权限系统"}],["meta",{"property":"og:description","content":"Hydro 的权限系统使用双层结构,分别为 Privilege (PRIV) 和 Permission (PERM)。 权限在系统内部使用位运算表示,具体的定义与数值可以查看 源代码 (https://github.com/hydro-dev/Hydro/blob/master/packages/hydrooj/src/model/builtin.ts..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-06-19T11:24:39.000Z"}],["meta",{"property":"article:modified_time","content":"2024-06-19T11:24:39.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"权限系统\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-19T11:24:39.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"Privilege","slug":"privilege","link":"#privilege","children":[]},{"level":2,"title":"Permission","slug":"permission","link":"#permission","children":[]},{"level":2,"title":"角色","slug":"角色","link":"#角色","children":[]},{"level":2,"title":"加入域","slug":"加入域","link":"#加入域","children":[]}],"git":{"createdTime":1704446362000,"updatedTime":1718796279000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"LaoShui","email":"79132480+laoshuikaixue@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":1.76,"words":529},"filePathRelative":"docs/user/permission.md","localizedDate":"January 5, 2024","autoDesc":true,"excerpt":""}')},7638:(e,t,r)=>{r.r(t),r.d(t,{default:()=>d});var i=r(6252);const o=(0,i._)("h1",{id:"权限系统",tabindex:"-1"},[(0,i._)("a",{class:"header-anchor",href:"#权限系统"},[(0,i._)("span",null,"权限系统")])],-1),a=(0,i._)("br",null,null,-1),n={href:"https://github.com/hydro-dev/Hydro/blob/master/packages/hydrooj/src/model/builtin.ts",target:"_blank",rel:"noopener noreferrer"},s=(0,i.uE)('Privilege 是用户在整套系统内拥有的权限,在所有域均生效。如创建用户,编辑系统设置,创建域,查看域等等。
特别地,PRIV.PRIV_USER_PROFILE
控制一个账号是否能够作为普通账号登录。若不具有此权限,该账号将无法登录(被封禁)。
常见需求:若不想让普通用户上传文件 可以关闭default角色的 PRIV_CREATE_FILE
权限
Permission 是用户在单个域内拥有的权限,如创建题目/比赛,发布/删除讨论等等。
如果 PERM.PERM_VIEW
被禁用,则该用户无法查看此域。
通常我们需要给特定的一组用户分配相同的权限。在用户量较多的时候这会非常混乱难以管理,为此我们设计了【角色】,便于批量操作与管理。 角色是针对域内权限(PERM)的。在系统内置了三个角色:
guest (对未登录用户生效,含已封禁用户) default (对所有未指定角色的用户生效,包括未加入域的用户) root (拥有所有权限) 通常情况下,如果需要对域做特殊的权限控制,应当新建一个用户组(例如 member)并将选定用户加入该用户组。 将角色移出域和将用户的角色设置为 default 是等价的。 若有需要,您也可以创建 teacher, admin 等其他角色。 考虑到系统中的用户可能非常多(数万甚至数十万),在用户列表中仅会显示权限不为 default 的用户。
加入域的过程实际上是 用户通过某种方式自助将自己的权限组由 default 变更到另一权限组(如member) 的过程。 因此在入域申请链接的权限组中选择 guest 和 default 是没有意义的。
',13),l={},d=(0,r(3744).Z)(l,[["render",function(e,t){const r=(0,i.up)("ExternalLinkIcon");return(0,i.wg)(),(0,i.iD)("div",null,[o,(0,i._)("p",null,[(0,i.Uk)("Hydro 的权限系统使用双层结构,分别为 Privilege (PRIV) 和 Permission (PERM)。"),a,(0,i.Uk)(" 权限在系统内部使用位运算表示,具体的定义与数值可以查看 "),(0,i._)("a",n,[(0,i.Uk)("源代码"),(0,i.Wm)(r)]),(0,i.Uk)(" 。")]),s])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const r=e.__vccOpts||e;for(const[e,i]of t)r[e]=i;return r}}}]);
\ No newline at end of file
diff --git a/assets/js/v-62edc12e.96d9657a.js b/assets/js/v-62edc12e.96d9657a.js
new file mode 100644
index 00000000..6eaf60c9
--- /dev/null
+++ b/assets/js/v-62edc12e.96d9657a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[1438],{9883:(e,t,o)=>{o.r(t),o.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-62edc12e","path":"/docs/user/copy-problem.html","title":"复制题目","lang":"en-US","frontmatter":{"description":"复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛/作业/训练计划中使用这些题目。 操作流程 1. 进入需要复制的题目页面或是题目列表页面。 2. 点击右侧栏底部的“复制”按钮或是多选题目后点击右侧复制题目按钮。 3. 在弹出的窗口中输入需要复制到的域的 ID。 4. 点击“确定”后将自动跳转到复制后的题目连接。 限制 不允许查看...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/copy-problem.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"复制题目"}],["meta",{"property":"og:description","content":"复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛/作业/训练计划中使用这些题目。 操作流程 1. 进入需要复制的题目页面或是题目列表页面。 2. 点击右侧栏底部的“复制”按钮或是多选题目后点击右侧复制题目按钮。 3. 在弹出的窗口中输入需要复制到的域的 ID。 4. 点击“确定”后将自动跳转到复制后的题目连接。 限制 不允许查看..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2022-02-25T15:35:42.000Z"}],["meta",{"property":"article:modified_time","content":"2022-02-25T15:35:42.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"复制题目\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2022-02-25T15:35:42.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"操作流程","slug":"操作流程","link":"#操作流程","children":[]},{"level":2,"title":"限制","slug":"限制","link":"#限制","children":[]}],"git":{"createdTime":1636103902000,"updatedTime":1645803342000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"Macesuted","email":"i@macesuted.moe","commits":1}]},"readingTime":{"minutes":0.7,"words":210},"filePathRelative":"docs/user/copy-problem.md","localizedDate":"November 5, 2021","autoDesc":true,"excerpt":""}')},2832:(e,t,o)=>{o.r(t),o.d(t,{default:()=>n});var i=o(6252);const r=[(0,i.uE)('复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛/作业/训练计划中使用这些题目。
进入需要复制的题目页面或是题目列表页面。 点击右侧栏底部的“复制”按钮或是多选题目后点击右侧复制题目按钮。 在弹出的窗口中输入需要复制到的域的 ID。 点击“确定”后将自动跳转到复制后的题目连接。 不允许查看/修改复制后的题目的测试数据。 不能复制一个复制来的题目。 部分题目可能不允许复制。这遵循 域设置>编辑域资料 中的管理员设定。 ',6)],a={},n=(0,o(3744).Z)(a,[["render",function(e,t){return(0,i.wg)(),(0,i.iD)("div",null,r)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,i]of t)o[e]=i;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-666426ae.a77f2425.js b/assets/js/v-666426ae.a77f2425.js
new file mode 100644
index 00000000..901fafb1
--- /dev/null
+++ b/assets/js/v-666426ae.a77f2425.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[9932],{7985:(e,t,a)=>{a.r(t),a.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-666426ae","path":"/docs/user/","title":"用户文档","lang":"en-US","frontmatter":{"description":"题目难度 Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。 1. 一般地,难度的数值越大,该题目越难。 2. 新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。 3. 越早递交评测的用户代码的评测结果对题目难度影响越大。 4. 题目的难度由算法计算得出,有可能出现不准确的结果。 参与比...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"用户文档"}],["meta",{"property":"og:description","content":"题目难度 Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。 1. 一般地,难度的数值越大,该题目越难。 2. 新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。 3. 越早递交评测的用户代码的评测结果对题目难度影响越大。 4. 题目的难度由算法计算得出,有可能出现不准确的结果。 参与比..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2021-05-08T17:02:49.000Z"}],["meta",{"property":"article:modified_time","content":"2021-05-08T17:02:49.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"用户文档\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2021-05-08T17:02:49.000Z\\",\\"author\\":[]}"]]},"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":{"createdTime":1620493369000,"updatedTime":1620493369000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":1.53,"words":459},"filePathRelative":"docs/user/README.md","localizedDate":"May 8, 2021","autoDesc":true,"excerpt":""}')},8213:(e,t,a)=>{a.r(t),a.d(t,{default:()=>l});var i=a(6252);const r=[(0,i.uE)('Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。
一般地,难度的数值越大,该题目越难。 新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。 越早递交评测的用户代码的评测结果对题目难度影响越大。 题目的难度由算法计算得出,有可能出现不准确的结果。 您可以在比赛的详细界面内点击“参与比赛”按钮进行参与。 比赛过程中“成绩表”会根据比赛规则显示排名。 在比赛截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。
若您想发布一个讨论,请先进入一个讨论节点 ,之后点击“创建一个讨论”按钮并填写:
标题; 内容; 是否高亮:若选择后,该贴的左边将有醒目的红色线条(需要“高亮讨论”权限); Pin:该讨论是否置顶(需要“置顶讨论”权限)。 之后点击“创建”按钮进行发布。
您可以在作业的详情页面中,点击“认领作业”。 在作业开始之前,您无法查看作业中的题目。 在作业持续时间内,您与他人的做题情况会被实时统计在“成绩表”内。 在作业进入延期阶段后,您仍然可以提交题目,但成绩表内的分数将根据延期扣分规则按百分比折算。 在作业截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。
',12)],n={},l=(0,a(3744).Z)(n,[["render",function(e,t){return(0,i.wg)(),(0,i.iD)("div",null,r)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const a=e.__vccOpts||e;for(const[e,i]of t)a[e]=i;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-669bced4.97a368ad.js b/assets/js/v-669bced4.97a368ad.js
new file mode 100644
index 00000000..e1cc0a26
--- /dev/null
+++ b/assets/js/v-669bced4.97a368ad.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[4833],{1459:(s,o,a)=>{a.r(o),a.d(o,{data:()=>n});const n=JSON.parse('{"key":"v-669bced4","path":"/plugins/migrate.html","title":"migrate","lang":"en-US","frontmatter":{"description":"从 HUSTOJ 升级 迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 HUSTOJ 的数据。 请注意备份相关文件。 请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 HUSTOJ 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 HUSTOJ 数据...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/migrate.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"migrate"}],["meta",{"property":"og:description","content":"从 HUSTOJ 升级 迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 HUSTOJ 的数据。 请注意备份相关文件。 请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 HUSTOJ 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 HUSTOJ 数据..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-05-12T03:18:30.000Z"}],["meta",{"property":"article:modified_time","content":"2023-05-12T03:18:30.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"migrate\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-05-12T03:18:30.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"从 HUSTOJ 升级","slug":"从-hustoj-升级","link":"#从-hustoj-升级","children":[]},{"level":2,"title":"从 SYZOJ 升级","slug":"从-syzoj-升级","link":"#从-syzoj-升级","children":[]},{"level":2,"title":"从 UniversalOJ 升级","slug":"从-universaloj-升级","link":"#从-universaloj-升级","children":[]},{"level":2,"title":"从 Vijos 升级","slug":"从-vijos-升级","link":"#从-vijos-升级","children":[]}],"git":{"createdTime":1665539184000,"updatedTime":1683861510000,"contributors":[{"name":"panda","email":"panda_dtdyy@outlook.com","commits":3},{"name":"cyhforlight","email":"52744639+cyhforlight@users.noreply.github.com","commits":1},{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":3.32,"words":995},"filePathRelative":"plugins/migrate.md","localizedDate":"October 12, 2022","autoDesc":true,"excerpt":""}')},4062:(s,o,a)=>{a.r(o),a.d(o,{default:()=>t});var n=a(6252);const l=[(0,n.uE)('Warning
迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 HUSTOJ 的数据。 请注意备份相关文件。
请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 HUSTOJ 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 HUSTOJ 数据库相同。
安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateHustoj
的脚本。 其参数格式如下:
{ " host " : " localhost " , " port " : 3306 , " name " : " jol " , " username " : "" , " password " : "" , " domainId " : " system " , " contestType " : "" , " dataDir " : "" , " uploadDir " : "" } \n
host: 数据库地址 port: 数据库端口 name: 数据库名,一般为 jol
username&password: 账号密码,若无则填写空字符串 domainId: 迁入的域,默认为 system
contestType: oi
或者 acm
,视情况而定 dataDir: HUSTOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理) uploadDir: HUSTOJ 中 上传文件的位置(这里存储着上传的图片和文件等信息,默认已指定 /home/judge/src/web/upload/
,如果此路径与您路径相同,请不要填写此项) 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 HUSTOJ 的管理员账号登录实例。
SYZOJ 与 HUSTOJ 迁移方法类似,迁移脚本应运行名为 migrateSyzoj
的脚本外,SYZOJ无需 contestType
参数。 其参数格式如下:
{ " host " : " localhost " , " port " : 3306 , " name " : " syzoj " , " username " : "" , " password " : "" , " domainId " : " system " , " dataDir " : "" } \n
host: 数据库地址 port: 数据库端口 name: 数据库名,一般为 syzoj
username&password: 账号密码,若无则填写空字符串 domainId: 迁入的域,默认为 system
dataDir: SYZOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理) 由于SYZOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 SYZOJ 的管理员账号登录实例。
UniversalOJ (常称作UOJ社区版)与前两者迁移方法类似,迁移脚本应运行名为 migrateUniversalOJ
的脚本。
由于其升级过程较为麻烦,安装脚本已提供自动升级服务,如您需要可运行安装脚本一键迁移,手动迁移请在开发群中提问。
由于UniversalOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 UniversalOJ 的管理员账号登录实例。
Warning
迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 vj4 的数据。 请注意备份相关文件。
请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 vj4 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 vj4 数据库相同。 若您使用 vj4-docker ,可更改 docker-compose.yml
将数据库映射至其他本机端口。
安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateVijos
的脚本。 其参数格式如下:
{ " host " : " localhost " , " port " : 27017 , " name " : " vj4 " , " username " : "" , " password " : "" } \n
host: 数据库地址 port: 数据库端口 name: 数据库名 username&password: 账号密码,若无则填写空字符串 Tips
vj4-docker 中数据库名为 vj4,无账号密码。
当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 vj4 的管理员账号登录实例。
Warning
若您的 vj4 是由 vj2 或 tyvj 升级而来,在迁移完成后请不要卸载该插件,否则可能导致部分用户无法登录。
',26)],e={},t=(0,a(3744).Z)(e,[["render",function(s,o){return(0,n.wg)(),(0,n.iD)("div",null,l)}]])},3744:(s,o)=>{o.Z=(s,o)=>{const a=s.__vccOpts||s;for(const[s,n]of o)a[s]=n;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-67d16688.5d7ae5cd.js b/assets/js/v-67d16688.5d7ae5cd.js
new file mode 100644
index 00000000..f9ede7bf
--- /dev/null
+++ b/assets/js/v-67d16688.5d7ae5cd.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[3325],{1517:(s,e,a)=>{a.r(e),a.d(e,{data:()=>t});const t=JSON.parse('{"key":"v-67d16688","path":"/plugins/","title":"插件","lang":"en-US","frontmatter":{"description":"Hydro 支持使用插件扩展自身所支持的功能。 插件对站点的所有内容具有完全的访问权限,请不要启用来历不明的插件。 附加组件列表 部分插件(斜体标注)需配合第三方软件使用,如仅安装不配置/不安装第三方软件会导致系统无法正常运行,详情请前往左侧插件详情查看。 Hydro 官方目前提供了以下附加组件: ID 描述 ---------------------...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"插件"}],["meta",{"property":"og:description","content":"Hydro 支持使用插件扩展自身所支持的功能。 插件对站点的所有内容具有完全的访问权限,请不要启用来历不明的插件。 附加组件列表 部分插件(斜体标注)需配合第三方软件使用,如仅安装不配置/不安装第三方软件会导致系统无法正常运行,详情请前往左侧插件详情查看。 Hydro 官方目前提供了以下附加组件: ID 描述 ---------------------..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-22T01:02:47.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-22T01:02:47.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"插件\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-22T01:02:47.000Z\\",\\"author\\":[]}"]]},"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":[]},{"level":2,"title":"卸载","slug":"卸载","link":"#卸载","children":[]}],"git":{"createdTime":1595413301000,"updatedTime":1713747767000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":7},{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":6},{"name":"(Macesuted)","email":"macesuted@foxmail.com","commits":3},{"name":"Macesuted","email":"macesuted@qq.com","commits":5},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"无限UCW","email":"45730483+wuxianucw@users.noreply.github.com","commits":2},{"name":"undefined","email":"masnn0@outlook.com","commits":1}]},"readingTime":{"minutes":1.78,"words":535},"filePathRelative":"plugins/README.md","localizedDate":"July 22, 2020","autoDesc":true,"excerpt":""}')},3748:(s,e,a)=>{a.r(e),a.d(e,{default:()=>d});var t=a(6252);const n=[(0,t.uE)('Hydro 支持使用插件扩展自身所支持的功能。
Warning
插件对站点的所有内容具有完全的访问权限,请不要启用来历不明的插件。
Tips
部分插件(斜体标注)需配合第三方软件使用,如仅安装不配置/不安装第三方软件 会导致系统无法正常运行,详情请前往左侧插件详情查看。
Hydro 官方目前提供了以下附加组件:
ID 描述 @hydrooj/blog 博客功能 @hydrooj/fps-importer 导入 fps 格式的题目 @hydrooj/geoip 显示用户登录地(需要IP库支持) @hydrooj/hydrojudge 评测组件 @hydrooj/import-qduoj 导入 QDUOJ 导出的题库 @hydrooj/import-hoj 导入 HOJ 导出的题库 @hydrooj/login-with-github 允许用户使用 GitHub 登录 @hydrooj/login-with-google 允许用户使用 Google 登录 @hydrooj/migrate 从 vijos4/HustOJ/SYZOJ/UniversalOJ 升级 @hydrooj/recaptcha 注册时启用 reCAPTCHA 验证码 @hydrooj/ui-default Hydro 的默认用户界面 @hydrooj/onlyoffice 显示 doc/docx 格式题目 @hydrooj/sonic 基于 sonic 的题目搜索增强(需安装 sonic) @hydrooj/elastic-search 基于 Elastic 的题目搜索增强(需安装 Elastic) @hydrooj/vjudge Codeforces/SPOJ/UOJ/POJ/Luogu @hydrooj/prom-client 导出系统状态至 Prometheus
大部分插件的配置均可在安装后于 控制面板>系统设置 中找到。
部分插件若安装后没有正确配置可能会影响系统正常使用!
先全局安装所需模块,再向 hydrooj 注册即可。例:安装 @hydrooj/geoip
yarn global add @hydrooj/geoip \nhydrooj addon add @hydrooj/geoip \n
或者,如果你正在安装一个其他途径获取的插件(自行创建等),请直接使用文件夹 绝对路径 : (文件夹路径即为 包含 package.json 的文件夹)
hydrooj addon add /root/xxx \n
请不要将插件与插件嵌套摆放,否则可能会导致一些不可预知的问题。
安装完插件后需要重启 hydrooj 以使插件生效。
yarn global upgrade-interactive --latest \n
yarn global remove @hydrooj/geoip \nhydrooj addon remove @hydrooj/geoip \n
',22)],o={},d=(0,a(3744).Z)(o,[["render",function(s,e){return(0,t.wg)(),(0,t.iD)("div",null,n)}]])},3744:(s,e)=>{e.Z=(s,e)=>{const a=s.__vccOpts||s;for(const[s,t]of e)a[s]=t;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-68002798.0f857d0c.js b/assets/js/v-68002798.0f857d0c.js
new file mode 100644
index 00000000..60883189
--- /dev/null
+++ b/assets/js/v-68002798.0f857d0c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5287],{4791:(e,t,i)=>{i.r(t),i.d(t,{data:()=>o});const o=JSON.parse('{"key":"v-68002798","path":"/docs/install/smtp.html","title":"SMTP","lang":"en-US","frontmatter":{"description":"以 QQ 邮箱为例。 SMTP_USER: 12345678@qq.com ; SMTP_PASS: 提供的 SMTP 密码 ; SMTP_HOST: smtp.qq.com ; SMTP_PORT: 465/587 (请参照邮件服务商说明) ; SMTP_SECURE: 是否使用加密 TLS 连接(请参照邮件服务商说明,使用 STARTTLS 的服务...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/install/smtp.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"SMTP"}],["meta",{"property":"og:description","content":"以 QQ 邮箱为例。 SMTP_USER: 12345678@qq.com ; SMTP_PASS: 提供的 SMTP 密码 ; SMTP_HOST: smtp.qq.com ; SMTP_PORT: 465/587 (请参照邮件服务商说明) ; SMTP_SECURE: 是否使用加密 TLS 连接(请参照邮件服务商说明,使用 STARTTLS 的服务..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-07-18T07:40:07.000Z"}],["meta",{"property":"article:modified_time","content":"2024-07-18T07:40:07.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"SMTP\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-07-18T07:40:07.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1631785934000,"updatedTime":1721288407000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"HuParry","email":"103566602+HuParry@users.noreply.github.com","commits":1},{"name":"Macesuted","email":"macesuted@qq.com","commits":1}]},"readingTime":{"minutes":0.52,"words":155},"filePathRelative":"docs/install/smtp.md","localizedDate":"September 16, 2021","autoDesc":true,"excerpt":""}')},6145:(e,t,i)=>{i.r(t),i.d(t,{default:()=>r});var o=i(6252);const l=[(0,o.uE)('以 QQ 邮箱为例。
SMTP_USER: 12345678@qq.com SMTP_PASS: 提供的 SMTP 密码 SMTP_HOST: smtp.qq.com SMTP_PORT: 465/587 (请参照邮件服务商说明) SMTP_SECURE: 是否使用加密 TLS 连接(请参照邮件服务商说明,使用 STARTTLS 的服务商无需勾选) SMTP_FROM: 发送签名(提示:若不清楚请填写邮件地址,填错会导致邮件无法发送) 已知能够完整兼容的服务商有:
QQ 邮箱 腾讯企业邮 网易 163 邮箱 飞书域名邮箱 Zeptomail Zoho Mail Outlook Gmail 新浪邮箱 如果使用其他服务商且没有发现问题,欢迎向此列表 Pull Request。
',6)],a={},r=(0,i(3744).Z)(a,[["render",function(e,t){return(0,o.wg)(),(0,o.iD)("div",null,l)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const i=e.__vccOpts||e;for(const[e,o]of t)i[e]=o;return i}}}]);
\ No newline at end of file
diff --git a/assets/js/v-69f3a96a.e1c9e854.js b/assets/js/v-69f3a96a.e1c9e854.js
new file mode 100644
index 00000000..5cff5577
--- /dev/null
+++ b/assets/js/v-69f3a96a.e1c9e854.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[726],{8689:(e,t,o)=>{o.r(t),o.d(t,{data:()=>d});const d=JSON.parse('{"key":"v-69f3a96a","path":"/docs/system/import-user.html","title":"导入用户","lang":"en-US","frontmatter":{"description":"目前支持 csv 格式(用 , 分隔)或 Excel 格式(用 TAB 分隔) 导入用户数据, 数据既可以用文本编辑器创建,也可以用 Excel 等软件来辅助创建。 每行最少三列,最多五列,分别为: 邮箱,用户名,密码,显示名,用户信息。(显示名和用户信息为可选) 请使用 UTF-8 编码,否则中文可能会乱码。 如果使用 CSV 格式(逗号分隔),则用...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/import-user.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"导入用户"}],["meta",{"property":"og:description","content":"目前支持 csv 格式(用 , 分隔)或 Excel 格式(用 TAB 分隔) 导入用户数据, 数据既可以用文本编辑器创建,也可以用 Excel 等软件来辅助创建。 每行最少三列,最多五列,分别为: 邮箱,用户名,密码,显示名,用户信息。(显示名和用户信息为可选) 请使用 UTF-8 编码,否则中文可能会乱码。 如果使用 CSV 格式(逗号分隔),则用..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2022-12-29T09:30:13.000Z"}],["meta",{"property":"article:modified_time","content":"2022-12-29T09:30:13.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"导入用户\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2022-12-29T09:30:13.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1628908242000,"updatedTime":1672306213000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":2},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"undefined","email":"i@undefined.moe","commits":2}]},"readingTime":{"minutes":0.84,"words":252},"filePathRelative":"docs/system/import-user.md","localizedDate":"August 14, 2021","autoDesc":true,"excerpt":""}')},197:(e,t,o)=>{o.r(t),o.d(t,{default:()=>a});var d=o(6252);const s=[(0,d.uE)('目前支持 csv 格式(用 ,
分隔)或 Excel 格式(用 TAB 分隔) 导入用户数据, 数据既可以用文本编辑器创建,也可以用 Excel 等软件来辅助创建。
每行最少三列,最多五列,分别为: 邮箱,用户名,密码,显示名,用户信息。(显示名和用户信息为可选) 请使用 UTF-8 编码,否则中文可能会乱码。 如果使用 CSV 格式(逗号分隔),则用户信息列不可用。
foo@undefined.moe\tuser1\tpassword1 \nbar@undefined.moe\tuser2\tpassword2\ttemp \ntest@undefined.moe\tuser3\tpassword3\ttest\t{"group":"class1","studentId":"123","school":"Hydro School"} \n
可以在粘贴后点击预览验证复制入的数据的有效性
这将创建三个用户:
user1
密码为 password1
, 邮箱 foo@undefined.moe
;user2
密码为 password2
,邮箱 bar@undefined.moe
,显示名为 temp
;user3
密码为 password3
,邮箱 test@undefined.moe
,显示名为 test
,学校为 Hydro School
,学号为 123
,该用户将会被分配至当前域的 class1
小组内; ',8)],n={},a=(0,o(3744).Z)(n,[["render",function(e,t){return(0,d.wg)(),(0,d.iD)("div",null,s)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,d]of t)o[e]=d;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-6b4a62ea.a445dff7.js b/assets/js/v-6b4a62ea.a445dff7.js
new file mode 100644
index 00000000..2f232aa7
--- /dev/null
+++ b/assets/js/v-6b4a62ea.a445dff7.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[6599],{9485:(e,t,o)=>{o.r(t),o.d(t,{data:()=>i});const i=JSON.parse('{"key":"v-6b4a62ea","path":"/docs/install/s3.html","title":"存储","lang":"en-US","frontmatter":{"description":"使用一键安装脚本部署的 Hydro 一般已自动完成存储配置。 文件默认存储于本地的 /data/file/hydro 目录下,切换存储后端时需要手动复制或移动原有文件。 请根据你使用的存储端类型阅读对应教程。(同时欢迎使用其他存储类型的用户向我们提供详细的存储教程) 使用 S3 作为存储后端 如果关闭了 file.pathStyle 选项,请在 end...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/install/s3.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"存储"}],["meta",{"property":"og:description","content":"使用一键安装脚本部署的 Hydro 一般已自动完成存储配置。 文件默认存储于本地的 /data/file/hydro 目录下,切换存储后端时需要手动复制或移动原有文件。 请根据你使用的存储端类型阅读对应教程。(同时欢迎使用其他存储类型的用户向我们提供详细的存储教程) 使用 S3 作为存储后端 如果关闭了 file.pathStyle 选项,请在 end..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-06-29T13:57:26.000Z"}],["meta",{"property":"article:modified_time","content":"2024-06-29T13:57:26.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"存储\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-06-29T13:57:26.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":3,"title":"使用 S3 作为存储后端","slug":"使用-s3-作为存储后端","link":"#使用-s3-作为存储后端","children":[]}],"git":{"createdTime":1631714121000,"updatedTime":1719669446000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":5},{"name":"undefined","email":"i@undefined.moe","commits":5},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2}]},"readingTime":{"minutes":1.27,"words":380},"filePathRelative":"docs/install/s3.md","localizedDate":"September 15, 2021","autoDesc":true,"excerpt":""}')},6817:(e,t,o)=>{o.r(t),o.d(t,{default:()=>r});var i=o(6252);const d=(0,i.uE)('Tips
使用一键安装脚本部署的 Hydro 一般已自动完成存储配置。
文件默认存储于本地的 /data/file/hydro
目录下,切换存储后端时需要手动复制或移动原有文件。 请根据你使用的存储端类型阅读对应教程。(同时欢迎使用其他存储类型的用户向我们提供详细的存储教程)
Tips
如果关闭了 file.pathStyle
选项,请在 endPointForUser
和 endPointForJudge
设置中填写真实 url,/fs/
端点将不可用。
MinIO
Warning
新版本 MinIO 占用较大,如果您为轻量使用,我们不建议使用 MinIO 。旧版本 Hydro 用户大部分可直接切换至 file 模式,由 Hydro 代替读取。
',7),c={href:"https://min.io/",target:"_blank",rel:"noopener noreferrer"},l=(0,i.uE)("file.type
: s3
file.endPoint
: http://127.0.0.1:9000
(即 MinIO 启动时显示的 endPoint)file.accessKey
: 参照 MinIO 配置file.secretKey
: 参照 MinIO 配置file.bucket
: hydro
(MinIO 内部存储桶名称)file.region
: us-east-1
file.pathStyle
: truefile.endPointForUser
: /fs/
file.endPointForJudge
: /fs/
保存后重启,已有文件请自行复制。
腾讯云COS
进入 控制面板>系统设置>存储桶设置。
file.type
: s3
file.endPoint
: https://cos.<存储桶地域>.myqcloud.com
(或是 https)file.accessKey
: 您的腾讯云 API 密钥的 SecretIdfile.secretKey
: 您的腾讯云 API 密钥的 SecretKeyfile.bucket
: <存储桶名称>file.region
: Autofile.pathStyle
: falsefile.endPointForUser
: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/
file.endPointForJudge
: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/
保存后重启,已有文件请自行复制。
阿里云OSS
// TODO & PRs Welcome
",8),n={},r=(0,o(3744).Z)(n,[["render",function(e,t){const o=(0,i.up)("ExternalLinkIcon");return(0,i.wg)(),(0,i.iD)("div",null,[d,(0,i._)("p",null,[(0,i._)("a",c,[(0,i.Uk)("安装 MinIO"),(0,i.Wm)(o)]),(0,i.Uk)(" 后进入 控制面板>manage_config。")]),l])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,i]of t)o[e]=i;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-6d3257b0.dcf0a34f.js b/assets/js/v-6d3257b0.dcf0a34f.js
new file mode 100644
index 00000000..6e268bb4
--- /dev/null
+++ b/assets/js/v-6d3257b0.dcf0a34f.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[578],{1952:(e,t,o)=>{o.r(t),o.d(t,{data:()=>n});const n=JSON.parse('{"key":"v-6d3257b0","path":"/docs/system/FAQ.html","title":"常见问题","lang":"en-US","frontmatter":{"description":"已移动至 此处 (/FAQ/)","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/FAQ.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"常见问题"}],["meta",{"property":"og:description","content":"已移动至 此处 (/FAQ/)"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2022-03-14T10:46:41.000Z"}],["meta",{"property":"article:modified_time","content":"2022-03-14T10:46:41.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"常见问题\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2022-03-14T10:46:41.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1622877676000,"updatedTime":1647254801000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":7},{"name":"Macesuted","email":"macesuted@qq.com","commits":3},{"name":"(Macesuted)","email":"1912192337@qq.com","commits":2},{"name":"stong12345","email":"93954074@qq.com","commits":1},{"name":"zryoung","email":"riyang@qq.com","commits":1}]},"readingTime":{"minutes":0.04,"words":11},"filePathRelative":"docs/system/FAQ.md","localizedDate":"June 5, 2021","autoDesc":true,"excerpt":""}')},4121:(e,t,o)=>{o.r(t),o.d(t,{default:()=>i});var n=o(6252);const a=(0,n._)("h1",{id:"常见问题",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#常见问题"},[(0,n._)("span",null,"常见问题")])],-1),r={},i=(0,o(3744).Z)(r,[["render",function(e,t){const o=(0,n.up)("RouterLink");return(0,n.wg)(),(0,n.iD)("div",null,[a,(0,n._)("p",null,[(0,n.Uk)("已移动至 "),(0,n.Wm)(o,{to:"/FAQ/"},{default:(0,n.w5)((()=>[(0,n.Uk)("此处")])),_:1})])])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,n]of t)o[e]=n;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-6dd45d9b.8633ef99.js b/assets/js/v-6dd45d9b.8633ef99.js
new file mode 100644
index 00000000..6c33f61e
--- /dev/null
+++ b/assets/js/v-6dd45d9b.8633ef99.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[6165],{627:(e,t,p)=>{p.r(t),p.d(t,{data:()=>r});const r=JSON.parse('{"key":"v-6dd45d9b","path":"/plugins/fps-importer.html","title":"fps-importer","lang":"en-US","frontmatter":{"description":"从 fps 文件导入题目 在题库右侧“创建题目”一栏中选择“从 FPS 文件导入”。 在打开的窗口中,您可以上传: fps 格式的 xml 文件; zip 文件,其中包含了一个或多个 fps 格式的 xml 文件; 由于防止解析 fps 文件消耗大量内存,系统默认拒绝导入超过 64MiB 的文件; xml 文件需要为 UTF8 编码,否则可能出现中文题...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/fps-importer.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"fps-importer"}],["meta",{"property":"og:description","content":"从 fps 文件导入题目 在题库右侧“创建题目”一栏中选择“从 FPS 文件导入”。 在打开的窗口中,您可以上传: fps 格式的 xml 文件; zip 文件,其中包含了一个或多个 fps 格式的 xml 文件; 由于防止解析 fps 文件消耗大量内存,系统默认拒绝导入超过 64MiB 的文件; xml 文件需要为 UTF8 编码,否则可能出现中文题..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-22T01:07:54.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-22T01:07:54.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"fps-importer\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-22T01:07:54.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"从 fps 文件导入题目","slug":"从-fps-文件导入题目","link":"#从-fps-文件导入题目","children":[]}],"git":{"createdTime":1618895412000,"updatedTime":1713748074000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":3},{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":0.63,"words":190},"filePathRelative":"plugins/fps-importer.md","localizedDate":"April 20, 2021","autoDesc":true,"excerpt":""}')},8432:(e,t,p)=>{p.r(t),p.d(t,{default:()=>n});var r=p(6252);const i=[(0,r._)("h1",{id:"fps-importer",tabindex:"-1"},[(0,r._)("a",{class:"header-anchor",href:"#fps-importer"},[(0,r._)("span",null,"fps-importer")])],-1),(0,r._)("h2",{id:"从-fps-文件导入题目",tabindex:"-1"},[(0,r._)("a",{class:"header-anchor",href:"#从-fps-文件导入题目"},[(0,r._)("span",null,"从 fps 文件导入题目")])],-1),(0,r._)("p",null,[(0,r.Uk)("在题库右侧“创建题目”一栏中选择“从 FPS 文件导入”。"),(0,r._)("br"),(0,r.Uk)(" 在打开的窗口中,您可以上传:")],-1),(0,r._)("ul",null,[(0,r._)("li",null,"fps 格式的 xml 文件"),(0,r._)("li",null,"zip 文件,其中包含了一个或多个 fps 格式的 xml 文件")],-1),(0,r._)("p",null,"由于防止解析 fps 文件消耗大量内存,系统默认拒绝导入超过 64MiB 的文件; xml 文件需要为 UTF8 编码,否则可能出现中文题面乱码; 在新版本 fps-importer 中,管理员可以修改导入文件大小限制,但请注意,我们仍不建议您导入过大的题目包。 若您的文件超过大小限制,可考虑先在本地使用 Easy-Fps-Viewer 等工具进行拆分。",-1)],o={},n=(0,p(3744).Z)(o,[["render",function(e,t){return(0,r.wg)(),(0,r.iD)("div",null,i)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const p=e.__vccOpts||e;for(const[e,r]of t)p[e]=r;return p}}}]);
\ No newline at end of file
diff --git a/assets/js/v-723d0d85.37d33c3e.js b/assets/js/v-723d0d85.37d33c3e.js
new file mode 100644
index 00000000..7f685123
--- /dev/null
+++ b/assets/js/v-723d0d85.37d33c3e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[8421],{3963:(t,e,o)=>{o.r(e),o.d(e,{data:()=>r});const r=JSON.parse('{"key":"v-723d0d85","path":"/docs/system/","title":"System","lang":"en-US","frontmatter":{"title":"System","article":false,"feed":false,"sitemap":false,"description":"","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"System"}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"en-US"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"System\\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0,"words":1},"filePathRelative":null,"autoDesc":true,"excerpt":""}')},8976:(t,e,o)=>{o.r(e),o.d(e,{default:()=>n});var r=o(6252);const s={},n=(0,o(3744).Z)(s,[["render",function(t,e){const o=(0,r.up)("AutoCatalog");return(0,r.wg)(),(0,r.iD)("div",null,[(0,r.Wm)(o)])}]])},3744:(t,e)=>{e.Z=(t,e)=>{const o=t.__vccOpts||t;for(const[t,r]of e)o[t]=r;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-74379e72.33637c2c.js b/assets/js/v-74379e72.33637c2c.js
new file mode 100644
index 00000000..042e944e
--- /dev/null
+++ b/assets/js/v-74379e72.33637c2c.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5548],{999:(s,a,n)=>{n.r(a),n.d(a,{data:()=>o});const o=JSON.parse('{"key":"v-74379e72","path":"/FAQ/","title":"常见问题集合","lang":"en-US","frontmatter":{"description":"好消息!本页和各大浏览器均达成了合作,使用 Ctrl-F 即可快速搜索关键词! 更多教程请点击右上角的常用教程查看。 用户QQ群 1085853538 如何快速上手了解系统功能? 参照本文 https://hydro.ac/discuss/6172ceeed850d38c79ae18f9 (https://hydro.ac/discuss/6172ce...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/FAQ/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"常见问题集合"}],["meta",{"property":"og:description","content":"好消息!本页和各大浏览器均达成了合作,使用 Ctrl-F 即可快速搜索关键词! 更多教程请点击右上角的常用教程查看。 用户QQ群 1085853538 如何快速上手了解系统功能? 参照本文 https://hydro.ac/discuss/6172ceeed850d38c79ae18f9 (https://hydro.ac/discuss/6172ce..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-07-24T09:09:52.000Z"}],["meta",{"property":"article:modified_time","content":"2024-07-24T09:09:52.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"常见问题集合\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-07-24T09:09:52.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"好消息!本页和各大浏览器均达成了合作,使用 Ctrl-F 即可快速搜索关键词!","slug":"好消息-本页和各大浏览器均达成了合作-使用-ctrl-f-即可快速搜索关键词","link":"#好消息-本页和各大浏览器均达成了合作-使用-ctrl-f-即可快速搜索关键词","children":[]},{"level":2,"title":"更多教程请点击右上角的常用教程查看。","slug":"更多教程请点击右上角的常用教程查看。","link":"#更多教程请点击右上角的常用教程查看。","children":[]},{"level":2,"title":"用户QQ群 1085853538","slug":"用户qq群-1085853538","link":"#用户qq群-1085853538","children":[]},{"level":2,"title":"如何快速上手了解系统功能?","slug":"如何快速上手了解系统功能","link":"#如何快速上手了解系统功能","children":[]},{"level":2,"title":"什么是 OJ?","slug":"什么是-oj","link":"#什么是-oj","children":[]},{"level":2,"title":"Arch Linux 开发模式安装时出现 [ERR_STREAM_PREMATURE_CLOSE]: Premature close 错误","slug":"arch-linux-开发模式安装时出现-err-stream-premature-close-premature-close-错误","link":"#arch-linux-开发模式安装时出现-err-stream-premature-close-premature-close-错误","children":[]},{"level":2,"title":"为什么我安装完成之后仍然无法访问?","slug":"为什么我安装完成之后仍然无法访问","link":"#为什么我安装完成之后仍然无法访问","children":[]},{"level":2,"title":"为什么我配置完反向代理(caddy/nginx)之后无法登录(出现CsrfTokenError)?","slug":"为什么我配置完反向代理-caddy-nginx-之后无法登录-出现csrftokenerror","link":"#为什么我配置完反向代理-caddy-nginx-之后无法登录-出现csrftokenerror","children":[]},{"level":2,"title":"怎么备份/还原备份/迁移数据?","slug":"怎么备份-还原备份-迁移数据","link":"#怎么备份-还原备份-迁移数据","children":[]},{"level":2,"title":"恢复备份时出现 \'/data/file/hydro\': Directory not empty","slug":"恢复备份时出现-data-file-hydro-directory-not-empty","link":"#恢复备份时出现-data-file-hydro-directory-not-empty","children":[]},{"level":2,"title":"更新升级","slug":"更新升级","link":"#更新升级","children":[]},{"level":2,"title":"怎么导入题目/创建题目?","slug":"怎么导入题目-创建题目","link":"#怎么导入题目-创建题目","children":[]},{"level":2,"title":"如何限制未登录用户访问?","slug":"如何限制未登录用户访问","link":"#如何限制未登录用户访问","children":[]},{"level":2,"title":"怎么添加页脚备案号?","slug":"怎么添加页脚备案号","link":"#怎么添加页脚备案号","children":[]},{"level":2,"title":"比赛作业里面的时间是什么含义,OI排名跟普通排名有何区别?","slug":"比赛作业里面的时间是什么含义-oi排名跟普通排名有何区别","link":"#比赛作业里面的时间是什么含义-oi排名跟普通排名有何区别","children":[]},{"level":2,"title":"脚本把 OJ 装在哪里了?","slug":"脚本把-oj-装在哪里了","link":"#脚本把-oj-装在哪里了","children":[]},{"level":2,"title":"题目的限时和内存限制的精度是怎样的?","slug":"题目的限时和内存限制的精度是怎样的","link":"#题目的限时和内存限制的精度是怎样的","children":[]},{"level":2,"title":"我想让 Python 支持 numpy 等等库,怎么办?","slug":"我想让-python-支持-numpy-等等库-怎么办","link":"#我想让-python-支持-numpy-等等库-怎么办","children":[]},{"level":2,"title":"使用安装脚本后忘记 MongoDB 的账号密码怎么办?","slug":"使用安装脚本后忘记-mongodb-的账号密码怎么办","link":"#使用安装脚本后忘记-mongodb-的账号密码怎么办","children":[]},{"level":2,"title":"如何关闭、打开用户注册?","slug":"如何关闭、打开用户注册","link":"#如何关闭、打开用户注册","children":[]},{"level":2,"title":"用户名为 Hydro 的用户是干什么的?密码是什么?可以登录么?","slug":"用户名为-hydro-的用户是干什么的-密码是什么-可以登录么","link":"#用户名为-hydro-的用户是干什么的-密码是什么-可以登录么","children":[]},{"level":2,"title":"如何修改网站图标?","slug":"如何修改网站图标","link":"#如何修改网站图标","children":[]},{"level":2,"title":"如何重置数据?","slug":"如何重置数据","link":"#如何重置数据","children":[]},{"level":2,"title":"评测显示“总时限超过 60s,评测取消”","slug":"评测显示-总时限超过-60s-评测取消","link":"#评测显示-总时限超过-60s-评测取消","children":[]},{"level":2,"title":"如何在背景中添加线条特效?","slug":"如何在背景中添加线条特效","link":"#如何在背景中添加线条特效","children":[]},{"level":2,"title":"使用 Hydro 要花多少钱?","slug":"使用-hydro-要花多少钱","link":"#使用-hydro-要花多少钱","children":[]},{"level":2,"title":"execve: no such file or directory","slug":"execve-no-such-file-or-directory","link":"#execve-no-such-file-or-directory","children":[]},{"level":2,"title":"怎么自定义用户标签?","slug":"怎么自定义用户标签","link":"#怎么自定义用户标签","children":[]},{"level":2,"title":"为什么我无法批量下载多个文件?","slug":"为什么我无法批量下载多个文件","link":"#为什么我无法批量下载多个文件","children":[]},{"level":2,"title":"为什么我的提交页面没有语言可选?","slug":"为什么我的提交页面没有语言可选","link":"#为什么我的提交页面没有语言可选","children":[]},{"level":2,"title":"The \'yarn global\' commands have been remove in 2.x - consider using \'yarn dlx\' or a third-party plugin instead","slug":"the-yarn-global-commands-have-been-remove-in-2-x-consider-using-yarn-dlx-or-a-third-party-plugin-instead","link":"#the-yarn-global-commands-have-been-remove-in-2-x-consider-using-yarn-dlx-or-a-third-party-plugin-instead","children":[]},{"level":2,"title":"我是机房用户,大量用户同 IP 操作触发了频率限制,怎么解决?","slug":"我是机房用户-大量用户同-ip-操作触发了频率限制-怎么解决","link":"#我是机房用户-大量用户同-ip-操作触发了频率限制-怎么解决","children":[]}],"git":{"createdTime":1647254801000,"updatedTime":1721812192000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":10},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1},{"name":"pt3155420267","email":"33685002+pt3155420267@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":10.3,"words":3089},"filePathRelative":"FAQ/README.md","localizedDate":"March 14, 2022","autoDesc":true,"excerpt":""}')},1845:(s,a,n)=>{n.r(a),n.d(a,{default:()=>d});var o=n(6252);const l=(0,o.uE)(' ',5),p={href:"https://hydro.ac/discuss/6172ceeed850d38c79ae18f9",target:"_blank",rel:"noopener noreferrer"},e=(0,o._)("br",null,null,-1),t=(0,o._)("br",null,null,-1),r=(0,o.uE)('系统中的用户只有编辑、禁用功能,没有删除功能,这是为了从根源上防止出现“教学事故”,请不要要求增加相关功能,如果认为自己绝不会误操作,请自行开发相关功能。
现在你所使用的评测系统也仅仅是一个程序,并没有人工智能。因此很多地方需要你来迁就它,如果不这样做,你的答案即使本质上是正确的,由于形式的错误造成系统不能理解,也会导致错误。 系统运行过程如下:
教师在系统中添加题目,并严格定义题目提供输入数据的格式和要求的输出数据格式。 教师根据题目定义的格式向系统中添加若干组测试数据,每组数据都包含输入数据和对应的输出。 学生阅读题目,并根据自己的理解提交程序。 系统编译并运行学生的程序,再将老师事先提供的输入数据“喂”给学生的程序,看它会输出什么。 如果学生程序的输出与老师之前提供的输出完全一致,一字不差,则认为学生的程序是正确的,否则则认为该程序错误。 如果运行过程中出现内存、时间上超出题目限制的情况,则中断程序的运行,并认为答案不正确。 在了解了上面的情况以后,同学们应该理解,如果题目没有要求程序输出“Please Input Two Number”之类的提示信息,那么自行输出这些文字将导致你的程序输出与老师事先告诉系统的输出不能做到“一字不差”,因而将导致系统报答案错误。 如果题目要求每两行输出之间要空一行,结果你没有空,会是格式错误,反之亦然。 也许你会觉得,哦,这系统太烂了,这点东西都不能自动识别;实际上正是这样才能有效训练大家编程的精确性、养成良好的代码习惯。很多程序高手都跟你一样,是从对这个系统吐槽开始学习如何认真仔细的、一丝不苟的进行编程的。 系统为了能用统一的方式运行所有同学的答案,不得不对所有人提交的答案的形式进行限定。 对于学习C、C++语言的同学来说,所有提交给系统的答案必须包含并且只有一个main函数,这个main函数必须返回int类型,并且最好返回0,因为操作系统对非零的返回值认为是运行出错。 编译错误发生时,点击“编译错误”的文字链接可以得到详细解释。
删除 .yarnrc.yml
和 .yarn
后再试。
如果您使用的是 阿里云/腾讯云 等服务商,请确保安全组放行了 80 和 443 端口。
',10),c=(0,o.uE)('hydrooj backup
hydrooj restore backup-xxx.zip
百度学习 crontab 的用法后,可以使用 sudo crontab -e
定制自动备份计划。
关闭 minio
(pm2 stop minio
) 后手动删除 /data/file/hydro
文件夹再重试。
yarn global upgrade-interactive --latest
然后按空格选中除 pm2 之外的所有包更新,回车确认。 然后 pm2 restart hydrooj
重启服务。 重启后 pm2 logs hydrooj --lines 100
没有看到报错并看到了 Server started
则一切正常。
Hydro 的所有历史版本,都可以无损升级到最新版本。如果老系统更新有疑问,随时加官方群咨询群主。
题目列表右侧有相应入口。
切记:不要导入过多你暂时用不上的题目,正确的方式是每次训练、作业,导入所需的5-10个题目,比赛作业结束后让题目成为训练题库的一部分。这样能保证题库中题号靠前的题目难度依次上升,适合后来的同学自行训练。不要贪图题目数量而忽视其质量。自己看不懂解法的题目,少用、慎用。
管理域 -> 管理权限 将 Guest 权限组的 查看此域 权限禁用。
在系统设置 footer_extra_html
内添加一行 <a herf="https://beian.miit.gov.cn/">XX 备 XX 号</a>
时间是指参与人员做出对应题目“花费”的时间: 即:做出题目的时刻 – 比赛开始的时刻 + 惩罚时间 惩罚时间 = 做对之前错误的提交数 * 20分钟。 普通排名按做对的题目数和“花费”的时间进行排名。 OI排名,按得分排名,题目可以按通过的比例进行记分,每题100分。如果希望数据的分值不平均分配,可以使用 config 配置。
Hydro 的默认位置可以运行 yarn global dir
得到。(不要直接改代码,更新会覆盖此处的所有修改,请使用插件API) 默认的数据库文件放置在 /data/db
,但是不要直接复制文件,而是推荐用 hydrooj backup
进行备份。 测试数据等文件存储于 /data/file
。 配置文件位于 /root/.config/hydro
和 /root/.hydro
。 对于正在运行中的生产服务器,任何操作前请做好离线备份。 备份文件一定要解压查看内部是否包含全部数据,关注备份的大小(大系统备份应该有上百兆),有条件找虚拟机实测还原是否成功
题目限时允许设定的字面精度是 1ms,但是由于操作系统内核参数的限定,实测的精度通常为4ms。 内存限制的精度是1MB,对于本地native的编译型语言c/c++/pascal/freebasic/clang等是考察程序本身的内存申请空间; 对于虚拟机和脚本语言,则包含了虚拟机本身或解释器本身的内存消耗。
如果你是 2022/8/12 日前安装,使用 pip3 install numpy
后 pm2 restart hydro-sandbox
否则参照请参照 编译器 章节。
看 /root/.hydro/config.json
。
用户注册由 Guest 用户(uid 为 0)的 PRIV_REGISTER_USER 权限控制,默认允许注册。 使用 hydrooj cli user setPriv 0 0
即可关闭注册。 若要重新打开,可使用 hydrooj cli user setPriv 0 8
。
变更后,请重启 hydrooj 服务:pm2 restart hydrooj
用户名为 Hydro 的用户(uid 为 1)仅用于发送系统消息(与 QQ 中的 10000 类似),无法登录。
使用 hydrooj addon create
创建一个插件,这会自动创建 /root/addon
目录。 进入 /root/addon/public
目录,将您的站点图标放置于该文件夹下。 您需要将以下文件放在该目录中(适配不同浏览器):
favicon-16x16.png
favicon-32x32.png
favicon-96x96.png
favicon.ico
(32x32)android-chrome-192x192.png
apple-touch-icon-180x180.png
分辨率应尽可能对应,但不强制要求。以上图片将在浏览器标签页图片上显示。 您还需要将以下文件放在该目录:
以上图片将在页面左上角 logo 显示。 之后前往系统设置,找到 nav_logo_dark
设置项,改为 /nav_logo_dark.png
,重启 Hydro 即可应用更改。
记得清理浏览器缓存。
Warning
此操作会删除所有用户/题目/比赛等数据。请谨慎操作!
',39),E={href:"https://github.com/hydro-dev/Hydro/blob/master/install/reset.sh",target:"_blank",rel:"noopener noreferrer"},y=(0,o.uE)('您可按需更改,显示顺序与配置中的排列顺序相同。
在系统设置中修改 total_time_limit 为允许的单题最大评测时长即可。
在系统设置中找到 footer_extra_html
项,加上如下内容:(写在一行内,不要多加换行)
基于 https://github.com/hustcc/canvas-nest.js ,MIT
<script> ( () => { function e ( e , n , t ){ return e . getAttribute ( n ) || t } function n (){ l = i . width = window . innerWidth || document . documentElement . clientWidth || document . body . clientWidth , u = i . height = window . innerHeight || document . documentElement . clientHeight || document . body . clientHeight } function c (){ var t , o , i , a , m ; r . clearRect ( 0 , 0 , l , u ) , s . forEach ( function ( e , n ){ for ( e . x += e . xa , e . y += e . ya , e . xa *= e . x > l || e . x < 0 ?- 1 : 1 , e . ya *= e . y > u || e . y < 0 ?- 1 : 1 , r . fillRect ( e . x - .5 , e . y - .5 , 1 , 1 ) , o = n + 1 ; o < d . length ; o ++ ) null!== ( t = d [ o ]) . x &&null!== t . y && ( i = e . x - t . x , a = e . y - t . y , ( m = i * i + a * a ) < t . max && ( t === y && m >= t . max / 2 && ( e . x -= .03 * i , e . y -= .03 * a ) , m = ( t . max - m ) / t . max , r . beginPath () , r . lineWidth = m / 2 , r . strokeStyle = " rgba( " + x . c + " , " + ( .2 + m ) + " ) " , r . moveTo ( e . x , e . y ) , r . lineTo ( t . x , t . y ) , r . stroke ())) } ) , w ( c ) } var l , u , d , t , o , i = document . createElement ( " canvas " ) , x = ( t = ( o = document . getElementsByTagName ( " script " )) . length , o = o [ t - 1 ] ,{ l : t , z : e ( o , " zIndex " , - 1 ) , o : e ( o , " opacity " , .5 ) , c : e ( o , " color " , " 0,0,0 " ) , n : e ( o , " count " , 99 ) } ) , a = " c_n " + x . l , r = i . getContext ( " 2d " ) , w = window . requestAnimationFrame || window . webkitRequestAnimationFrame || window . mozRequestAnimationFrame || window . oRequestAnimationFrame || window . msRequestAnimationFrame ||function ( e ){ window . setTimeout ( e , 1e3 / 45 ) }, m = Math . random , y = { x : null , y : null , max : 2e4 } ; i . id = a , i . style . cssText = " position:fixed;top:0;left:0;z-index: " + x . z + " ;opacity: " + x . o , document . getElementsByClassName ( " main " )[ 0 ] . appendChild ( i ) , n () , window . onresize = n , window . onmousemove =function ( e ){ e = e || window . event , y . x = e . clientX , y . y = e . clientY }, window . onmouseout =function (){ y . x =null , y . y =null } ;for ( var s = [] , h = 0 ; x . n > h ; h ++ ) { var f = m () * l , g = m () * u , p = 2 * m () - 1 , v = 2 * m () - 1 ; s . push ( { x : f , y : g , xa : p , ya : v , max : 6e3 } ) } d = s . concat ([ y ]) , setTimeout ( function (){ c () }, 100 ) } )() ;</script> \n
',8),D={href:"https://pay.undefined.moe",target:"_blank",rel:"noopener noreferrer"},F=(0,o.uE)('脚本安装默认只装了一小部分编译器。请参照 编译器 章节安装配置其他编译器。
进入 MongoDB,执行下面的操作即可(根据具体情况替换尖括号中的部分):
use hydro \ndb.user.update( {" _id ": <用户 UID>}, { $set : {" badge ": " <标签内容>#<背景颜色(HEX)>#<文字颜色(HEX)> "}}) \n
请使用现代浏览器进行操作,并尝试给网站设置 https。 否则请选择逐个下载文件(Ctrl+点击文件名)。
题目 -> 评测设置 -> 允许的语言 域设置 -> 编辑域资料 -> 允许的语言 这两个地方,应该填英文逗号分隔的语言ID,不会填请留空。
如果你搞不明白这个问题,请老实用安装脚本,不要折腾开发模式。
方案一: 通过在内网架设代理服务器,将内网 ip 发送至服务端。(推荐) 方案二: 使用形如 hydrooj cli system set limit.user_login 999
的命令设置新的频率限制(可在错误页面查看具体是触发了哪条限制) 方案三: 使用 pm2 start hydrooj -- --benchmark
启动,关闭所有频率限制(不推荐)
',13),i={},d=(0,n(3744).Z)(i,[["render",function(s,a){const n=(0,o.up)("ExternalLinkIcon"),i=(0,o.up)("RouterLink");return(0,o.wg)(),(0,o.iD)("div",null,[l,(0,o._)("p",null,[(0,o.Uk)("参照本文 "),(0,o._)("a",p,[(0,o.Uk)("https://hydro.ac/discuss/6172ceeed850d38c79ae18f9"),(0,o.Wm)(n)]),(0,o.Uk)(" 无服务器快速体验系统功能。"),e,(0,o.Uk)(" 如果你没有二开很多功能的需求,推荐直接使用在线服务。超过两万题的题库可以直接复制使用,无需购置云服务器,无需手动维护,更省心。"),t,(0,o.Uk)(" 如果你有需要绑定自己的域名或是改 Logo 等等自定义需求,也可在管理面板中开通高级功能自助操作。")]),r,(0,o._)("p",null,[(0,o.Uk)("反向代理时请确保设置了正确的 Host Header。"),(0,o.Wm)(i,{to:"/docs/install/proxy.html"},{default:(0,o.w5)((()=>[(0,o.Uk)("详细说明")])),_:1})]),c,(0,o._)("p",null,[(0,o.Uk)("将 "),(0,o._)("a",E,[(0,o.Uk)("此脚本"),(0,o.Wm)(n)]),(0,o.Uk)(" 下载到服务器运行。")]),y,(0,o._)("p",null,[(0,o.Uk)("不要钱,我们是 AGPL 的。如果你钱多,可以 "),(0,o._)("a",D,[(0,o.Uk)("给我发个红包"),(0,o.Wm)(n)]),(0,o.Uk)("。")]),F])}]])},3744:(s,a)=>{a.Z=(s,a)=>{const n=s.__vccOpts||s;for(const[s,o]of a)n[s]=o;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-744497ce.0a587faa.js b/assets/js/v-744497ce.0a587faa.js
new file mode 100644
index 00000000..9aa12be1
--- /dev/null
+++ b/assets/js/v-744497ce.0a587faa.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5671],{7579:(e,t,o)=>{o.r(t),o.d(t,{data:()=>r});const r=JSON.parse('{"key":"v-744497ce","path":"/api/","title":"API","lang":"en-US","frontmatter":{"description":"此处列出部分系统通信协议。","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/api/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"API"}],["meta",{"property":"og:description","content":"此处列出部分系统通信协议。"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-11-22T01:11:53.000Z"}],["meta",{"property":"article:modified_time","content":"2023-11-22T01:11:53.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"API\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-11-22T01:11:53.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1700615513000,"updatedTime":1700615513000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":0.04,"words":13},"filePathRelative":"api/README.md","localizedDate":"November 22, 2023","autoDesc":true,"excerpt":""}')},4272:(e,t,o)=>{o.r(t),o.d(t,{default:()=>i});var r=o(6252);const a=[(0,r._)("h1",{id:"api",tabindex:"-1"},[(0,r._)("a",{class:"header-anchor",href:"#api"},[(0,r._)("span",null,"API")])],-1),(0,r._)("p",null,"此处列出部分系统通信协议。",-1)],n={},i=(0,o(3744).Z)(n,[["render",function(e,t){return(0,r.wg)(),(0,r.iD)("div",null,a)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,r]of t)o[e]=r;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-7445cd33.0ffdbf65.js b/assets/js/v-7445cd33.0ffdbf65.js
new file mode 100644
index 00000000..63ce8115
--- /dev/null
+++ b/assets/js/v-7445cd33.0ffdbf65.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2368],{7402:(t,e,n)=>{n.r(e),n.d(e,{data:()=>a});const a=JSON.parse('{"key":"v-7445cd33","path":"/dev/","title":"开发环境部署","lang":"en-US","frontmatter":{"description":"开发环境仅适合需要进行大量深度修改或希望贡献代码的用户。 如果您没有过 TypeScript 项目的开发经验,非常不建议自建开发环境,请基于插件系统进行你所需要的功能添加与修改。 使用自动脚本安装也可以基于插件系统完成大部分的定制需求(参照左侧【使用 TypeScript 编写插件】章节)。 如果您需要编译 UI,请确认您的开发环境至少拥有 8GB 内...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"开发环境部署"}],["meta",{"property":"og:description","content":"开发环境仅适合需要进行大量深度修改或希望贡献代码的用户。 如果您没有过 TypeScript 项目的开发经验,非常不建议自建开发环境,请基于插件系统进行你所需要的功能添加与修改。 使用自动脚本安装也可以基于插件系统完成大部分的定制需求(参照左侧【使用 TypeScript 编写插件】章节)。 如果您需要编译 UI,请确认您的开发环境至少拥有 8GB 内..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-07-23T09:45:08.000Z"}],["meta",{"property":"article:modified_time","content":"2024-07-23T09:45:08.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"开发环境部署\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-07-23T09:45:08.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"安装依赖","slug":"安装依赖","link":"#安装依赖","children":[]},{"level":2,"title":"安装 Hydro","slug":"安装-hydro","link":"#安装-hydro","children":[]},{"level":2,"title":"插件","slug":"插件","link":"#插件","children":[]},{"level":2,"title":"启动 Hydro","slug":"启动-hydro","link":"#启动-hydro","children":[]},{"level":2,"title":"更新","slug":"更新","link":"#更新","children":[]}],"git":{"createdTime":1611599229000,"updatedTime":1721727908000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":16},{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":5},{"name":"Macesuted","email":"macesuted@qq.com","commits":3},{"name":"(Macesuted)","email":"macesuted@foxmail.com","commits":2},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"(Macesuted)","email":"1912192337@qq.com","commits":1}]},"readingTime":{"minutes":2.93,"words":878},"filePathRelative":"dev/README.md","localizedDate":"January 25, 2021","autoDesc":true,"excerpt":""}')},2121:(t,e,n)=>{n.r(e),n.d(e,{default:()=>y});var a=n(6252);const l=(0,a.uE)('开发环境仅适合需要进行大量深度修改或希望贡献代码的用户。 如果您没有过 TypeScript 项目的开发经验,非常不建议自建开发环境,请基于插件系统进行你所需要的功能添加与修改。 使用自动脚本安装也可以基于插件系统完成大部分的定制需求(参照左侧【使用 TypeScript 编写插件】章节)。 如果您需要编译 UI,请确认您的开发环境至少拥有 8GB 内存。
功能对比 生产模式 开发模式 快速起步 ✅ ❌ 插件 API ✅ ✅ 底层代码修改 ❌ ✅ 热重载 ❌ ✅ 性能优化 ✅ ❌ 兼容性 ✅ ❌ 技术支持 ✅ ❌ 部署难度 简单 复杂 升级 简单 复杂 技能要求 低 高 空闲内存要求 2G 8G 可切换至开发模式 是 = 可切换至生产模式 = 需重写代码
Tips
使用开发环境默认您有良好的国际互联网连接。以下报错信息均为网络问题导致,您可以尝试换源/使用代理/切换网络环境。
Failed to connect Connection reset connect timeout 开发组不会为您解决任何网络问题。
在开发之前,请务必确认您使用了支持 TypeScript 的 IDE 环境,这可以极大降低开发难度。
',6),s=(0,a._)("li",null,"系统要求:Hydro开发环境目前仅支持 Linux 系统,如您使用 Windows 请使用 WSL2 。",-1),d={href:"https://www.mongodb.com/try/download/community",target:"_blank",rel:"noopener noreferrer"},r=(0,a._)("li",null,[(0,a.Uk)("NodeJS:请安装 NodeJS >=18 版本。(若使用 apt 请使用 nodesource 提供的源替代官方源) (推荐使用 nix ,可通过"),(0,a._)("code",null,". <(curl https://hydro.ac/nix.sh)"),(0,a.Uk)(" 快速安装)")],-1),o=(0,a._)("li",null,[(0,a.Uk)("yarn:安装 yarn 前请先完成 NodeJS 安装。 "),(0,a._)("code",null,"nix-env -iA nixpkgs.yarn"),(0,a.Uk)(" 或 "),(0,a._)("code",null,"npm install -g yarn")],-1),i=(0,a._)("li",null,"若需要使用 hydrojudge 请参照 hydrojudge 插件说明部分完成沙箱的安装配置。",-1),c=(0,a.uE)('git clone https://github.com/hydro-dev/Hydro.git /root/Hydro --recursive # 下载至 /root/Hydro 文件夹 \ncd /root/Hydro # 进入工作目录 \nyarn # 安装依赖包 \nyarn build:ui:production # 编译前端 \n
开发环境部署完成后默认不启用任何插件。
所有官方插件均随源码仓库下载到安装文件夹的 packages
子文件夹下,可以通过下面的命令启用官方插件(以启用 @hydrooj/ui-default
为例):
yarn hydrooj addon add @hydrooj/ui-default \n
对于非官方插件,下载后通过下面的命令启用即可(以启用位置在 /root/addon
下的插件为例):
yarn hydrooj addon add /root/addon \n
支持如下启动参数:
--port=2333
指定启动端口--debug
启用开发模式--watch
启用热重载(实验性)使用 yarn debug --port=2333 --watch
启动 Hydro,并在后台运行 yarn build:ui:dev
,可以对前端源码进行实时转译,在反复修改时可节省编译时间。启动完成后,您可以在 8000 端口访问到 Hydro 实例,且前端的任何更改将即时生效。(后端热重载可能存在 bug,部分模块修改后可能仍需重启才能生效) 请注意:此功能仅在启用了 @hydrooj/ui-default
插件的情况下才会生效。
首次启动会要求您填写数据库连接信息。请根据您数据库的安装填写(若无密码则留空) 请按照下文说明创建管理员账户即可正常使用。
需要更新的时候进入对应仓库文件夹执行 git pull
,然后重新 yarn && yarn build:ui:production
即可。
',15),p={},y=(0,n(3744).Z)(p,[["render",function(t,e){const n=(0,a.up)("ExternalLinkIcon");return(0,a.wg)(),(0,a.iD)("div",null,[l,(0,a._)("ul",null,[s,(0,a._)("li",null,[(0,a.Uk)("MongoDB:Hydro 需要 "),(0,a._)("a",d,[(0,a.Uk)("MongoDB"),(0,a.Wm)(n)]),(0,a.Uk)(" 提供数据库服务。")]),r,o,i]),c])}]])},3744:(t,e)=>{e.Z=(t,e)=>{const n=t.__vccOpts||t;for(const[t,a]of e)n[t]=a;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-82f2a624.4ca6060e.js b/assets/js/v-82f2a624.4ca6060e.js
new file mode 100644
index 00000000..f219272d
--- /dev/null
+++ b/assets/js/v-82f2a624.4ca6060e.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[7138],{4624:(e,t,o)=>{o.r(t),o.d(t,{data:()=>r});const r=JSON.parse('{"key":"v-82f2a624","path":"/dev/PERM_PRIV.html","title":"权限节点","lang":"en-US","frontmatter":{"description":"Hydro 的权限使用位运算处理。 例:若某用户具有 PRIVEDITSYSTEM 与 PRIVSETPERM 权限,应设置为 `(1","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/dev/PERM_PRIV.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"权限节点"}],["meta",{"property":"og:description","content":"Hydro 的权限使用位运算处理。 例:若某用户具有 PRIVEDITSYSTEM 与 PRIVSETPERM 权限,应设置为 `(1"}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-05T09:19:22.000Z"}],["meta",{"property":"article:modified_time","content":"2024-01-05T09:19:22.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"权限节点\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-05T09:19:22.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1611599229000,"updatedTime":1704446362000,"contributors":[{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":3},{"name":"undefined","email":"i@undefined.moe","commits":2},{"name":"(Macesuted)","email":"macesuted@foxmail.com","commits":1},{"name":"Macesuted","email":"57275149+Macesuted@users.noreply.github.com","commits":1},{"name":"Macesuted","email":"macesuted@qq.com","commits":1}]},"readingTime":{"minutes":0.21,"words":63},"filePathRelative":"dev/PERM_PRIV.md","localizedDate":"January 25, 2021","autoDesc":true,"excerpt":""}')},9464:(e,t,o)=>{o.r(t),o.d(t,{default:()=>m});var r=o(6252);const a=(0,r._)("h1",{id:"权限节点",tabindex:"-1"},[(0,r._)("a",{class:"header-anchor",href:"#权限节点"},[(0,r._)("span",null,"权限节点")])],-1),n=(0,r._)("p",null,[(0,r.Uk)("Hydro 的权限使用位运算处理。"),(0,r._)("br"),(0,r.Uk)(" 例:若某用户具有 "),(0,r._)("code",null,"PRIV_EDIT_SYSTEM"),(0,r.Uk)(" 与 "),(0,r._)("code",null,"PRIV_SET_PERM"),(0,r.Uk)(" 权限,应设置为 "),(0,r._)("code",null,"(1<<0)|(1<<1)"),(0,r.Uk)(" (即 3)")],-1),i={href:"https://github.com/hydro-dev/Hydro/blob/master/packages/hydrooj/src/model/builtin.ts",target:"_blank",rel:"noopener noreferrer"},c=(0,r._)("p",null,[(0,r.Uk)("扩展阅读:"),(0,r._)("a",{href:"/docs/user/permission"},"权限结构")],-1),d={},m=(0,o(3744).Z)(d,[["render",function(e,t){const o=(0,r.up)("ExternalLinkIcon");return(0,r.wg)(),(0,r.iD)("div",null,[a,n,(0,r._)("p",null,[(0,r.Uk)("可以看 "),(0,r._)("a",i,[(0,r.Uk)("代码"),(0,r.Wm)(o)]),(0,r.Uk)(" 中关于此部分的内容。")]),c])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const o=e.__vccOpts||e;for(const[e,r]of t)o[e]=r;return o}}}]);
\ No newline at end of file
diff --git a/assets/js/v-8daa1a0e.ad9d63c1.js b/assets/js/v-8daa1a0e.ad9d63c1.js
new file mode 100644
index 00000000..d27399e0
--- /dev/null
+++ b/assets/js/v-8daa1a0e.ad9d63c1.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2509],{4958:(e,t,r)=>{r.r(t),r.d(t,{data:()=>o});const o=JSON.parse('{"key":"v-8daa1a0e","path":"/","title":"","lang":"en-US","frontmatter":{"home":true,"heroImage":"/favicon.png","heroText":"Hydro","tagline":"高性能在线测评系统","actions":[{"text":"介绍 💡","link":"/docs/","type":"primary"},{"text":"部署指南","link":"/docs/install/"}],"features":[{"title":"安全","details":"使用 Linux 容器技术隔离用户程序"},{"title":"便捷","details":"支持使用脚本一键搭建"},{"title":"强大","details":"提供了比赛 训练 讨论 题解 作业等功能,并可通过安装附加组件进行扩展"},{"title":"快速","details":"沙箱复用,延迟计算,提高运行效率"}],"footer":"AGPL3.0 Licensed | Copyright © 2021-present Undefined","description":"LICENSE GitHub Workflow Status hydrooj npm node-current GitHub contributors GitHub commit activity Hydro 是一个高效的信息学在线测评系统。特点:易于部署(且提供安装脚本),轻量,功能强大且易于扩展。 Github 仓库 (https://github...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:description","content":"LICENSE GitHub Workflow Status hydrooj npm node-current GitHub contributors GitHub commit activity Hydro 是一个高效的信息学在线测评系统。特点:易于部署(且提供安装脚本),轻量,功能强大且易于扩展。 Github 仓库 (https://github..."}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-12T12:11:12.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-12T12:11:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\",\\"description\\":\\"LICENSE GitHub Workflow Status hydrooj npm node-current GitHub contributors GitHub commit activity Hydro 是一个高效的信息学在线测评系统。特点:易于部署(且提供安装脚本),轻量,功能强大且易于扩展。 Github 仓库 (https://github...\\"}"]]},"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":{"createdTime":1595413301000,"updatedTime":1712923872000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":9},{"name":"Macesuted Kysic","email":"57275149+Macesuted@users.noreply.github.com","commits":3},{"name":"Macesuted Kysic","email":"macesuted@foxmail.com","commits":3},{"name":"(Macesuted)","email":"macesuted@foxmail.com","commits":2},{"name":"Macesuted","email":"57275149+Macesuted@users.noreply.github.com","commits":2},{"name":"undefined","email":"masnn0@outlook.com","commits":2},{"name":"Macesuted","email":"macesuted@qq.com","commits":1},{"name":"Macesuted Kysic","email":"macesuted@qq.com","commits":1},{"name":"criyle","email":"gaoyang4425@gmail.com","commits":1},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1}]},"readingTime":{"minutes":3.43,"words":1030},"filePathRelative":"README.md","localizedDate":"July 22, 2020","autoDesc":true,"excerpt":""}')},8586:(e,t,r)=>{r.r(t),r.d(t,{default:()=>S});var o=r(6252);const i=(0,o.uE)('
Hydro 是一个高效的信息学在线测评系统。特点:易于部署(且提供安装脚本),轻量,功能强大且易于扩展。
',2),l={href:"https://github.com/hydro-dev/Hydro",target:"_blank",rel:"noopener noreferrer"},n=(0,o._)("br",null,null,-1),a=(0,o._)("br",null,null,-1),s=(0,o._)("br",null,null,-1),d=(0,o._)("br",null,null,-1),u={href:"https://github.com/hydro-dev/Hydro/issues",target:"_blank",rel:"noopener noreferrer"},m={href:"https://gitpod.io/#https://github.com/hydro-dev/Hydro",target:"_blank",rel:"noopener noreferrer"},c={href:"https://hydro.ac/",target:"_blank",rel:"noopener noreferrer"},h=(0,o._)("h2",{id:"联系我们",tabindex:"-1"},[(0,o._)("a",{class:"header-anchor",href:"#联系我们"},[(0,o._)("span",null,"联系我们")])],-1),p=(0,o._)("a",{href:"mailto:i@undefined.moe"},"i@undefined.moe",-1),y=(0,o._)("br",null,null,-1),b={href:"https://t.me/undefinedmoe",target:"_blank",rel:"noopener noreferrer"},g=(0,o._)("br",null,null,-1),k=(0,o._)("p",null,[(0,o.Uk)("注1:Hydro 为开源框架,任何人均能够在遵守协议的情况下使用这套框架。"),(0,o._)("br"),(0,o.Uk)(" 版权申诉相关问题请联系对应网站管理者,(通常为其 UID=2 的用户),与开发者无关。")],-1),_={href:"https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md",target:"_blank",rel:"noopener noreferrer"},f=(0,o._)("br",null,null,-1),H=(0,o._)("strong",null,"请勿加群",-1),U=(0,o.uE)('本项目中的 examples/ install/ packages/ui-default/ 下的内容仅采用 AGPL-3.0 进行授权。 项目其余部分使用双重许可:
您可以在遵守 AGPL-3.0 许可证和下述附加条款章节的前提下免费使用这些代码: 如确需闭源,您也可以联系我们购买其他授权。 基于 AGPL3 协议第七条,您在使用本项目时,需要遵守以下额外条款:
不可移除本项目的版权声明与作者/来源署名;(AGPL3 7(b) ) 当重分发经修改后的本软件时,需要在软件名或版本号中采用可识别的方式进行注明;(AGPL3 7(c) ) 除非得到许可,不得以宣传为目的使用作者姓名;(AGPL3 7(d) ) 即: 在您部署 Hydro 时,需要保留底部的 Powered by Hydro
字样,其中的 Hydro
字样需指向 hydro.js.org/本仓库/fork
之一的链接。 若您对源码做出修改/扩展,同样需要以 AGPL-3.0-or-later 开源,您可以以 Powered by Hydro, Modified by xxx
格式在页脚注明。 此限制对以下模块仍然有效:
Hydro 插件; 包括但不限于使用 http 协议与 Hydro 进行交互的组件; ',8),v=(0,o._)("br",null,null,-1),G={href:"https://github.com/mamoe/mirai/issues/850",target:"_blank",rel:"noopener noreferrer"},E=(0,o.uE)('项目开源不代表开发者有义务为您提供服务。 在提问前请先阅读《提问的智慧》。 若有必要,开发者有权对您停止任何技术支持。 开发组会 尽可能 保证用户可以进行平滑升级,但无法保证不在新版本引入影响使用的漏洞,且内部实现可能会在不发布任何通知的情况下进行重命名/修改/删除。 如果您对以上条目感到不适,建议您停止使用本项目。
排名不分先后,按照链接字典序。
',4),L={href:"https://github.com/",target:"_blank",rel:"noopener noreferrer"},x={href:"https://github.com/criyle",target:"_blank",rel:"noopener noreferrer"},W={href:"https://github.com/vijos/vj4",target:"_blank",rel:"noopener noreferrer"},w={},S=(0,r(3744).Z)(w,[["render",function(e,t){const r=(0,o.up)("ExternalLinkIcon");return(0,o.wg)(),(0,o.iD)("div",null,[i,(0,o._)("p",null,[(0,o._)("a",l,[(0,o.Uk)("Github 仓库"),(0,o.Wm)(r)])]),(0,o._)("p",null,[(0,o.Uk)("欢迎 star 本项目,这是对开发者的鼓励。"),n,(0,o.Uk)(" 项目的开发与维护需要资金,欢迎进行捐助。"),a,(0,o.Uk)(" Hydro 提供收费的功能定制服务,如您需要可与我们联系。"),s,(0,o.Uk)(" 相关文档若说明的不够详细,请提交 Pull Request 或联系开发组说明。"),d,(0,o.Uk)(" Bug 和功能建议请在 "),(0,o._)("a",u,[(0,o.Uk)("Issues"),(0,o.Wm)(r)]),(0,o.Uk)(" 提出。")]),(0,o._)("p",null,[(0,o._)("a",m,[(0,o.Uk)("在 Gitpod 打开已配置完成的测试环境"),(0,o.Wm)(r)])]),(0,o._)("p",null,[(0,o._)("a",c,[(0,o.Uk)("Hydro Online Judge"),(0,o.Wm)(r)])]),h,(0,o._)("p",null,[(0,o.Uk)("Email "),p,y,(0,o.Uk)(" Telegram "),(0,o._)("a",b,[(0,o.Uk)("@undefinedmoe"),(0,o.Wm)(r)]),g,(0,o.Uk)(" Hydro 用户群:1085853538")]),k,(0,o._)("p",null,[(0,o.Uk)("注2:加入用户群请先阅读"),(0,o._)("a",_,[(0,o.Uk)("《提问的智慧》"),(0,o.Wm)(r)]),(0,o.Uk)("。"),f,(0,o.Uk)(" 同时群内可能存在部分令您感到不适或感到冒犯的内容。若对此有顾虑"),H,(0,o.Uk)("。")]),U,(0,o._)("p",null,[(0,o.Uk)("若您需要对这些模块闭源处理,请考虑联系我们以购买许可。"),v,(0,o.Uk)(" 鉴于 Mirai 处的 "),(0,o._)("a",G,[(0,o.Uk)("不和谐事件"),(0,o.Wm)(r)]),(0,o.Uk)(" 对此项目做如下声明:")]),E,(0,o._)("ul",null,[(0,o._)("li",null,[(0,o._)("a",L,[(0,o.Uk)("Github"),(0,o.Wm)(r)]),(0,o.Uk)(" 为 Hydro 提供了代码托管与自动构建。")]),(0,o._)("li",null,[(0,o._)("a",x,[(0,o.Uk)("criyle"),(0,o.Wm)(r)]),(0,o.Uk)(" 提供评测沙箱实现。")]),(0,o._)("li",null,[(0,o._)("a",W,[(0,o.Uk)("Vijos"),(0,o.Wm)(r)]),(0,o.Uk)(" 为 Hydro 提供了UI框架。")])])])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const r=e.__vccOpts||e;for(const[e,o]of t)r[e]=o;return r}}}]);
\ No newline at end of file
diff --git a/assets/js/v-a08ef0ec.f3aa503a.js b/assets/js/v-a08ef0ec.f3aa503a.js
new file mode 100644
index 00000000..cd154302
--- /dev/null
+++ b/assets/js/v-a08ef0ec.f3aa503a.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[288],{2560:(s,a,e)=>{e.r(a),e.d(a,{data:()=>n});const n=JSON.parse('{"key":"v-a08ef0ec","path":"/plugins/hydrojudge.html","title":"hydrojudge","lang":"en-US","frontmatter":{"description":"您可以通过一键安装脚本快速安装独立评测机,详情请前往 部署Hydro (/docs/install/#部署) 查看。 准备 在配置评测机之前,请确认您的站点已经可以访问并正常登录/注册。 您应该预先下载您所要支持的语言的编译器,若您在配置完评测机后 升级/重新安装 了编译器,您需要重新启动沙箱。 关于编译器说明,请参照 编译器 (/docs/insta...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/hydrojudge.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"hydrojudge"}],["meta",{"property":"og:description","content":"您可以通过一键安装脚本快速安装独立评测机,详情请前往 部署Hydro (/docs/install/#部署) 查看。 准备 在配置评测机之前,请确认您的站点已经可以访问并正常登录/注册。 您应该预先下载您所要支持的语言的编译器,若您在配置完评测机后 升级/重新安装 了编译器,您需要重新启动沙箱。 关于编译器说明,请参照 编译器 (/docs/insta..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-12T12:11:12.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-12T12:11:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"hydrojudge\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-12T12:11:12.000Z\\",\\"author\\":[]}"]]},"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":2,"title":"更新","slug":"更新","link":"#更新","children":[]},{"level":2,"title":"关闭","slug":"关闭","link":"#关闭","children":[{"level":3,"title":"作为附加组件","slug":"作为附加组件-1","link":"#作为附加组件-1","children":[]},{"level":3,"title":"作为独立进程","slug":"作为独立进程-1","link":"#作为独立进程-1","children":[]}]},{"level":2,"title":"卸载","slug":"卸载","link":"#卸载","children":[]},{"level":2,"title":"评测设置","slug":"评测设置","link":"#评测设置","children":[{"level":3,"title":"作为附加组件","slug":"作为附加组件-2","link":"#作为附加组件-2","children":[]},{"level":3,"title":"作为独立进程","slug":"作为独立进程-2","link":"#作为独立进程-2","children":[]}]},{"level":2,"title":"修改编译选项/添加新语言支持","slug":"修改编译选项-添加新语言支持","link":"#修改编译选项-添加新语言支持","children":[]},{"level":2,"title":"测试数据格式","slug":"测试数据格式","link":"#测试数据格式","children":[]},{"level":2,"title":"调整沙箱空间大小","slug":"调整沙箱空间大小","link":"#调整沙箱空间大小","children":[]},{"level":2,"title":"C/C++ 彩色编译错误信息","slug":"c-c-彩色编译错误信息","link":"#c-c-彩色编译错误信息","children":[]},{"level":2,"title":"开大程序运行栈空间","slug":"开大程序运行栈空间","link":"#开大程序运行栈空间","children":[]},{"level":2,"title":"提高测评精度","slug":"提高测评精度","link":"#提高测评精度","children":[]},{"level":2,"title":"内存计量不准确","slug":"内存计量不准确","link":"#内存计量不准确","children":[]}],"git":{"createdTime":1613893902000,"updatedTime":1712923872000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":19},{"name":"undefined","email":"i@undefined.moe","commits":11},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":3},{"name":"Macesuted Kysic","email":"57275149+Macesuted@users.noreply.github.com","commits":1},{"name":"criyle","email":"gaoyang4425@gmail.com","commits":1},{"name":"代建杉","email":"wood3s@foxmail.com","commits":1}]},"readingTime":{"minutes":5.22,"words":1565},"filePathRelative":"plugins/hydrojudge.md","localizedDate":"February 21, 2021","autoDesc":true,"excerpt":""}')},8817:(s,a,e)=>{e.r(a),e.d(a,{default:()=>A});var n=e(6252);const l=(0,n._)("h1",{id:"hydrojudge",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#hydrojudge"},[(0,n._)("span",null,"hydrojudge")])],-1),o={class:"hint-container tip"},p=(0,n._)("p",{class:"hint-container-title"},"Tips",-1),r=(0,n._)("h2",{id:"准备",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#准备"},[(0,n._)("span",null,"准备")])],-1),t=(0,n._)("p",null,"在配置评测机之前,请确认您的站点已经可以访问并正常登录/注册。",-1),d=(0,n._)("p",null,[(0,n.Uk)("您应该预先下载您所要支持的语言的编译器,若您在配置完评测机后 升级/重新安装 了编译器,您需要重新启动沙箱。"),(0,n._)("br"),(0,n.Uk)(" 关于编译器说明,请参照 "),(0,n._)("a",{href:"/docs/install/compiler"},"编译器"),(0,n.Uk)(" 章节。")],-1),c=(0,n._)("br",null,null,-1),i={href:"https://github.com/criyle/go-judge/releases",target:"_blank",rel:"noopener noreferrer"},y=(0,n._)("code",null,"127.0.0.1:5050",-1),u=(0,n._)("strong",null,"以 root 权限",-1),h=(0,n.uE)('Tips
由于用附加组件安装的评测机与 Hydro 必须在同一台服务器上,每一个 Hydro 实例最多只能有一台评测机由附加组件安装。
在安装 Hydro 的机器上运行下面的指令安装 @hydrooj/hydrojudge
:
yarn global add @hydrooj/hydrojudge \nhydrooj addon add @hydrooj/hydrojudge \n
重启 Hydro 后 hydrojudge 即可正常运行。
Tips
该方法可以帮助您在任意服务器上部署评测机。
',8),E=(0,n.uE)('然后在运行评测机的服务器上安装 HydroJudge :
. <( curl https://hydro.ac/setup.sh ) --judge \n
创建目录 ~/.config/hydro
,在该目录下创建文件 judge.yaml
,配置文件格式如下:
hosts : \n localhost : \n type : hydro # vj4 用户请在此处填写 vj4 \n server_url : http://localhost/ # Hydro 运行的网址 \n uname : judge # 评测账号用户名 \n password : abc123 # 评测账号密码 \n detail : true # 默认为 true \n
设置完之后,使用下面的指令即可开始运行(可以使用 pm2 管理):
HydroJudge 会发布不定期更新。您可以使用 yarn global upgrade-interactive --latest
来检测并进行更新。
在 系统设置>hydrojudge 中有一栏 Disable builtin judge,将它勾上,然后重启 Hydro 即可。
根据开启的方法关闭即可。
关闭后运行下面指令即可。
yarn global remove @hydrooj/hydrojudge \nhydrooj addon remove @hydrooj/hydrojudge \n
在 系统设置>hydrojudge 修改对应的参数,然后重启 Hydro 和 hydrojudge 即可。
如果有需要修改单题测试点数量上限等设置,可以在 ~/.config/hydro/judge.yaml
的末尾添加下列内容:
testcases_max : 100 # 单题最多测试点数量 \ntotal_time_limit : 120 # 单题最大总测试时长 \nparallelism : 2 # 单评测机评测进程数量 \n# 更多可选配置均可添加在此处,格式与前面的三排类似 \n
',22),m={href:"https://github.com/hydro-dev/Hydro/blob/9c0afa38e3e6fa886ab9e9237847893fa6714392/packages/hydrojudge/src/config.ts#L12",target:"_blank",rel:"noopener noreferrer"},g=(0,n._)("h2",{id:"修改编译选项-添加新语言支持",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#修改编译选项-添加新语言支持"},[(0,n._)("span",null,"修改编译选项/添加新语言支持")])],-1),F=(0,n._)("p",null,[(0,n.Uk)("对于已安装内置评测机的用户(无论内置评测机是否启动),在 控制面板>系统设置 中修改 judge.langs 配置项即可;对于没有安装内置评测机的用户,需要在 "),(0,n._)("code",null,"~/.config/hydro/langs.yaml"),(0,n.Uk)(" 中配置。")],-1),b={href:"https://github.com/hydro-dev/Hydro/blob/71bb2f0b517be8f6966f97f835f2521f179b3d84/packages/hydrooj/setting.yaml#L12",target:"_blank",rel:"noopener noreferrer"},v=(0,n._)("p",null,[(0,n.Uk)("如果您添加了新的语言,您还需要前往 控制面板>系统设置 中修改 Language Highlight ID 与 Monaco language modes。"),(0,n._)("br"),(0,n.Uk)(" 分别表示选择对应的语言后的高亮设置(基于 PrismJS)和 Monaco 编辑器语法规则设置。")],-1),D=(0,n._)("p",null,"修改完后请重启 Hydro 和 hydrojudge 。",-1),f=(0,n._)("h2",{id:"测试数据格式",tabindex:"-1"},[(0,n._)("a",{class:"header-anchor",href:"#测试数据格式"},[(0,n._)("span",null,"测试数据格式")])],-1),k=(0,n.uE)('Warning
如果不调整沙箱的空间大小,当您的评测使用文件 IO 且输入输出文件较大时可能会引发错误。
对于 2022/8/12 前安装的用户:
在服务器上运行下面的代码找到 hydro-sandbox 的运行目录:
pm2 info hydro-sandbox | grep " exec cwd " \n
',5),B={href:"https://github.com/criyle/go-judge/blob/master/mount.yaml",target:"_blank",rel:"noopener noreferrer"},C=(0,n._)("code",null,"size",-1),_=(0,n._)("code",null,"nr_inodes",-1),x=(0,n.uE)('对于 2022/8/12 后安装的用户:
编辑 /root/.hydro/mount.yaml
,修改 size 即可。
确认您安装了支持彩色输出的编译器; 在系统设置中,将 C/C++ 编译命令后加上 -fdiagnostics-color=always
例:
c : \n compile : /usr/bin/gcc -O2 -Wall -std=c99 -o ${name} foo.c -lm -fdiagnostics-color=always \n
2022/8/12 后安装的实例默认已开启无限栈空间,无需手动操作
在很多时候系统默认为程序提供的栈空间并不能满足我们的需求,此时我们需要手动为用户程序提供更大的栈空间。
修改 pm2 中 hydro-sandbox 的启动参数为 ulimit -s unlimited && /usr/bin/hydro-sandbox
:
pm2 del hydro-sandbox \npm2 start bash --name hydro-sandbox -- -c " ulimit -s unlimited && hydro-sandbox " \n
禁用 CPU 频率缩放与 Intel 睿频加速技术,防止 CPU 频率波动。
禁用内存地址空间随机化,以使得存在内存寻址错误的代码能够得到更多可重复的结果,可以通过在 /etc/sysctl.conf
中添加下面这行并运行 sudo sysctl -p
应用:
kernel.randomize_va_space = 0 \n
在控制面板上出现内容为 You are using cgroup v2 without kernel 5.19+. This could result in inaccurate memory usage measurements.
警告时,意味着当前系统的内存消耗计量存在误差。
部分 Linux 设备默认使用 cgroup2,而在 5.19 版本前的内核的 cgroup2 中移除了精确计量内存消耗的接口。 若要获得更精确的内存计量,推荐启用 cgroup v1 (您可以通过检查 /sys/fs/cgroup/memory/memory.memsw.usage_in_bytes
是否存在来验证是否当前系统是否启用了 cgroup v1 ):
以 Ubuntu 的默认引导器 GRUB 2 为例,编辑 /etc/default/grub
: 在其中
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" \n
后,加入 `cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0,变为:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0" \n
运行以下命令更新 GRUB 2 的配置,然后重新启动。
',24),U={},A=(0,e(3744).Z)(U,[["render",function(s,a){const e=(0,n.up)("RouterLink"),U=(0,n.up)("ExternalLinkIcon");return(0,n.wg)(),(0,n.iD)("div",null,[l,(0,n._)("div",o,[p,(0,n._)("p",null,[(0,n.Uk)("您可以通过一键安装脚本快速安装独立评测机,详情请前往 "),(0,n.Wm)(e,{to:"/docs/install/#%E9%83%A8%E7%BD%B2"},{default:(0,n.w5)((()=>[(0,n.Uk)("部署Hydro")])),_:1}),(0,n.Uk)(" 查看。")])]),r,t,d,(0,n._)("p",null,[(0,n.Uk)("如果不使用自动脚本,您需要按照如下方式手动安装沙箱服务:"),c,(0,n.Uk)(" 前往 "),(0,n._)("a",i,[(0,n.Uk)("criyle/go-judge"),(0,n.Wm)(U)]),(0,n.Uk)(" 下载对应 cpu 架构的 go-judge。 go-judge 需要在后台运行并监听 "),y,(0,n.Uk)(" 。如果系统使用的 cgroup 版本为 1 或者使用的为非 systemd init 的发行版,请"),u,(0,n.Uk)("运行。 可使用 pm2 进行管理。")]),h,(0,n._)("p",null,[(0,n.Uk)("首先需要创建一个有 PRIV_JUDGE 权限的账户,具体方法参照 "),(0,n.Wm)(e,{to:"/docs/system/cli/#%E5%88%9B%E5%BB%BA%E8%AF%84%E6%B5%8B%E8%B4%A6%E5%8F%B7"},{default:(0,n.w5)((()=>[(0,n.Uk)("此处")])),_:1}),(0,n.Uk)("。(在部署 Hydro 的服务器上运行)")]),E,(0,n._)("p",null,[(0,n.Uk)("在 "),(0,n._)("a",m,[(0,n.Uk)("此处"),(0,n.Wm)(U)]),(0,n.Uk)(" 的设置均可添加到此处。")]),g,F,(0,n._)("p",null,[(0,n.Uk)("文件格式参照 "),(0,n._)("a",b,[(0,n.Uk)("此处"),(0,n.Wm)(U)]),(0,n.Uk)(" 。")]),v,D,f,(0,n._)("p",null,[(0,n.Uk)("参照 "),(0,n.Wm)(e,{to:"/docs/user/problem/#%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F"},{default:(0,n.w5)((()=>[(0,n.Uk)("测试数据格式")])),_:1}),(0,n.Uk)(" 配置。")]),k,(0,n._)("p",null,[(0,n.Uk)("将 "),(0,n._)("a",B,[(0,n.Uk)("mount.yaml"),(0,n.Wm)(U)]),(0,n.Uk)(" 下载并放置在 sandbox 的运行目录下。然后修改第 64 行和第 68 行的 "),C,(0,n.Uk)(" 和 "),_,(0,n.Uk)(" 的大小至您想要的大小,保存后重启 sandbox 即可完成更改。")]),x])}]])},3744:(s,a)=>{a.Z=(s,a)=>{const e=s.__vccOpts||s;for(const[s,n]of a)e[s]=n;return e}}}]);
\ No newline at end of file
diff --git a/assets/js/v-cceda784.fdb7d9d8.js b/assets/js/v-cceda784.fdb7d9d8.js
new file mode 100644
index 00000000..c4860a5e
--- /dev/null
+++ b/assets/js/v-cceda784.fdb7d9d8.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[9142],{5649:(s,a,n)=>{n.r(a),n.d(a,{data:()=>l});const l=JSON.parse('{"key":"v-cceda784","path":"/docs/system/cli.html","title":"Hydro Cli","lang":"en-US","frontmatter":{"description":"在使用 cli 之前,请完成数据库配置。 指令中使用 括起来的参数必须给出,用 [] 括起来的参数可以给出,若不给出则按照默认设置。 用户请根据自己的情况替换掉用 或是 [] 包括起来的部分(括号也应替换) cli 可以帮助用户在控制台下快捷地进行一些操作。 这些命令需要以在终端以 root 用户执行(安装时执行命令的位置)。 下面给出了一些常用的例子...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/system/cli.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"Hydro Cli"}],["meta",{"property":"og:description","content":"在使用 cli 之前,请完成数据库配置。 指令中使用 括起来的参数必须给出,用 [] 括起来的参数可以给出,若不给出则按照默认设置。 用户请根据自己的情况替换掉用 或是 [] 包括起来的部分(括号也应替换) cli 可以帮助用户在控制台下快捷地进行一些操作。 这些命令需要以在终端以 root 用户执行(安装时执行命令的位置)。 下面给出了一些常用的例子..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-05-12T03:18:30.000Z"}],["meta",{"property":"article:modified_time","content":"2023-05-12T03:18:30.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Hydro Cli\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-05-12T03:18:30.000Z\\",\\"author\\":[]}"]]},"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":[]},{"level":2,"title":"创建评测账号","slug":"创建评测账号","link":"#创建评测账号","children":[]},{"level":2,"title":"黑名单相关","slug":"黑名单相关","link":"#黑名单相关","children":[]},{"level":2,"title":"命令列表","slug":"命令列表","link":"#命令列表","children":[]}],"git":{"createdTime":1632364924000,"updatedTime":1683861510000,"contributors":[{"name":"Macesuted","email":"macesuted@qq.com","commits":1},{"name":"panda","email":"panda_dtdyy@outlook.com","commits":1},{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":2.75,"words":824},"filePathRelative":"docs/system/cli.md","localizedDate":"September 23, 2021","autoDesc":true,"excerpt":""}')},7020:(s,a,n)=>{n.r(a),n.d(a,{default:()=>y});var l=n(6252);const o=(0,l.uE)('Tips
在使用 cli 之前,请完成数据库配置。 指令中使用 <>
括起来的参数必须给出,用 []
括起来的参数可以给出,若不给出则按照默认设置。用户请根据自己的情况替换掉用 <>
或是 []
包括起来的部分(括号也应替换)
cli 可以帮助用户在控制台下快捷地进行一些操作。 这些命令需要以在终端以 root 用户执行(安装时执行命令的位置)。 下面给出了一些常用的例子。
Tips
很少使用。建议通过 控制面板>导入用户 功能代替
hydrooj cli user create < mai l > < usernam e > < passwor d > < ui d > \n# 该用户的邮箱、用户名和密码 \n \n# 如创建邮箱为 hydro@hydro.local,用户名为 Hydro,密码为 hydrohydro ,UID 为 2 的用户: \n# 请确保 UID 为不小于 2 的正整数且未被占用,邮箱和用户名均不重复。 \nhydrooj cli user create hydro@hydro.local Hydro hydrohydro 2 \n
若一切正常,运行该指令后您会从命令行窗口中看到该用户 uid。
hydrooj cli user setSuperAdmin < ui d > \n \n# 如设置 uid 为 2 的用户为管理员: \nhydrooj cli user setSuperAdmin 2 \n
hydrooj cli user setPriv < ui d > < pri v > \n
',11),p=(0,l._)("code",null,"[priv]",-1),e=(0,l.uE)('hydrooj cli user setPassword < ui d > < passwor d > \n \n# 如将 uid 为 1 的用户的密码改为 hydrohydro: \nhydrooj cli user setPassword 1 hydrohydro \n
先 创建一个账号 。
您需要留意运行此指令返回的数字,表示该用户的 uid
,需要填入下面的指令中,然后给予该账号评测权限。
hydrooj cli user setJudge < ui d > \n
完成后将配置的用户名及密码写入评测机配置文件,评测机即可连接到网页端。
用户封禁:
hydrooj cli user setPriv < ui d > 0 \n
IP/邮箱域名封禁:
# key 格式为 ip::xxx.xxx.xxx.xxx (封禁 IP 访问) 或是 mail::xxx.com (禁止 xxx.com 的邮箱注册) \nhydrooj cli blacklist add < ke y > [duration] # 将 <key> 拉入黑名单,时长为 [duration] (以月为单位的整数,默认为 12,若 duration=0 则永久封禁) \nhydrooj cli blacklist get < ke y > # 获取黑名单中有关 <key> 的信息 \nhydrooj cli blacklist del < ke y > # 将 <key> 移出黑名单 \n
',13),t={href:"https://github.com/hydro-dev/Hydro/tree/master/packages/hydrooj/src/model",target:"_blank",rel:"noopener noreferrer"},r=(0,l.uE)('这里并没有列出所有可以运行的指令,因为其中很多功能我们更推荐通过 Web 访问。
hydrooj cli user create < mai l > < unam e > < passwor d > [uid] [ regip ] [ priv ] \n# 创建邮箱为 <mail>,用户名为 <uname>,密码为 <password>,ID 为 [uid],注册 ip 为 [regip],权限为 [priv] 的用户 \nhydrooj cli user setUname < ui d > < unma e > # 将 ID 为 <uid> 的用户的用户名设置为 <uname> \nhydrooj cli user setPriv < ui d > < pri v > # 将 ID 为 <uid> 的用户的权限设为 <priv> \nhydrooj cli user setPassword < ui d > < passwor d > # 将 ID 为 <uid> 的用户的密码设置为 <password> \nhydrooj cli user setEmail < ui d > < mai l > # 将 ID 为 <uid> 的用户的邮箱设置为 <mail> \nhydrooj cli user setSuperAdmin < ui d > # 将 ID 为 <uid> 的用户设为全站管理员 \nhydrooj cli problem import < domainI d > < file/pat h > # 将 <file/path> 的Hydro格式题目包导入至 <domainId> 域中 \nhydrooj cli problem export < domainI d > # 将 <domainId> 域中的所有题目包导出 \nhydrooj cli system set < ke y > < valu e > # 修改系统设置 <key> 值为 <value> \n
',2),c={},y=(0,n(3744).Z)(c,[["render",function(s,a){const n=(0,l.up)("RouterLink"),c=(0,l.up)("ExternalLinkIcon");return(0,l.wg)(),(0,l.iD)("div",null,[o,(0,l._)("p",null,[(0,l.Uk)("关于参数 "),p,(0,l.Uk)(" ,可阅读 "),(0,l.Wm)(n,{to:"/dev/PERM_PRIV/"},{default:(0,l.w5)((()=>[(0,l.Uk)("此处")])),_:1}),(0,l.Uk)("。")]),e,(0,l._)("p",null,[(0,l.Uk)("所有于 "),(0,l._)("a",t,[(0,l.Uk)("此文件夹"),(0,l.Wm)(c)]),(0,l.Uk)(" 下的函数均可用 cli 调用。")]),r])}]])},3744:(s,a)=>{a.Z=(s,a)=>{const n=s.__vccOpts||s;for(const[s,l]of a)n[s]=l;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-d67234a8.1e5b1169.js b/assets/js/v-d67234a8.1e5b1169.js
new file mode 100644
index 00000000..49399f56
--- /dev/null
+++ b/assets/js/v-d67234a8.1e5b1169.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5895],{8857:(e,t,a)=>{a.r(t),a.d(t,{data:()=>c});const c=JSON.parse('{"key":"v-d67234a8","path":"/plugins/elastic.html","title":"Elastic search","lang":"en-US","frontmatter":{"description":"此插件需配合第三方软件 Elasticsearch 使用,如仅安装插件不配置/不安装第三方软件会导致系统无法正常运行,Elasticsearch 并非轻量化软件,如您的服务器不满足该软件要求不建议安装。 安装 Elasticsearch 后安装 @hydrooj/elastic-search 插件。 进入 HydroOJ 控制面板,在系统设置内正确填写...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/elastic.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"Elastic search"}],["meta",{"property":"og:description","content":"此插件需配合第三方软件 Elasticsearch 使用,如仅安装插件不配置/不安装第三方软件会导致系统无法正常运行,Elasticsearch 并非轻量化软件,如您的服务器不满足该软件要求不建议安装。 安装 Elasticsearch 后安装 @hydrooj/elastic-search 插件。 进入 HydroOJ 控制面板,在系统设置内正确填写..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-04-22T01:06:00.000Z"}],["meta",{"property":"article:modified_time","content":"2024-04-22T01:06:00.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Elastic search\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-04-22T01:06:00.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1665539184000,"updatedTime":1713747960000,"contributors":[{"name":"panda","email":"panda_dtdyy@outlook.com","commits":2},{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":0.47,"words":141},"filePathRelative":"plugins/elastic.md","localizedDate":"October 12, 2022","autoDesc":true,"excerpt":""}')},2299:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var c=a(6252);const r=[(0,c.uE)('Tips
此插件需配合第三方软件 Elasticsearch 使用,如仅安装插件不配置/不安装第三方软件 会导致系统无法正常运行,Elasticsearch 并非轻量化软件,如您的服务器不满足该软件要求不建议安装。
安装 Elasticsearch 后安装 @hydrooj/elastic-search
插件。
进入 HydroOJ 控制面板,在系统设置内正确填写 endpoint
。
然后在脚本管理中找到重建题目索引,点击运行,参数留空即可。
至此,搜索功能应当可以正常使用。
',6)],i={},o=(0,a(3744).Z)(i,[["render",function(e,t){return(0,c.wg)(),(0,c.iD)("div",null,r)}]])},3744:(e,t)=>{t.Z=(e,t)=>{const a=e.__vccOpts||e;for(const[e,c]of t)a[e]=c;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-dc52bc6a.f1e022c2.js b/assets/js/v-dc52bc6a.f1e022c2.js
new file mode 100644
index 00000000..c214d7b0
--- /dev/null
+++ b/assets/js/v-dc52bc6a.f1e022c2.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2132],{3231:(s,e,n)=>{n.r(e),n.d(e,{data:()=>a});const a=JSON.parse('{"key":"v-dc52bc6a","path":"/docs/user/problem-format.html","title":"Hydro Problem Format","lang":"en-US","frontmatter":{"description":"为了便于系统间进行数据交换,Hydro 定义了一种基于 zip 的标准格式用于题目传输。压缩包内文件结构如下: 其中 problem.yaml 内容如下: problem*.md 中为 markdown 格式的题面,语言代号支持完整形式(如 zhCN),也支持短形式(如 zh)。若同时存在多个语言的题面,Hydro 将会自动识别并提供切换功能。 tes...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/user/problem-format.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"Hydro Problem Format"}],["meta",{"property":"og:description","content":"为了便于系统间进行数据交换,Hydro 定义了一种基于 zip 的标准格式用于题目传输。压缩包内文件结构如下: 其中 problem.yaml 内容如下: problem*.md 中为 markdown 格式的题面,语言代号支持完整形式(如 zhCN),也支持短形式(如 zh)。若同时存在多个语言的题面,Hydro 将会自动识别并提供切换功能。 tes..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-05-19T14:49:26.000Z"}],["meta",{"property":"article:modified_time","content":"2023-05-19T14:49:26.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Hydro Problem Format\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-05-19T14:49:26.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1684507766000,"updatedTime":1684507766000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":1}]},"readingTime":{"minutes":0.78,"words":233},"filePathRelative":"docs/user/problem-format.md","localizedDate":"May 19, 2023","autoDesc":true,"excerpt":""}')},2021:(s,e,n)=>{n.r(e),n.d(e,{default:()=>p});var a=n(6252);const l=[(0,a.uE)('为了便于系统间进行数据交换,Hydro 定义了一种基于 zip 的标准格式用于题目传输。压缩包内文件结构如下:
喵? tree \n. \n├── 任意文件名的文件夹 \n│ ├── problem.yaml \n│ ├── problem_zh.md \n│ ├── testdata \n│ │ ├── config.yaml \n│ │ ├── a1.in \n│ │ ├── a1.out \n│ │ ├── a2.in \n│ │ ├── a2.out \n│ │ ├── a3.in \n│ │ └── a3.out \n│ └── additional_file \n│ ├── a.png \n│ └── b.pdf \n└── ... \n
其中 problem.yaml 内容如下:
title : 题目名 \ntag : \n- 标签1 \n- 标签2 \npid : 题号(字母+数字) \n
problem_*.md 中为 markdown 格式的题面,语言代号支持完整形式(如 zh_CN),也支持短形式(如 zh)。若同时存在多个语言的题面,Hydro 将会自动识别并提供切换功能。
testdata 文件夹中存放所有测试数据文件,命名规则和配置文件格式请参照【测试数据格式】章节。
additional_file 中存储附加文件,通常用于存放图片,PDF 等文件。这些文件可以在题面中使用 file://文件名 的路径访问。
',8)],o={},p=(0,n(3744).Z)(o,[["render",function(s,e){return(0,a.wg)(),(0,a.iD)("div",null,l)}]])},3744:(s,e)=>{e.Z=(s,e)=>{const n=s.__vccOpts||s;for(const[s,a]of e)n[s]=a;return n}}}]);
\ No newline at end of file
diff --git a/assets/js/v-fa72264c.c4725840.js b/assets/js/v-fa72264c.c4725840.js
new file mode 100644
index 00000000..98f8b586
--- /dev/null
+++ b/assets/js/v-fa72264c.c4725840.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[8886],{9758:(e,t,r)=>{r.r(t),r.d(t,{data:()=>a});const a=JSON.parse('{"key":"v-fa72264c","path":"/plugins/recaptcha.html","title":"recaptcha","lang":"en-US","frontmatter":{"description":"我们采用 reCAPTCHA v3 来检验注册者是否是人类,在注册过程中没有看见传统验证码属正常现象。 前往 创建 reCAPTCHA 密钥。 reCAPTCHA 类型请选择“reCAPTCHA 第 3 版”。 创建成功后将客户端密钥和服务端密钥分别填入系统设置 recaptcha 栏下的 key 和 secret 中,重启 Hydro 后 reCAP...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/plugins/recaptcha.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"recaptcha"}],["meta",{"property":"og:description","content":"我们采用 reCAPTCHA v3 来检验注册者是否是人类,在注册过程中没有看见传统验证码属正常现象。 前往 创建 reCAPTCHA 密钥。 reCAPTCHA 类型请选择“reCAPTCHA 第 3 版”。 创建成功后将客户端密钥和服务端密钥分别填入系统设置 recaptcha 栏下的 key 和 secret 中,重启 Hydro 后 reCAP..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2021-04-20T05:10:12.000Z"}],["meta",{"property":"article:modified_time","content":"2021-04-20T05:10:12.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"recaptcha\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2021-04-20T05:10:12.000Z\\",\\"author\\":[]}"]]},"headers":[],"git":{"createdTime":1618895412000,"updatedTime":1618895412000,"contributors":[{"name":"Macesuted","email":"57275149+Macesuted@users.noreply.github.com","commits":1}]},"readingTime":{"minutes":0.34,"words":102},"filePathRelative":"plugins/recaptcha.md","localizedDate":"April 20, 2021","autoDesc":true,"excerpt":""}')},6843:(e,t,r)=>{r.r(t),r.d(t,{default:()=>s});var a=r(6252);const c=(0,a._)("h1",{id:"recaptcha",tabindex:"-1"},[(0,a._)("a",{class:"header-anchor",href:"#recaptcha"},[(0,a._)("span",null,"recaptcha")])],-1),o=(0,a._)("div",{class:"hint-container tip"},[(0,a._)("p",{class:"hint-container-title"},"Tips"),(0,a._)("p",null,"我们采用 reCAPTCHA v3 来检验注册者是否是人类,在注册过程中没有看见传统验证码属正常现象。")],-1),n={href:"https://www.google.com/recaptcha/admin/create",target:"_blank",rel:"noopener noreferrer"},p=(0,a._)("br",null,null,-1),i=(0,a._)("p",null,[(0,a.Uk)("创建成功后将客户端密钥和服务端密钥分别填入系统设置 recaptcha 栏下的 "),(0,a._)("code",null,"key"),(0,a.Uk)(" 和 "),(0,a._)("code",null,"secret"),(0,a.Uk)(" 中,重启 Hydro 后 reCAPTCHA 即可正常工作。")],-1),l={},s=(0,r(3744).Z)(l,[["render",function(e,t){const r=(0,a.up)("ExternalLinkIcon");return(0,a.wg)(),(0,a.iD)("div",null,[c,o,(0,a._)("p",null,[(0,a.Uk)("前往 "),(0,a._)("a",n,[(0,a.Uk)("https://www.google.com/recaptcha/admin/create"),(0,a.Wm)(r)]),(0,a.Uk)(" 创建 reCAPTCHA 密钥。"),p,(0,a.Uk)(" reCAPTCHA 类型请选择“reCAPTCHA 第 3 版”。")]),i])}]])},3744:(e,t)=>{t.Z=(e,t)=>{const r=e.__vccOpts||e;for(const[e,a]of t)r[e]=a;return r}}}]);
\ No newline at end of file
diff --git a/assets/js/v-fdd5d9ea.dcd6ea9f.js b/assets/js/v-fdd5d9ea.dcd6ea9f.js
new file mode 100644
index 00000000..7fcaed77
--- /dev/null
+++ b/assets/js/v-fdd5d9ea.dcd6ea9f.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[2689],{2405:(s,n,a)=>{a.r(n),a.d(n,{data:()=>l});const l=JSON.parse('{"key":"v-fdd5d9ea","path":"/docs/install/compiler.html","title":"编译器","lang":"en-US","frontmatter":{"description":"从 2022/8/12 开始,Hydro 为了避免宿主机环境变化对于评测的影响,对于 此后新安装的实例 默认使用 nix () 管理环境。 如果你是在这之前安装的 Hydro,请使用 apt 安装编译器后使用 pm2 restart hydro-sandbox 重启沙箱,并忽略本章节。 以下是 nix 的简要操作说明: 使用 nix-env -iA n...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/install/compiler.html"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"编译器"}],["meta",{"property":"og:description","content":"从 2022/8/12 开始,Hydro 为了避免宿主机环境变化对于评测的影响,对于 此后新安装的实例 默认使用 nix () 管理环境。 如果你是在这之前安装的 Hydro,请使用 apt 安装编译器后使用 pm2 restart hydro-sandbox 重启沙箱,并忽略本章节。 以下是 nix 的简要操作说明: 使用 nix-env -iA n..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2023-02-26T07:44:01.000Z"}],["meta",{"property":"article:modified_time","content":"2023-02-26T07:44:01.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"编译器\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2023-02-26T07:44:01.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"进阶","slug":"进阶","link":"#进阶","children":[]}],"git":{"createdTime":1660293799000,"updatedTime":1677397441000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":3}]},"readingTime":{"minutes":1.98,"words":593},"filePathRelative":"docs/install/compiler.md","localizedDate":"August 12, 2022","autoDesc":true,"excerpt":""}')},3186:(s,n,a)=>{a.r(n),a.d(n,{default:()=>E});var l=a(6252);const p=(0,l.uE)('从 2022/8/12 开始,Hydro 为了避免宿主机环境变化对于评测的影响,对于 此后新安装的实例 默认使用 nix 管理环境。 如果你是在这之前安装的 Hydro,请使用 apt 安装编译器后使用 pm2 restart hydro-sandbox
重启沙箱,并忽略本章节。
以下是 nix 的简要操作说明:
使用 nix-env -iA nixpkgs.编译器名
安装新编译器,后重启沙箱 pm2 restart hydro-sandbox
生效。
',4),o={href:"https://search.nixos.org/packages",target:"_blank",rel:"noopener noreferrer"},e=(0,l._)("br",null,null,-1),r=(0,l.uE)('nix-env -iA nixpkgs.busybox nixpkgs.bash nixpkgs.diffutils nixpkgs.unzip # 基础组件,已预装,不建议删除 \nnix-env -iA nixpkgs.gcc nixpkgs.fpc # C/C++ 和 Pascal,已预装,不建议删除 \nnix-env -iA nixpkgs.ghc # Haskell \nnix-env -iA nixpkgs.rustc # Rust \nnix-env -iA nixpkgs.python2 # Python2 \nnix-env -iA nixpkgs.pythonPackages.numpy # Python2 Numpy 库 \nnix-env -iA nixpkgs.python3Minimal \nnix-env -iA nixpkgs.python3Packages.numpy \nnix-env -iA nixpkgs.php # PHP \nnix-env -iA nixpkgs.go # Golang \nnix-env -iA nixpkgs.nodejs # NodeJS \nnix-env -iA nixpkgs.openjdk_headless # Java \nnix-env -iA nixpkgs.ruby # Ruby \nnix-env -iA nixpkgs.mono # C# \nnix-env -iA nixpkgs.julia_17-bin # Julia \n
使用 nix-env -q
查看已安装的列表,后使用 nix-env -e 编译器名
即可删除对应的编译器。 请注意不要误删 Hydro 基础组件,且操作完成后需要重启沙箱 pm2 restart hydro-sandbox
生效。
如果你需要更加复杂的编译环境配置,我们建议使用编写单独的 nix 文件。
{ \n system ? builtins. currentSystem , \n pkgs ? import <nixpkgs> { system = system ; } \n}: \n \npkgs . buildEnv { \n name = " hydrojudge-rootfs " ; \n paths = with pkgs ; [ \n coreutils bash diffutils nix zip unzip gcc \n # 上方包是评测所需要的,请勿删除, \n # 在下方列出你所需要的包,查找方式同上文: \n fpc python3 rustc \n ] ; \n ignoreCollisions = true; \n pathsToLink = [ " / " ] ; \n # 导出一些基本信息和部分编译器所需的 /etc/passwd \n postBuild = '' \n mkdir $out/buildInfo \n echo 'root:x:0:0:root:/root:/bin/bash' >$out/etc/passwd \n date >$out/buildInfo/timestamp \n '' ; \n} \n
复制以上文件,保存为 default.nix
,使用 nix-build
进行构建。 构建后会产生一个 result
文件夹,记住该文件夹所在的路径。 打开 ~/.hydro/mount.yaml
将其中 /root/.nix-profile
替换为编译出的 result
文件夹(切换到新的环境) 之后保存并重启沙箱。
后续若需更改环境配置,仅需要修改 default.nix
文件之后 nix-build
重新构建,再重启沙箱即可生效。 构建过程中的缓存文件可以使用 nix-collect-garbage
进行清理。
',7),t={href:"https://nixos.org/guides/nix-language.html",target:"_blank",rel:"noopener noreferrer"},c={href:"https://nixos.org/manual/nix/stable/language/index.html",target:"_blank",rel:"noopener noreferrer"},i={},E=(0,a(3744).Z)(i,[["render",function(s,n){const a=(0,l.up)("ExternalLinkIcon");return(0,l.wg)(),(0,l.iD)("div",null,[p,(0,l._)("p",null,[(0,l.Uk)("可以在 "),(0,l._)("a",o,[(0,l.Uk)("Nixos Search"),(0,l.Wm)(a)]),(0,l.Uk)(" 中搜索你需要的编译器。"),e,(0,l.Uk)(" 以下是常用编译器的示例:")]),r,(0,l._)("p",null,[(0,l.Uk)("更详细的 nix 语言介绍,请参照 "),(0,l._)("a",t,[(0,l.Uk)("Nix Guide"),(0,l.Wm)(a)]),(0,l.Uk)(" 和 "),(0,l._)("a",c,[(0,l.Uk)("Nix Manual"),(0,l.Wm)(a)]),(0,l.Uk)("。")])])}]])},3744:(s,n)=>{n.Z=(s,n)=>{const a=s.__vccOpts||s;for(const[s,l]of n)a[s]=l;return a}}}]);
\ No newline at end of file
diff --git a/assets/js/v-fe9aee22.85842b44.js b/assets/js/v-fe9aee22.85842b44.js
new file mode 100644
index 00000000..7d263a13
--- /dev/null
+++ b/assets/js/v-fe9aee22.85842b44.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunkhydro_dev_github_io=self.webpackChunkhydro_dev_github_io||[]).push([[5872],{636:(e,n,t)=>{t.r(n),t.d(n,{data:()=>s});const s=JSON.parse('{"key":"v-fe9aee22","path":"/docs/install/","title":"部署 Hydro","lang":"en-US","frontmatter":{"description":"这里提供了几套方案帮助您建立自己的站点,请选择适合您的方案并继续。 搭建过程中如果遇到问题欢迎 联系我们 (/#联系我们) 提问。 服务器选择 不同服务商提供的 CPU 主频不同,下方数据仅供参考。 最低服务器配置: CPU: 1核 内存: 2G。(约可允许 100 人使用) 请尽量不要使用突发性能实例或共享型实例,这可能会导致评测时间计量不准确 Ce...","head":[["meta",{"property":"og:url","content":"https://hydro.js.org/docs/install/"}],["meta",{"property":"og:site_name","content":"Hydro"}],["meta",{"property":"og:title","content":"部署 Hydro"}],["meta",{"property":"og:description","content":"这里提供了几套方案帮助您建立自己的站点,请选择适合您的方案并继续。 搭建过程中如果遇到问题欢迎 联系我们 (/#联系我们) 提问。 服务器选择 不同服务商提供的 CPU 主频不同,下方数据仅供参考。 最低服务器配置: CPU: 1核 内存: 2G。(约可允许 100 人使用) 请尽量不要使用突发性能实例或共享型实例,这可能会导致评测时间计量不准确 Ce..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-18T07:19:14.000Z"}],["meta",{"property":"article:modified_time","content":"2024-01-18T07:19:14.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"部署 Hydro\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-18T07:19:14.000Z\\",\\"author\\":[]}"]]},"headers":[{"level":2,"title":"服务器选择","slug":"服务器选择","link":"#服务器选择","children":[]},{"level":2,"title":"部署","slug":"部署","link":"#部署","children":[]}],"git":{"createdTime":1620493369000,"updatedTime":1705562354000,"contributors":[{"name":"undefined","email":"i@undefined.moe","commits":23},{"name":"Macesuted","email":"macesuted@qq.com","commits":8},{"name":"代建杉","email":"wood3s@foxmail.com","commits":1}]},"readingTime":{"minutes":3.17,"words":951},"filePathRelative":"docs/install/README.md","localizedDate":"May 8, 2021","autoDesc":true,"excerpt":""}')},192:(e,n,t)=>{t.r(n),t.d(n,{default:()=>d});var s=t(6252);const a=(0,s._)("h1",{id:"部署-hydro",tabindex:"-1"},[(0,s._)("a",{class:"header-anchor",href:"#部署-hydro"},[(0,s._)("span",null,"部署 Hydro")])],-1),l=(0,s._)("br",null,null,-1),o=(0,s._)("h2",{id:"服务器选择",tabindex:"-1"},[(0,s._)("a",{class:"header-anchor",href:"#服务器选择"},[(0,s._)("span",null,"服务器选择")])],-1),i=(0,s._)("p",null,[(0,s.Uk)("不同服务商提供的 CPU 主频不同,下方数据仅供参考。"),(0,s._)("br"),(0,s.Uk)(" 最低服务器配置: CPU: 1核 内存: 2G。(约可允许 100 人使用)"),(0,s._)("br"),(0,s._)("strong",null,"请尽量不要使用突发性能实例或共享型实例,这可能会导致评测时间计量不准确")],-1),r={href:"https://www.centos.org/centos-linux-eol/",target:"_blank",rel:"noopener noreferrer"},p=(0,s.uE)('Tips
兼容大部分 Linux 发行版,推荐使用 Debian 12 / Debian 11 / Ubuntu 22.04 (教程多,成功率高,上手简单),不支持 CentOS 及其各种变种:
CentOS Alibaba Cloud Linux TencentOS OpenCloudOS 如果你的机器内存较小(<=2GiB),请避免使用 Ubuntu 22.04,它会消耗较多的内存。建议使用 Debian 12 / Debian 11。 如果你有 Linux 运维经验,Hydro 同样支持在 Alpine Linux 上运行,Alpine Linux 系统启动后仅占用 ~100M 内存,是在低配置服务器上运行的更优方案。
Warning
虚拟机用户请注意:
Hydro 使用的数据库依赖于 CPU 的 avx 指令集以提高运行性能,大部分虚拟机软件默认没有启用 avx 指令集,请参照您使用的虚拟机软件说明。 虚拟机由于非独占 CPU,会导致评测时间计量精度降低。 由于虚拟机本身的数据保存机制,突然断电很容易导致数据库损坏无法读取,请务必定期备份数据库,有条件请购买 UPS 保证供电稳定。 Docker 用户请注意:
使用安装脚本需要设置 USER
环境变量为 root
。 需要使用 --privileged
参数启动容器,否则评测机无法运行。 开发组不对 docker 部署提供技术支持。 Tips
Hydro 需要使用以下端口: 80, 443, 2019, 8888, 5050, 27017,请确保这些端口空闲。安装和安装后的所有操作均需要在 root 权限下进行!(sudo su
) 。 宝塔面板已知出现多次高危漏洞,为防止数据丢失,请不要在生产环境中使用!
运行下面的脚本,等待几分钟即可(建议复制防止敲错):
LANG = zh . <( curl https://hydro.ac/setup.sh ) \n
Tips
如果有特殊需求,安装脚本支持一些可选的高级选项,以此方式调用: . <(curl https://hydro.ac/setup.sh) --foo --bar
--no-caddy 不配置安装反向代理,只监听8888端口 --judge 仅作为独立评测机安装 阿里云/腾讯云/华为云等等用户安装后如果不能访问 请百度搜索 xx云 放行80端口
脚本默认使用的为清华大学镜像。 安装完成后,从 http://服务器ip/
访问网页端,注册一个账号,之后在终端中使用
hydrooj cli user setSuperAdmin 2 \n
将首个注册用户设置为超级管理员。之后刷新页面,您应当能在上方导航栏看到控制面板入口。 进入控制面板,右侧系统设置,验证管理员密码后按需修改配置,注意 Server BaseURL 一项需要填写访问网站用的完整的 URL,以 /
结尾。(重要,务必正确填写,样例:https://hydro.ac/
)
系统安装后需要题库,可前往 https://hydro.ac/d/tk/p 免费专区进行下载,支持批量导入。 至此,基础功能安装已全部完成,另,如果你的服务部署在内网,且希望外网的用户可以访问,可以百度搜索 “端口映射” 相关教程。
',11),c={},d=(0,t(3744).Z)(c,[["render",function(e,n){const t=(0,s.up)("RouterLink"),c=(0,s.up)("ExternalLinkIcon");return(0,s.wg)(),(0,s.iD)("div",null,[a,(0,s._)("p",null,[(0,s.Uk)("这里提供了几套方案帮助您建立自己的站点,请选择适合您的方案并继续。"),l,(0,s.Uk)(" 搭建过程中如果遇到问题欢迎 "),(0,s.Wm)(t,{to:"/#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC"},{default:(0,s.w5)((()=>[(0,s.Uk)("联系我们")])),_:1}),(0,s.Uk)(" 提问。")]),o,i,(0,s._)("p",null,[(0,s.Uk)("CentOS 8 "),(0,s._)("a",r,[(0,s.Uk)("已于 2021-12-31 停止支持"),(0,s.Wm)(c)]),(0,s.Uk)(",后续不会为安全漏洞发布补丁,建议重装为其他操作系统。")]),p])}]])},3744:(e,n)=>{n.Z=(e,n)=>{const t=e.__vccOpts||e;for(const[e,s]of n)t[e]=s;return t}}}]);
\ No newline at end of file
diff --git a/dev/PERM_PRIV.html b/dev/PERM_PRIV.html
new file mode 100644
index 00000000..248611eb
--- /dev/null
+++ b/dev/PERM_PRIV.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 权限节点 | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/dev/db-layout.html b/dev/db-layout.html
new file mode 100644
index 00000000..b168e73c
--- /dev/null
+++ b/dev/db-layout.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 数据库结构 | Hydro
+
+
+
+
+
+ Skip to main content
数据库结构 基础列:(domainId, docId, docType), owner, title, content 存储所有文档,包括题目,比赛,训练等等,使用 docType 字段区分文档类型,docType 的定义可参照 packages/hydrooj/src/model/document.ts 。
基础列:(domainId, docId, docType, uid), owner, title, content 存储用户在对应文档下留下的信息,如题目的提交状态,比赛的成绩等等。
基础列:((_id), domainId), uid, code, lang, score, status 存储用户的提交记录。
基础列:(_id), uname, unameLower, mail, mailLower, priv 在系统中的所有用户。
存储系统日志。
用于提交队列等。
用于处理 Hydro 的内部事件通讯,请勿手动操作。
定时任务相关。
用于记录用户的访问情况,作频率限制用
存储临时信息,如登陆状态,注册验证码等
Prev
命名规则
Next
权限节点
+
+
+
diff --git a/dev/frontend-modify.html b/dev/frontend-modify.html
new file mode 100644
index 00000000..00ca6333
--- /dev/null
+++ b/dev/frontend-modify.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 前端修改 | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/dev/hook.html b/dev/hook.html
new file mode 100644
index 00000000..621b606b
--- /dev/null
+++ b/dev/hook.html
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+ 使用 TypeScript 编写插件 | Hydro
+
+
+
+
+
+ Skip to main content
使用 TypeScript 编写插件 请注意:在阅读本节之前,请确认您已阅读【使用 TypeScript 编写插件】一节并已完成了插件的创建。
import { Context , Time } from ' hydrooj ' ;
+
+export async function apply ( ctx : Context ) {
+ // handler 表示路由事件
+ // after 表示在主逻辑完成后运行,同时支持 before, before-operation, 参照 【插件编写】 章节 【请求流程】
+ // RecordDetail 为需要捕获的路由名
+ // #get 表示仅捕获 GET 请求,若无此后缀表示捕获该路由的所有请求
+ ctx . on ( ' handler/after/RecordDetail#get ' , ( h ) => { // handler 系列钩子的一参数为对应的 Handler 实例
+ // 不允许查看 24 小时以前的提交记录
+ if ( h . rdoc . _id . getTimestamp () < new Date ( Date . now () - Time . day )) {
+ h . rdoc . code = '' ;
+ }
+ } ) ;
+}
+
import { Context } from ' hydrooj ' ;
+
+async function getAnnounce ( domainId : string , limit = 5 ) {
+ // 获取公告...
+ return adocs ;
+}
+
+export async function apply ( ctx : Context ) {
+ ctx . withHandlerClass ( ' HomeHandler ' , ( HomeHandler ) => {
+ // 修改 HomeHandler 中的一个方法(添加公告)
+ HomeHandler . prototype . getAnnounce = getAnnounce ;
+ } ) ;
+}
+
Prev
使用 TypeScript 编写插件
Next
前端修改
+
+
+
diff --git a/dev/index.html b/dev/index.html
new file mode 100644
index 00000000..8801fdce
--- /dev/null
+++ b/dev/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+ 开发环境部署 | Hydro
+
+
+
+
+
+ Skip to main content
开发环境部署 开发环境仅适合需要进行大量深度修改或希望贡献代码的用户。 如果您没有过 TypeScript 项目的开发经验,非常不建议自建开发环境,请基于插件系统进行你所需要的功能添加与修改。 使用自动脚本安装也可以基于插件系统完成大部分的定制需求(参照左侧【使用 TypeScript 编写插件】章节)。 如果您需要编译 UI,请确认您的开发环境至少拥有 8GB 内存。
功能对比 生产模式 开发模式 快速起步 ✅ ❌ 插件 API ✅ ✅ 底层代码修改 ❌ ✅ 热重载 ❌ ✅ 性能优化 ✅ ❌ 兼容性 ✅ ❌ 技术支持 ✅ ❌ 部署难度 简单 复杂 升级 简单 复杂 技能要求 低 高 空闲内存要求 2G 8G 可切换至开发模式 是 = 可切换至生产模式 = 需重写代码
Tips
使用开发环境默认您有良好的国际互联网连接。以下报错信息均为网络问题导致,您可以尝试换源/使用代理/切换网络环境。
Failed to connect Connection reset connect timeout 开发组不会为您解决任何网络问题。
在开发之前,请务必确认您使用了支持 TypeScript 的 IDE 环境,这可以极大降低开发难度。
系统要求:Hydro开发环境目前仅支持 Linux 系统,如您使用 Windows 请使用 WSL2 。 MongoDB:Hydro 需要 MongoDBopen in new window 提供数据库服务。 NodeJS:请安装 NodeJS >=18 版本。(若使用 apt 请使用 nodesource 提供的源替代官方源) (推荐使用 nix ,可通过. <(curl https://hydro.ac/nix.sh)
快速安装) yarn:安装 yarn 前请先完成 NodeJS 安装。 nix-env -iA nixpkgs.yarn
或 npm install -g yarn
若需要使用 hydrojudge 请参照 hydrojudge 插件说明部分完成沙箱的安装配置。 git clone https://github.com/hydro-dev/Hydro.git /root/Hydro --recursive # 下载至 /root/Hydro 文件夹
+cd /root/Hydro # 进入工作目录
+yarn # 安装依赖包
+yarn build:ui:production # 编译前端
+
开发环境部署完成后默认不启用任何插件。
所有官方插件均随源码仓库下载到安装文件夹的 packages
子文件夹下,可以通过下面的命令启用官方插件(以启用 @hydrooj/ui-default
为例):
yarn hydrooj addon add @hydrooj/ui-default
+
对于非官方插件,下载后通过下面的命令启用即可(以启用位置在 /root/addon
下的插件为例):
yarn hydrooj addon add /root/addon
+
支持如下启动参数:
--port=2333
指定启动端口--debug
启用开发模式--watch
启用热重载(实验性)使用 yarn debug --port=2333 --watch
启动 Hydro,并在后台运行 yarn build:ui:dev
,可以对前端源码进行实时转译,在反复修改时可节省编译时间。启动完成后,您可以在 8000 端口访问到 Hydro 实例,且前端的任何更改将即时生效。(后端热重载可能存在 bug,部分模块修改后可能仍需重启才能生效) 请注意:此功能仅在启用了 @hydrooj/ui-default
插件的情况下才会生效。
首次启动会要求您填写数据库连接信息。请根据您数据库的安装填写(若无密码则留空) 请按照下文说明创建管理员账户即可正常使用。
需要更新的时候进入对应仓库文件夹执行 git pull
,然后重新 yarn && yarn build:ui:production
即可。
Next
命名规则
+
+
+
diff --git a/dev/naming.html b/dev/naming.html
new file mode 100644
index 00000000..a58ce3b4
--- /dev/null
+++ b/dev/naming.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 命名规则 | Hydro
+
+
+
+
+
+ Skip to main content
命名规则 在 Hydro 中的大部分变量有固定命名规则:
pdoc: 题目 tdoc: 比赛/作业/训练 rdoc: 提交记录 ddoc: 讨论 drdoc: 讨论的回复 drrdoc: 讨论的二级回复 mdoc: 站内信息 psdoc: 题目的提交状态 tsdoc: 比赛/作业的提交状态 ... 以及它们的变种:
pdocs: 包含若干题目的数组 pdict: 键为题目 id,题目详情为值的对象 ... 更多细节可在 packages/hydrooj/src/interface.ts 中找到。
get()
获取内容,返回对应值或 nullgetList()
获取内容,返回 dict 类对象getMulti()
获取数据库查询的指针edit()
更新内容 Prev
开发环境部署
Next
数据库结构
+
+
+
diff --git a/dev/third-party-auth.html b/dev/third-party-auth.html
new file mode 100644
index 00000000..62ebd130
--- /dev/null
+++ b/dev/third-party-auth.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+ 接入第三方账号系统 | Hydro
+
+
+
+
+
+ Skip to main content
接入第三方账号系统 Hydro 支持接入第三方的账号系统,并且有以下内置模块可用:
@hydrooj/login-with-github @hydrooj/login-with-google 在阅读本节之前,请确保你已阅读 【插件开发】 章节。
以 Github 登录为例:
import {
+ Context , ForbiddenError , Handler , superagent , SystemModel ,
+ TokenModel , UserFacingError , ValidationError ,
+} from ' hydrooj ' ;
+
+declare module ' hydrooj ' {
+ interface SystemKeys {
+ ' login-with-github.id ' : string ;
+ ' login-with-github.secret ' : string ;
+ ' login-with-github.endpoint ' : string ;
+ }
+}
+
+// 当用户点击 【使用 XX 登录】 按钮时,此函数会被执行
+async function get ( this: Handler ) {
+ // 从系统设置中获取基础设置,并储存状态信息(完成登录逻辑后应该跳转到哪一页)
+ const [ appid , [ state ]] = await Promise . all ([
+ SystemModel . get ( ' login-with-github.id ' ) ,
+ TokenModel . add ( TokenModel . TYPE_OAUTH , 600 , { redirect : this . request . referer } ) ,
+ ]) ;
+ // 将用户重定向至第三方平台请求授权。
+ this . response . redirect = ` https://github.com/login/oauth/authorize?client_id= ${ appid } &state= ${ state } &scope=read:user,user:email ` ;
+}
+
+// 当用户在三方系统中完成授权,需要重定向到 /oauth/xxx/callback,这时所有返回的参数作为 callback 的一参数传入。
+async function callback ({ state , code }) {
+ // 获取系统设置和之前的状态。
+ const [[ appid , secret , endpoint , url ], s ] = await Promise . all ([
+ SystemModel . getMany ([
+ ' login-with-github.id ' ,
+ ' login-with-github.secret ' ,
+ ' login-with-github.endpoint ' ,
+ ' server.url ' ,
+ ]) ,
+ TokenModel . get ( state , TokenModel . TYPE_OAUTH ) ,
+ ]) ;
+ if ( ! s ) throw new ValidationError ( ' token ' ) ;
+ // 使用从 url 中返回的 token 请求第三方的 API,获取用户信息,作为函数返回。
+ // 在 OAuth 协议中,需要使用 state 和 code 换取 access_token 再调用 API,这在不同系统中可能设计不同。
+ // 系统会根据返回的用户信息自动查找已有用户或是创建新用户。
+ const res = await superagent . post ( `${ endpoint || ' https://github.com '} /login/oauth/access_token ` )
+ . send ( {
+ client_id : appid ,
+ client_secret : secret ,
+ code ,
+ redirect_uri : `${ url } oauth/github/callback ` ,
+ state ,
+ } )
+ . set ( ' accept ' , ' application/json ' ) ;
+ if ( res . body . error ) {
+ throw new UserFacingError (
+ res . body . error , res . body . error_description , res . body . error_uri ,
+ ) ;
+ }
+ const t = res . body . access_token ;
+ const userInfo = await superagent . get ( `${ endpoint ? `${ endpoint } /api ` : ' https://api.github.com '} /user ` )
+ . set ( ' User-Agent ' , ' Hydro-OAuth ' )
+ . set ( ' Accept ' , ' application/vnd.github.v3+json ' )
+ . set ( ' Authorization ' , ` token ${ t }` ) ;
+ const ret = {
+ _id : `${ userInfo . body . id } @github.local ` ,
+ email : userInfo . body . email ,
+ bio : userInfo . body . bio ,
+ // 提供多个用户名,若需创建用户则从前往后尝试,直到用户名可用
+ uname : [ userInfo . body . name , userInfo . body . login ] . filter ( ( i ) => i ) ,
+ avatar : ` github: ${ userInfo . body . login }` ,
+ } ;
+ await TokenModel . del ( s . _id , TokenModel . TYPE_OAUTH ) ;
+ if ( ! ret . email ) throw new ForbiddenError ( " You don't have a verified email. " ) ;
+ return ret ;
+}
+
+// 注册此模块。
+export function apply ( ctx : Context ) {
+ ctx . provideModule ( ' oauth ' , ' github ' , {
+ text : ' Login with Github ' ,
+ callback ,
+ get ,
+ } ) ;
+ ctx . i18n . load ( ' zh ' , {
+ ' Login With Github ' : ' 使用 Github 登录 ' ,
+ } ) ;
+}
+
Prev
前端修改
+
+
+
diff --git a/dev/typescript.html b/dev/typescript.html
new file mode 100644
index 00000000..7512c982
--- /dev/null
+++ b/dev/typescript.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+ 使用 TypeScript 编写插件 | Hydro
+
+
+
+
+
+ Skip to main content
使用 TypeScript 编写插件 前置条件:NodeJS>=18 此教程将以编写剪贴板插件为例进行说明。
使用 hydrooj addon create
快速在 /root/addon
下初始化一个插件或是在一个空文件夹中运行 yarn init
并按照提示填写相关信息。
# 使用 yarn init 的样例
+/workspace/hydro-plugin $ yarn init
+yarn init v1.22.4
+question name (hydro-plugin): @hydrooj/pastebin
+question version (1.0.0): 0.0.1
+question description: HydroOJ的剪贴板组件
+question entry point (index.js): index.ts
+question repository url: https://github.com/hydro-dev/pastebin.git
+question author: undefined < i@undefined.mo e >
+question license (MIT): MIT
+question private:
+success Saved package.json
+
有时我们希望使用本机的 IDE 编写插件上传到服务器(我们也推荐这么做,编辑器提供的代码补全可以很大程度简化开发流程),可以进行如下操作:
在本机安装 NodeJS 和 yarn 。 参照步骤 1 使用 yarn init
创建一个项目。 使用 VSCode 打开插件文件夹。 使用 yarn add hydrooj -D
安装相关开发组件。 参照下文进行插件开发工作 将本地的文件夹上传至服务器,并使用 hydrooj addon add 插件绝对路径
启用上传的插件。 分析:剪贴板组件需要以下功能:
与数据库交互来存储/检索相应文档。 提供 /paste/create 路由以创建新文档。 提供 /paste/show/:ID 来查看已创建的文档。 根据用户ID进行鉴权,允许将文档设置为私密以防止他人查看。 在路由中定义所有的函数应均为异步函数,支持的函数有:prepare, get, post, post[Operation], cleanup 具体流程如下:
先执行 prepare(args) (如果存在)
+args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数,
+再执行 prepare(args) (如果存在)
+检查请求类型:
+
+为 GET ?
+ -> 执行 get(args)
+为 POST ?
+ -> 执行 post(args)
+ -> 含有 operation 字段?
+ -> 执行 post[Operation]
+
+执行 cleanup()
+
如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。
在表单提交时的 operation 字段使用下划线,函数名使用驼峰命名。 如 <input type="hidden" name="operation" value="confirm_delete">
对应 postConfirmDelete
函数。
应当提供 apply
函数,并与定义的 Handler 一同挂载到 global.Hydro.handler[模块名]
位置。 apply
函数将在初始化阶段被调用。
// @noErrors
+// @module: esnext
+// @filename: index.ts
+import {
+ db , definePlugin , Handler , NotFoundError , param , PermissionError , PRIV , Types ,
+} from ' hydrooj ' ;
+
+const coll = db . collection ( ' paste ' ) ;
+
+interface Paste {
+ _id : string ;
+ owner : number ;
+ content : string ;
+ isPrivate : boolean ;
+}
+
+declare module ' hydrooj ' {
+ interface Model {
+ pastebin : typeof pastebinModel ;
+ }
+ interface Collections {
+ paste : Paste ; // 声明数据表类型
+ }
+}
+
+async function add ( userId : number , content : string , isPrivate : boolean ) : Promise < string > {
+ const pasteId = String . random ( 16 ) ; // Hydro 提供了此方法,创建一个长度为16的随机字符串
+ // 使用 mongodb 为数据库驱动,相关操作参照其文档
+ const result = await coll . insertOne ( {
+ _id : pasteId ,
+ owner : userId ,
+ content ,
+ isPrivate ,
+ } ) ;
+ return result . insertedId ; // 返回插入的文档ID
+}
+
+async function get ( pasteId : string ) : Promise < Paste > {
+ return await coll . findOne ( { _id : pasteId } ) ;
+}
+
+// 暴露这些接口,使得 cli 也能够正常调用这些函数;
+const pastebinModel = { add , get } ;
+global . Hydro . model . pastebin = pastebinModel ;
+
+// 创建新路由
+class PasteCreateHandler extends Handler {
+ // Get请求时触发该函数
+ async get () {
+ // 检查用户是否登录,此处为多余(因为底部注册路由时已声明所需权限)
+ // 此方法适用于权限的动态检查
+ // this.checkPriv(PRIV.PRIV_USER_PROFILE);
+ this . response . template = ' paste_create.html ' ; // 返回此页面
+ }
+
+ // 使用 Types.Content 检查输入
+ @param ( ' content ' , Types . Content )
+ @param ( ' private ' , Types . Boolean )
+ // 从用户提交的表单中取出content和private字段
+ // domainId 为固定传入参数
+ async post ( domainId : string , content : string , isPrivate = false ) {
+ // 在HTML表单提交的多选框中,选中值为 'on',未选中则为空,需要进行转换
+ const pasteid = await pastebinModel . add ( this . user . _id , content , !! isPrivate ) ;
+ // 将用户重定向到创建完成的url
+ this . response . redirect = this . url ( ' paste_show ' , { id : pasteid } ) ;
+ // 相应的,提供了 this.back() 方法用于将用户重定向至前一个地址(通常用于 Ajax 或是部分更新操作)
+ }
+}
+
+class PasteShowHandler extends Handler {
+ @param ( ' id ' , Types . String )
+ async get ( domainId : string , id : string ) {
+ const doc = await pastebin . get ( id ) ;
+ if ( ! doc ) throw new NotFoundError ( id ) ;
+ if ( doc . isPrivate && this . user . _id !== doc . owner ) {
+ throw new PermissionError () ;
+ }
+ this . response . body = { doc } ;
+ this . response . template = ' paste_show.html ' ;
+ }
+
+ @param ( ' id ' , Types . String )
+ async postDelete ( domainId : string , id : string ) {
+ // 当提交表单并存在 operation 值为 delete 时执行。
+ // 本例中未实现删除功能,仅作为说明。
+ }
+}
+
+// Hydro会在服务初始化完成后调用该函数。
+export async function apply () {
+ // 注册一个名为 paste_create 的路由,匹配 '/paste/create',
+ // 使用PasteCreateHandler处理,访问改路由需要PRIV.PRIV_USER_PROFILE权限
+ // 提示:路由匹配基于 path-to-regexp
+ ctx . Route ( ' paste_create ' , ' /paste/create ' , PasteCreateHandler , PRIV . PRIV_USER_PROFILE ) ;
+ ctx . Route ( ' paste_show ' , ' /paste/show/:id ' , PasteShowHandler ) ;
+}
+
+
模板采用 nunjucks 语法。放置于 templates/
文件夹下。 会在请求结束时根据 response.template
的值选择模板,并使用 response.body
的值进行渲染,存入 response.body
中。 若 response.template
为空或 request.headers['accept'] == 'application/json'
,则跳过渲染步骤。
用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。
Prev
权限节点
Next
使用 TypeScript 编写插件
+
+
+
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 00000000..aa6b094f
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+ 介绍 | Hydro
+
+
+
+
+
+ Skip to main content
介绍 为什么使用 Hydro?
安全:使用 Linux 容器技术(只读文件系统,命名空间和 cgroup )进行隔离,杜绝卡评测;
高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;
扩展:Hydro 支持安装额外模块进行扩展;
强大:配合 Judge 模块(或 HydroJudge 独立评测机),可支持 spj,交互题,提交答案题,文件IO 等多种特性;
自定:所有权限节点均可自由设置;
易上手:无需改动源代码,系统设置中预留了大量可自行修改的内容;管理逻辑简洁;
社区:Hydro 正在持续维护中;
如果您正在使用 HustOJ,可以导出题目为 FPS 文件后使用 fps-importer 插件 直接导入 Hydro。
如果您正在使用 QDUOJ, 可以导出题目为 QDUOJ-zip 格式后使用 import-qduoj 插件直接导入 Hydro。
如果您正在使用 Vijos / SYZOJ / HustOJ / UniversalOJ, 可以直接使用 migrate 插件 导入所有数据至 Hydro。
Hydro 支持很多其他系统无法支持的题型,可在 https://hydro.ac/d/system_test/p 中查看并免费下载使用样例。(需要登录) 下方对比了 Hydro 与其他主流 OJ 系统的功能。(只进行在不修改源代码情况下的对比)
+:支持
+=:部分支持
+?: 未知
+-:不支持
+
功能 Hydro HustOJ SYZOJ QDUOJ Vijos 安装 一键脚本 一键脚本 手动搭建 docker docker 数据库 MongoDB MySQL MariaDB Postgres MongoDB 测试数据存储 本地/S3 本地 本地 本地 数据库 多评测机 + = = = + 测试数据同步 按需抓取 全量同步 全量同步 全量同步 按需抓取 比赛 ACM/OI/IOI/乐多 ACM/OI ACM/OI/IOI ACM/OI/IOI ACM/OI 封榜 + + - - - 作业功能 + + - - + 修改编译命令/添加语言 + = - - + 权限系统 + = - - + 训练计划(题单) + + - - + 团队 + - - - + Hack + - - - - SpecialJudge + + + - = Subtask + - + - - 交互题 + - + - - RemoteJudge CF/SPOJ/UOJ/POJ/Luogu HDU/PKU - - - 题目导入 fps/syzoj/qduoj/hydro fps/qduoj syzoj fps/qduoj -
点击 部署 ,开始部署您的 OJ 吧!
+
+
+
diff --git a/docs/install/compiler.html b/docs/install/compiler.html
new file mode 100644
index 00000000..8b11cbcd
--- /dev/null
+++ b/docs/install/compiler.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+ 编译器 | Hydro
+
+
+
+
+
+ Skip to main content
编译器 从 2022/8/12 开始,Hydro 为了避免宿主机环境变化对于评测的影响,对于 此后新安装的实例 默认使用 nix 管理环境。 如果你是在这之前安装的 Hydro,请使用 apt 安装编译器后使用 pm2 restart hydro-sandbox
重启沙箱,并忽略本章节。
以下是 nix 的简要操作说明:
使用 nix-env -iA nixpkgs.编译器名
安装新编译器,后重启沙箱 pm2 restart hydro-sandbox
生效。
可以在 Nixos Searchopen in new window 中搜索你需要的编译器。 以下是常用编译器的示例:
nix-env -iA nixpkgs.busybox nixpkgs.bash nixpkgs.diffutils nixpkgs.unzip # 基础组件,已预装,不建议删除
+nix-env -iA nixpkgs.gcc nixpkgs.fpc # C/C++ 和 Pascal,已预装,不建议删除
+nix-env -iA nixpkgs.ghc # Haskell
+nix-env -iA nixpkgs.rustc # Rust
+nix-env -iA nixpkgs.python2 # Python2
+nix-env -iA nixpkgs.pythonPackages.numpy # Python2 Numpy 库
+nix-env -iA nixpkgs.python3Minimal
+nix-env -iA nixpkgs.python3Packages.numpy
+nix-env -iA nixpkgs.php # PHP
+nix-env -iA nixpkgs.go # Golang
+nix-env -iA nixpkgs.nodejs # NodeJS
+nix-env -iA nixpkgs.openjdk_headless # Java
+nix-env -iA nixpkgs.ruby # Ruby
+nix-env -iA nixpkgs.mono # C#
+nix-env -iA nixpkgs.julia_17-bin # Julia
+
使用 nix-env -q
查看已安装的列表,后使用 nix-env -e 编译器名
即可删除对应的编译器。 请注意不要误删 Hydro 基础组件,且操作完成后需要重启沙箱 pm2 restart hydro-sandbox
生效。
如果你需要更加复杂的编译环境配置,我们建议使用编写单独的 nix 文件。
{
+ system ? builtins. currentSystem ,
+ pkgs ? import <nixpkgs> { system = system ; }
+}:
+
+pkgs . buildEnv {
+ name = " hydrojudge-rootfs " ;
+ paths = with pkgs ; [
+ coreutils bash diffutils nix zip unzip gcc
+ # 上方包是评测所需要的,请勿删除,
+ # 在下方列出你所需要的包,查找方式同上文:
+ fpc python3 rustc
+ ] ;
+ ignoreCollisions = true;
+ pathsToLink = [ " / " ] ;
+ # 导出一些基本信息和部分编译器所需的 /etc/passwd
+ postBuild = ''
+ mkdir $out/buildInfo
+ echo 'root:x:0:0:root:/root:/bin/bash' >$out/etc/passwd
+ date >$out/buildInfo/timestamp
+ '' ;
+}
+
复制以上文件,保存为 default.nix
,使用 nix-build
进行构建。 构建后会产生一个 result
文件夹,记住该文件夹所在的路径。 打开 ~/.hydro/mount.yaml
将其中 /root/.nix-profile
替换为编译出的 result
文件夹(切换到新的环境) 之后保存并重启沙箱。
后续若需更改环境配置,仅需要修改 default.nix
文件之后 nix-build
重新构建,再重启沙箱即可生效。 构建过程中的缓存文件可以使用 nix-collect-garbage
进行清理。
更详细的 nix 语言介绍,请参照 Nix Guideopen in new window 和 Nix Manualopen in new window 。
Prev
反向代理 / SSL 配置
+
+
+
diff --git a/docs/install/index.html b/docs/install/index.html
new file mode 100644
index 00000000..50109a37
--- /dev/null
+++ b/docs/install/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+ 部署 Hydro | Hydro
+
+
+
+
+
+ Skip to main content
部署 Hydro 这里提供了几套方案帮助您建立自己的站点,请选择适合您的方案并继续。 搭建过程中如果遇到问题欢迎 联系我们 提问。
不同服务商提供的 CPU 主频不同,下方数据仅供参考。 最低服务器配置: CPU: 1核 内存: 2G。(约可允许 100 人使用)请尽量不要使用突发性能实例或共享型实例,这可能会导致评测时间计量不准确
CentOS 8 已于 2021-12-31 停止支持open in new window ,后续不会为安全漏洞发布补丁,建议重装为其他操作系统。
Tips
兼容大部分 Linux 发行版,推荐使用 Debian 12 / Debian 11 / Ubuntu 22.04 (教程多,成功率高,上手简单),不支持 CentOS 及其各种变种:
CentOS Alibaba Cloud Linux TencentOS OpenCloudOS 如果你的机器内存较小(<=2GiB),请避免使用 Ubuntu 22.04,它会消耗较多的内存。建议使用 Debian 12 / Debian 11。 如果你有 Linux 运维经验,Hydro 同样支持在 Alpine Linux 上运行,Alpine Linux 系统启动后仅占用 ~100M 内存,是在低配置服务器上运行的更优方案。
Warning
虚拟机用户请注意:
Hydro 使用的数据库依赖于 CPU 的 avx 指令集以提高运行性能,大部分虚拟机软件默认没有启用 avx 指令集,请参照您使用的虚拟机软件说明。 虚拟机由于非独占 CPU,会导致评测时间计量精度降低。 由于虚拟机本身的数据保存机制,突然断电很容易导致数据库损坏无法读取,请务必定期备份数据库,有条件请购买 UPS 保证供电稳定。 Docker 用户请注意:
使用安装脚本需要设置 USER
环境变量为 root
。 需要使用 --privileged
参数启动容器,否则评测机无法运行。 开发组不对 docker 部署提供技术支持。 Tips
Hydro 需要使用以下端口: 80, 443, 2019, 8888, 5050, 27017,请确保这些端口空闲。安装和安装后的所有操作均需要在 root 权限下进行!(sudo su
) 。 宝塔面板已知出现多次高危漏洞,为防止数据丢失,请不要在生产环境中使用!
运行下面的脚本,等待几分钟即可(建议复制防止敲错):
LANG = zh . <( curl https://hydro.ac/setup.sh )
+
Tips
如果有特殊需求,安装脚本支持一些可选的高级选项,以此方式调用: . <(curl https://hydro.ac/setup.sh) --foo --bar
--no-caddy 不配置安装反向代理,只监听8888端口 --judge 仅作为独立评测机安装 阿里云/腾讯云/华为云等等用户安装后如果不能访问 请百度搜索 xx云 放行80端口
脚本默认使用的为清华大学镜像。 安装完成后,从 http://服务器ip/
访问网页端,注册一个账号,之后在终端中使用
hydrooj cli user setSuperAdmin 2
+
将首个注册用户设置为超级管理员。之后刷新页面,您应当能在上方导航栏看到控制面板入口。 进入控制面板,右侧系统设置,验证管理员密码后按需修改配置,注意 Server BaseURL 一项需要填写访问网站用的完整的 URL,以 /
结尾。(重要,务必正确填写,样例:https://hydro.ac/
)
系统安装后需要题库,可前往 https://hydro.ac/d/tk/p 免费专区进行下载,支持批量导入。 至此,基础功能安装已全部完成,另,如果你的服务部署在内网,且希望外网的用户可以访问,可以百度搜索 “端口映射” 相关教程。
Next
存储
+
+
+
diff --git a/docs/install/proxy.html b/docs/install/proxy.html
new file mode 100644
index 00000000..6a3a49de
--- /dev/null
+++ b/docs/install/proxy.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+ 反向代理 / SSL 配置 | Hydro
+
+
+
+
+
+ Skip to main content
反向代理 / SSL 配置 Warning
若使用反向代理,请注意系统设置中的 server.xff 和 server.xhost 设置项需要填写正确(小写),分别对应反向代理所添加的标头名(通常为 x-forwarded-for 和 x-forwarded-host,部分反代工具会使用 x-real-ip 替代 x-forwarded-for)。 server.xhost 设置项配置错误会导致用户无法登录等问题。(CsrfTokenError) server.xff 设置项配置错误会导致无法记录用户IP。
除一键安装脚本在安装 Caddy 后会自动配置设置项,其他工具请在使用工具前先配置好系统设置!否则将造成用户无法登录、无法记录用户IP等问题。
若您使用 Nginx,请注意配置 WebSocket 协议的反向代理,否则会导致评测状态无法自动刷新,在线 IDE 无法正常使用等问题。
Hydro 支持使用 Caddy, HaProxy 等工具进行反向代理,此处open in new window 提供了一些配置样例。
Hydro 推荐您使用 Caddyopen in new window 。以下为样例 Caddyfile。 提示:如果您的服务器位于国内,则需要进行备案后才能使用 80 和 443 端口。
hydro.ac {
+ log {
+ output file /data/access.log {
+ roll_size 1gb
+ roll_keep_for 72h
+ }
+ format json
+ }
+ root * /root/.hydro/static
+ @static {
+ file {
+ try_files {path}
+ }
+ }
+ handle @static {
+ file_server
+ }
+ handle {
+ reverse_proxy http://127.0.0.1:8888
+ }
+}
+
Prev
存储
Next
编译器
+
+
+
diff --git a/docs/install/s3.html b/docs/install/s3.html
new file mode 100644
index 00000000..c906a55c
--- /dev/null
+++ b/docs/install/s3.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 存储 | Hydro
+
+
+
+
+
+ Skip to main content
存储 Tips
使用一键安装脚本部署的 Hydro 一般已自动完成存储配置。
文件默认存储于本地的 /data/file/hydro
目录下,切换存储后端时需要手动复制或移动原有文件。 请根据你使用的存储端类型阅读对应教程。(同时欢迎使用其他存储类型的用户向我们提供详细的存储教程)
Tips
如果关闭了 file.pathStyle
选项,请在 endPointForUser
和 endPointForJudge
设置中填写真实 url,/fs/
端点将不可用。
MinIO
Warning
新版本 MinIO 占用较大,如果您为轻量使用,我们不建议使用 MinIO 。旧版本 Hydro 用户大部分可直接切换至 file 模式,由 Hydro 代替读取。
安装 MinIOopen in new window 后进入 控制面板>manage_config。
file.type
: s3
file.endPoint
: http://127.0.0.1:9000
(即 MinIO 启动时显示的 endPoint)file.accessKey
: 参照 MinIO 配置file.secretKey
: 参照 MinIO 配置file.bucket
: hydro
(MinIO 内部存储桶名称)file.region
: us-east-1
file.pathStyle
: truefile.endPointForUser
: /fs/
file.endPointForJudge
: /fs/
保存后重启,已有文件请自行复制。
腾讯云COS
进入 控制面板>系统设置>存储桶设置。
file.type
: s3
file.endPoint
: https://cos.<存储桶地域>.myqcloud.com
(或是 https)file.accessKey
: 您的腾讯云 API 密钥的 SecretIdfile.secretKey
: 您的腾讯云 API 密钥的 SecretKeyfile.bucket
: <存储桶名称>file.region
: Autofile.pathStyle
: falsefile.endPointForUser
: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/
file.endPointForJudge
: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/
保存后重启,已有文件请自行复制。
阿里云OSS
// TODO & PRs Welcome
Prev
部署 Hydro
Next
反向代理 / SSL 配置
+
+
+
diff --git a/docs/install/smtp.html b/docs/install/smtp.html
new file mode 100644
index 00000000..598104ff
--- /dev/null
+++ b/docs/install/smtp.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ SMTP | Hydro
+
+
+
+
+
+ Skip to main content
SMTP 以 QQ 邮箱为例。
SMTP_USER: 12345678@qq.com SMTP_PASS: 提供的 SMTP 密码 SMTP_HOST: smtp.qq.com SMTP_PORT: 465/587 (请参照邮件服务商说明) SMTP_SECURE: 是否使用加密 TLS 连接(请参照邮件服务商说明,使用 STARTTLS 的服务商无需勾选) SMTP_FROM: 发送签名(提示:若不清楚请填写邮件地址,填错会导致邮件无法发送) 已知能够完整兼容的服务商有:
QQ 邮箱 腾讯企业邮 网易 163 邮箱 飞书域名邮箱 Zeptomail Zoho Mail Outlook Gmail 新浪邮箱 如果使用其他服务商且没有发现问题,欢迎向此列表 Pull Request。
+
+
+
diff --git a/docs/system/FAQ.html b/docs/system/FAQ.html
new file mode 100644
index 00000000..b070fed9
--- /dev/null
+++ b/docs/system/FAQ.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 常见问题 | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/docs/system/cdn.html b/docs/system/cdn.html
new file mode 100644
index 00000000..23613a62
--- /dev/null
+++ b/docs/system/cdn.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 使用内容分发网络 | Hydro
+
+
+
+
+
+ Skip to main content
使用内容分发网络 如您希望改善 Hydro 的访问质量,在您的服务器带宽较小的情况下,您可以考虑使用内容分发网络,即 CDN ,通常情况下您仅需设置资源 CDN 即可大幅度改善访问质量,关于如何使用内容分发网络和使用中的任何问题请联系各大云厂商。
创建并配置好资源 CDN ,在控制面板中将 server.cdn
设置项修改为 CDN 域名。(如 https://cdn.hydro.ac/
,以 /
结尾)。
如果您预算充足,可以使用全站 CDN。
Warning
全站 CDN 配置较为繁琐,如您没有相关使用经验请仅建立并配置资源 CDN ,配置资源 CDN 在大部分情况下即可大幅度改善访问质量。 因各服务商全站 CDN 配置方法不同,配置过程不同,需要配置的内容较多,以下仅为参考配置且配置补全 ,如果有任何问题建议先查阅云服务商文档及咨询云服务商工程师。
缓存设置可以参考以下设置:
类型 内容 缓存行为 全部文件 全部文件 遵循源站 文件后缀 jpg,js,png,css,gif 缓存一天
同时设置添加回源HTTP请求头
头部参数 头部取值 X-Forward-For 参考所使用服务商CDN文档来设置用户来源IP
且您应当修改系统设置中的 server.xff
值为 X-Forwarded-For
,该设置是为了能够让系统正确获取到用户的IP地址。
Prev
导入用户
Next
数据库备份和恢复
+
+
+
diff --git a/docs/system/cli.html b/docs/system/cli.html
new file mode 100644
index 00000000..2c7309ad
--- /dev/null
+++ b/docs/system/cli.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+ Hydro Cli | Hydro
+
+
+
+
+
+ Skip to main content
Hydro Cli Tips
在使用 cli 之前,请完成数据库配置。 指令中使用 <>
括起来的参数必须给出,用 []
括起来的参数可以给出,若不给出则按照默认设置。用户请根据自己的情况替换掉用 <>
或是 []
包括起来的部分(括号也应替换)
cli 可以帮助用户在控制台下快捷地进行一些操作。 这些命令需要以在终端以 root 用户执行(安装时执行命令的位置)。 下面给出了一些常用的例子。
Tips
很少使用。建议通过 控制面板>导入用户 功能代替
hydrooj cli user create < mai l > < usernam e > < passwor d > < ui d >
+# 该用户的邮箱、用户名和密码
+
+# 如创建邮箱为 hydro@hydro.local,用户名为 Hydro,密码为 hydrohydro ,UID 为 2 的用户:
+# 请确保 UID 为不小于 2 的正整数且未被占用,邮箱和用户名均不重复。
+hydrooj cli user create hydro@hydro.local Hydro hydrohydro 2
+
若一切正常,运行该指令后您会从命令行窗口中看到该用户 uid。
hydrooj cli user setSuperAdmin < ui d >
+
+# 如设置 uid 为 2 的用户为管理员:
+hydrooj cli user setSuperAdmin 2
+
hydrooj cli user setPriv < ui d > < pri v >
+
关于参数 [priv]
,可阅读 此处 。
hydrooj cli user setPassword < ui d > < passwor d >
+
+# 如将 uid 为 1 的用户的密码改为 hydrohydro:
+hydrooj cli user setPassword 1 hydrohydro
+
先 创建一个账号 。
您需要留意运行此指令返回的数字,表示该用户的 uid
,需要填入下面的指令中,然后给予该账号评测权限。
hydrooj cli user setJudge < ui d >
+
完成后将配置的用户名及密码写入评测机配置文件,评测机即可连接到网页端。
用户封禁:
hydrooj cli user setPriv < ui d > 0
+
IP/邮箱域名封禁:
# key 格式为 ip::xxx.xxx.xxx.xxx (封禁 IP 访问) 或是 mail::xxx.com (禁止 xxx.com 的邮箱注册)
+hydrooj cli blacklist add < ke y > [duration] # 将 <key> 拉入黑名单,时长为 [duration] (以月为单位的整数,默认为 12,若 duration=0 则永久封禁)
+hydrooj cli blacklist get < ke y > # 获取黑名单中有关 <key> 的信息
+hydrooj cli blacklist del < ke y > # 将 <key> 移出黑名单
+
所有于 此文件夹open in new window 下的函数均可用 cli 调用。
这里并没有列出所有可以运行的指令,因为其中很多功能我们更推荐通过 Web 访问。
hydrooj cli user create < mai l > < unam e > < passwor d > [uid] [ regip ] [ priv ]
+# 创建邮箱为 <mail>,用户名为 <uname>,密码为 <password>,ID 为 [uid],注册 ip 为 [regip],权限为 [priv] 的用户
+hydrooj cli user setUname < ui d > < unma e > # 将 ID 为 <uid> 的用户的用户名设置为 <uname>
+hydrooj cli user setPriv < ui d > < pri v > # 将 ID 为 <uid> 的用户的权限设为 <priv>
+hydrooj cli user setPassword < ui d > < passwor d > # 将 ID 为 <uid> 的用户的密码设置为 <password>
+hydrooj cli user setEmail < ui d > < mai l > # 将 ID 为 <uid> 的用户的邮箱设置为 <mail>
+hydrooj cli user setSuperAdmin < ui d > # 将 ID 为 <uid> 的用户设为全站管理员
+hydrooj cli problem import < domainI d > < file/pat h > # 将 <file/path> 的Hydro格式题目包导入至 <domainId> 域中
+hydrooj cli problem export < domainI d > # 将 <domainId> 域中的所有题目包导出
+hydrooj cli system set < ke y > < valu e > # 修改系统设置 <key> 值为 <value>
+
Prev
维护
Next
导入用户
+
+
+
diff --git a/docs/system/database.html b/docs/system/database.html
new file mode 100644
index 00000000..78f620f2
--- /dev/null
+++ b/docs/system/database.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 数据库备份和恢复 | Hydro
+
+
+
+
+
+ Skip to main content
数据库备份和恢复 Warning
非常不推荐直接操作数据库!
当你改动一个字段的时候,可能与其相关的部分忘记修改,改完觉得好像没什么问题,过段时间发现了一些异常,根本不会想到是你这次改数据库导致的,之后又不会修。 直接修改数据库后,可能没有通知主程序,缓存仍然存在,表现为修改不生效。 直接操作数据库的权限过大,若操作失误带来的影响通常是灾难性的。 在绝大部分情况下均不需要/不可以直接操作数据库。若确需要,可使用 hydrooj db
命令打开数据库 shell,也可以从 ~/.hydro/config.json
查找数据库 connection string 并使用外部工具进行连接。
注:MongoDB 的用户是附加在特定数据库中的,使用外部工具连接请确保使用了正确的 authSource
选项。
为了保证数据安全,请定期备份。
若您使用自动脚本安装,可使用 hydrooj backup
快捷备份数据,备份完成后会在当前目录生成备份压缩包文件,您可使用 hydrooj restore <备份文件路径>
恢复之前备份的数据。
可使用 MongoDB 自带的 mongodumpopen in new window 进行数据库备份。并将 /data/file
文件夹备份即可。
对于数据库,请请不要在数据库运行时直接拷贝数据库文件夹 。请每次备份后检查生成的备份文件的大小和内容,确保备份成功。 请不要把备份数据和 Hydro 系统放在同一台机器上,这样数据丢失的风险仍然较高。
使用 MongoDB 自带的 mongorestoreopen in new window 导入备份的数据库文件,并还原 /data/file
目录文件。 如果只是想不同机器之间迁移部署,只需要在停止 Hydro 和 MongoDB 服务后 将相关文件夹(通常为 /data/db
与 /data/file
与 /root/.hydro/config.json
)复制即可。
Prev
使用内容分发网络
Next
前端修改
+
+
+
diff --git a/docs/system/frontend-modify.html b/docs/system/frontend-modify.html
new file mode 100644
index 00000000..e185e263
--- /dev/null
+++ b/docs/system/frontend-modify.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 前端修改 | Hydro
+
+
+
+
+
+ Skip to main content
前端修改 此指南将教您修改前端文件。
如果您正在使用开发者模式,请直接修改 packages/ui-default/templates
下的文件。
如果您使用安装脚本部署:
请先使用 hydrooj addon create
创建一个本地插件(如果之前没有做过的话)。
通常的,在您访问的 url 前加上 view-source:
(如 view-source:https://hydro.ac
即可查看页面源代码,在第二行的 <html data-page="xxx">
中 data-page
值即为页面名(首页例外,为 main.html
)。 在 默认 templatesopen in new window 中找到对应文件,将文件的全部内容 复制到 ~/addon/templates/
文件夹下后进行修改即可。
特别的,创建题目时的默认模板位于 partials/problem_default.md
,创建训练计划时的默认模板位于 partials/training_default.json
,修改方式同上。
以上所有更改均会在重启 Hydro 后生效。
Prev
数据库备份和恢复
Next
现场赛指南
+
+
+
diff --git a/docs/system/import-user.html b/docs/system/import-user.html
new file mode 100644
index 00000000..053a9eee
--- /dev/null
+++ b/docs/system/import-user.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ 导入用户 | Hydro
+
+
+
+
+
+ Skip to main content
导入用户 目前支持 csv 格式(用 ,
分隔)或 Excel 格式(用 TAB 分隔) 导入用户数据, 数据既可以用文本编辑器创建,也可以用 Excel 等软件来辅助创建。
每行最少三列,最多五列,分别为: 邮箱,用户名,密码,显示名,用户信息。(显示名和用户信息为可选) 请使用 UTF-8 编码,否则中文可能会乱码。 如果使用 CSV 格式(逗号分隔),则用户信息列不可用。
foo@undefined.moe user1 password1
+bar@undefined.moe user2 password2 temp
+test@undefined.moe user3 password3 test {"group":"class1","studentId":"123","school":"Hydro School"}
+
可以在粘贴后点击预览验证复制入的数据的有效性
这将创建三个用户:
user1
密码为 password1
, 邮箱 foo@undefined.moe
;user2
密码为 password2
,邮箱 bar@undefined.moe
,显示名为 temp
;user3
密码为 password3
,邮箱 test@undefined.moe
,显示名为 test
,学校为 Hydro School
,学号为 123
,该用户将会被分配至当前域的 class1
小组内; Prev
Hydro Cli
Next
使用内容分发网络
+
+
+
diff --git a/docs/system/index.html b/docs/system/index.html
new file mode 100644
index 00000000..ce15da71
--- /dev/null
+++ b/docs/system/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ System | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/docs/system/maintain.html b/docs/system/maintain.html
new file mode 100644
index 00000000..db6c0582
--- /dev/null
+++ b/docs/system/maintain.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+ 维护 | Hydro
+
+
+
+
+
+ Skip to main content
维护 使用一键安装脚本安装的 Hydro 使用 PM2 对进程进行管理。
可以通过下面的指令查看当前 PM2 正在管理的所有进程。
一键安装脚本默认会创建下面几个进程:
hydrooj
: Hydro 主进程hydro-sandbox
: Hydro 评测沙箱mongodb
: MongoDB 数据库caddy
: 反向代理后文的指令中将用 <name>
替代此处的进程名称,用 <id>
替代进程 ID(进程 ID 可通过 pm2 ls
查看)。(尖括号同样需要替换)
pm2 ls # 查看进程列表
+pm2 start < i d > # 启动进程
+pm2 stop < i d > # 关闭进程
+pm2 restart < i d > # 重启进程
+pm2 del < i d > # 删除进程
+pm2 log < id/nam e > --lines=100 # 查看该进程的后 100 行日志
+pm2 attach < i d > # 与进程交互
+pm2 save # 保存对 PM2 进行的修改(在添加、修改、删除进程后需要执行该指令)
+
在部分环境(常见于 lxc 容器或是精简版系统)下,服务器重启后 Hydro 可能不能正常自启动,这时请使用 pm2 resurrect
手动载入进程列表。
如果手动修改进程列表且已经覆盖掉保存的原列表,请使用 pm2 stop all && pm2 del all
清空所有进程之后重新运行安装脚本。原有数据不会丢失。
Hydro 主进程同样支持多进程启动,但在中低端服务器(不超过4核)中没有必要使用多进程启动 Hydro,会降低性能且成倍提高内存占用。
pm2 start hydrooj -i < n > # 以 n 进程启动 Hydro 主进程
+
Hydro 系统会不定期发布更新,可以使用下面的命令获取更新。
无特殊情况请 不要更新PM2 !此操作可能导致进程列表丢失!
yarn global upgrade-interactive --latest # 在交互式界面中选择想要更新的组件
+pm2 restart hydrooj # 更新完后需重启 hydrooj
+
cd `yarn global dir` && yarn list --pattern hydrooj
+
yarn cache clean && nix-collect-garbage
+
Next
Hydro Cli
+
+
+
diff --git a/docs/system/onsite-contest.html b/docs/system/onsite-contest.html
new file mode 100644
index 00000000..4fea4c0d
--- /dev/null
+++ b/docs/system/onsite-contest.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 现场赛指南 | Hydro
+
+
+
+
+
+ Skip to main content
现场赛指南 本指南适用于希望进行线下赛,在内网部署评测设施的用户。 以下日期排期仅供参考,具体可根据实际情况自行安排。
本文部分内容同样适用于 DOMJudge。
请检查下述列表是否均按需求配置完成:
关于选手机设置:
选手机预装了 Linux 系统,并有对应的开发环境。 推荐使用 CAICPC 作为安装镜像,直接选择第二项启动选项即可一键安装。 选手机均连接到内网,且选手机之间无法互相访问,但可以访问公网服务器(若使用的路由器不支持该功能可以在选手机使用 iptables 拦截其他流量)。 可使用 DHCP 配置选手机网络,但需保证地址租期足够长(推荐七天)。 关于服务器设置:
关于 CAICPC 镜像:
本镜像基于标准 ICPC 镜像修改而来。 添加了状态上报,用于统一监测服务器状态; 支持调用 VLC 截取屏幕和摄像头流供 live 模块使用; 支持批量下发管理命令(一键锁屏/解锁/重启/显示座位号等等); 使用安装脚本安装 Hydro。 导入所需的比赛用户。 安装 @hydrooj/onsite-toolkit
插件。 参照 https://github.com/hydro-dev/xcpc-tools
说明安装独立模块。 由志愿者打开所有选手机桌面上的 seat.txt 文件,填入座位号,保存,后台所见座位号应当同步刷新; 如果需要根据座位号自动登录,此时导出 IP/队伍 表,在 onsite-toolkit 设置中填入。 准备完成后,批量修改选手机为强密码!!! // TODO: tools 配置
关于打印:
打印功能在 xcpc-tools
中配置。 在 server 端新建一个打印机 token,在赛场旁摆放一台电脑,安装对应的打印机驱动,以 client 模式运行 xcpc-tools
,填入 token,即可连接。 xcpc-tools
会自动抓取打印任务自动打印,默认每个文件最多打印五页,队伍名称和座位号会在纸张顶部。关于气球:
气球通常由小票机进行打印。每当有队伍通过题目时,会打印一张小票; 小票内含队伍名,座位号,气球颜色,该队伍当前的所有气球颜色等信息,志愿者拿到小票后根据其上内容分发气球。 关于自动登录:
启用后,在地址列表的用户均会自动登录上指定的对应账户,用户不可重新登录,不可登出,不可在其他 IP 登录。 操作前请确认列表中不含管理员账号和管理员所使用的机器 IP !
可选:
安装 grafana 和 netdata 用于监测服务器运行状态 以及给领导展示 ; 热身赛通常使用至少一道可以反复提交爆破的题目,引导选手大量提交,测试服务器负载情况。
如果需要发气球请提早给气球打气(通常比赛的前一小时气球组会非常忙) 记得给打印机补纸,小票机同理。 // TODO: 滚榜设置
Prev
前端修改
Next
常见问题
+
+
+
diff --git a/docs/user/copy-problem.html b/docs/user/copy-problem.html
new file mode 100644
index 00000000..0fd1df3a
--- /dev/null
+++ b/docs/user/copy-problem.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 复制题目 | Hydro
+
+
+
+
+
+ Skip to main content
复制题目 复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛/作业/训练计划中使用这些题目。
进入需要复制的题目页面或是题目列表页面。 点击右侧栏底部的“复制”按钮或是多选题目后点击右侧复制题目按钮。 在弹出的窗口中输入需要复制到的域的 ID。 点击“确定”后将自动跳转到复制后的题目连接。 不允许查看/修改复制后的题目的测试数据。 不能复制一个复制来的题目。 部分题目可能不允许复制。这遵循 域设置>编辑域资料 中的管理员设定。 Prev
Hydro Problem Format
+
+
+
diff --git a/docs/user/domain.html b/docs/user/domain.html
new file mode 100644
index 00000000..137c929f
--- /dev/null
+++ b/docs/user/domain.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+ 域 | Hydro
+
+
+
+
+
+ Skip to main content
域 域功能类似团队,允许在一套系统中创建多个环境(如不同班级,或是不同功能,等等) 用户可以创建多个域。(需要用户有 PRIV_CREATE_DOMAIN 权限,默认仅开放给管理员账户)。 域间数据完全独立,仅用户信息相通(注册账户后,在该实例的所有域中均有效)。
登录账号后,在“我的”选项卡中找到“我的域”,并点击“创建域”,填入以下信息:
ID: 每个域有一个唯一的 ID,将会在域 URL 中体现。创建后无法修改。 名称: 域的名字,创建后可以更改。 公告: 域主页上显示的公告,创建后可以更改。 avatar: 域头像,与用户头像同理,可以使用 gravatar:email
或 qq:id
或 github:name
或 url:link
的格式添加。将会在“我的域”界面内显示。 创建域后,您将在此域中拥有管理员权限,可以在域内进行添加题目/创建比赛等操作。
您可以在“管理域”选项卡中点击“初始化讨论节点”按钮初始化讨论节点。
未登录用户将默认使用 guest
权限,登录用户将默认使用 default
权限。 (所以将登陆用户设为 default
权限后并不会显示在“管理用户”页内,这也表示所有用户默认不会出现在管理列表中) 所以将一个用户的权限设为 default
和将用户移出该域是等价的。
对于不在列表中的用户,点击右上角“添加用户”,在左侧选中用户,右侧选择权限组,再点击“确定”即可。
若您想要创建比赛/作业,您可以在“比赛”或“作业”选项卡中,在页面右侧找到“创建”按钮, 题目一栏支持根据题目ID或是题目名自动筛选。设置完后可点击“创建”按钮创建比赛(描述这类的框不知道写啥就随便填,不能留空)。
Tips
若因为删除作业/比赛内题目导致无法打开,可以通过 /contest/<id>/edit
或 /homework/<id>/edit
(即在无法打开的页面页面后加上 /edit
)直接访问编辑页并修正。
若您想要创建训练,您可以在“训练” 项卡中点击“新建训练计划”,填写以下信息:
标题:该训练的标题; 简介:该训练的简介,会与标题同时显示在列表页面中; 说明:该训练的详细信息; 计划:该训练的具体题目及计划信息,其格式如下: [
+ {章节详细信息},
+ {章节详细信息},
+ ...
+ {章节详细信息}
+]
+
其中,“章节详细信息”的包含以下部分:
_id
:章节数字编号;title
:章节标题;requireNids
:训练此章节之前需要完成的章节数字编号,若无要求则留空,若有多个则使用逗号分隔;pids
:此章节中包含的题目的 ID ,若有多个则使用逗号分隔。举例 :若要在训练中创建三个章节,章节中分别有 ID 为 1,2,3 的题目。其中章节一、二无前置条件,章节三需要同时完成章节一、二后才能进行,则格式如下:
[
+ {
+ " _id " : 1 ,
+ " title " : " 入门 " ,
+ " requireNids " : [],
+ " pids " : [ 1 ]
+ },
+ {
+ " _id " : 2 ,
+ " title " : " 精通 " ,
+ " requireNids " : [],
+ " pids " : [ 2 ]
+ },
+ {
+ " _id " : 3 ,
+ " title " : " 大师 " ,
+ " requireNids " : [ 1 , 2 ],
+ " pids " : [ 3 ]
+ }
+]
+
Tips
若因为删除训练计划内题目导致训练计划无法打开,可以通过 /training/<id>/edit
(即训练计划页面后加上 /edit
)直接访问训练计划编辑页并修正配置文件。
Prev
用户文档
Next
权限系统
+
+
+
diff --git a/docs/user/index.html b/docs/user/index.html
new file mode 100644
index 00000000..a273eecb
--- /dev/null
+++ b/docs/user/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 用户文档 | Hydro
+
+
+
+
+
+ Skip to main content
用户文档 Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。
一般地,难度的数值越大,该题目越难。 新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。 越早递交评测的用户代码的评测结果对题目难度影响越大。 题目的难度由算法计算得出,有可能出现不准确的结果。 您可以在比赛的详细界面内点击“参与比赛”按钮进行参与。 比赛过程中“成绩表”会根据比赛规则显示排名。 在比赛截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。
若您想发布一个讨论,请先进入一个讨论节点 ,之后点击“创建一个讨论”按钮并填写:
标题; 内容; 是否高亮:若选择后,该贴的左边将有醒目的红色线条(需要“高亮讨论”权限); Pin:该讨论是否置顶(需要“置顶讨论”权限)。 之后点击“创建”按钮进行发布。
您可以在作业的详情页面中,点击“认领作业”。 在作业开始之前,您无法查看作业中的题目。 在作业持续时间内,您与他人的做题情况会被实时统计在“成绩表”内。 在作业进入延期阶段后,您仍然可以提交题目,但成绩表内的分数将根据延期扣分规则按百分比折算。 在作业截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。
Next
域
+
+
+
diff --git a/docs/user/permission.html b/docs/user/permission.html
new file mode 100644
index 00000000..6cea091c
--- /dev/null
+++ b/docs/user/permission.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ 权限系统 | Hydro
+
+
+
+
+
+ Skip to main content
权限系统 Hydro 的权限系统使用双层结构,分别为 Privilege (PRIV) 和 Permission (PERM)。 权限在系统内部使用位运算表示,具体的定义与数值可以查看 源代码open in new window 。
Privilege 是用户在整套系统内拥有的权限,在所有域均生效。如创建用户,编辑系统设置,创建域,查看域等等。
特别地,PRIV.PRIV_USER_PROFILE
控制一个账号是否能够作为普通账号登录。若不具有此权限,该账号将无法登录(被封禁)。
常见需求:若不想让普通用户上传文件 可以关闭default角色的 PRIV_CREATE_FILE
权限
Permission 是用户在单个域内拥有的权限,如创建题目/比赛,发布/删除讨论等等。
如果 PERM.PERM_VIEW
被禁用,则该用户无法查看此域。
通常我们需要给特定的一组用户分配相同的权限。在用户量较多的时候这会非常混乱难以管理,为此我们设计了【角色】,便于批量操作与管理。 角色是针对域内权限(PERM)的。在系统内置了三个角色:
guest (对未登录用户生效,含已封禁用户) default (对所有未指定角色的用户生效,包括未加入域的用户) root (拥有所有权限) 通常情况下,如果需要对域做特殊的权限控制,应当新建一个用户组(例如 member)并将选定用户加入该用户组。 将角色移出域和将用户的角色设置为 default 是等价的。 若有需要,您也可以创建 teacher, admin 等其他角色。 考虑到系统中的用户可能非常多(数万甚至数十万),在用户列表中仅会显示权限不为 default 的用户。
加入域的过程实际上是 用户通过某种方式自助将自己的权限组由 default 变更到另一权限组(如member) 的过程。 因此在入域申请链接的权限组中选择 guest 和 default 是没有意义的。
Prev
域
Next
题目
+
+
+
diff --git a/docs/user/problem-create.html b/docs/user/problem-create.html
new file mode 100644
index 00000000..6436c539
--- /dev/null
+++ b/docs/user/problem-create.html
@@ -0,0 +1,239 @@
+
+
+
+
+
+
+
+
+
+ Hydro常见题型的制做心得 | Hydro
+
+
+
+
+
+ Skip to main content
Hydro常见题型的制做心得 作者: laomai qq: 29985091 网址: http://82.157.98.222:8888/ 日期: 2022/03/16
本文为作者使用hydro时的实验记录,希望对大家有帮助.包括如下内容
零. hydro题目存储格式 一. 制做最简单的oj题 二. 含有自定义头文件的oj题,即函数交互式的题目 三. 半自动对拍的oj题,即不需要录入预期输出的题 四. 完全对拍题,即不需要录入输入数据和输出数据的题 五. 指定输入文件和输出文件 六. 多个子任务 七. 客观题,即制做有标准答案的填空和选择题.
如果想在本地建立好题目,然后批量上传的话. 下面的格式应该对你有帮助 每个题目应自占一个目录,目录名为题目编号比如1 ,2,3,4等等. 每个题目目录下一般有下面的元素:problem_zh.md
这个文件是就是题目的内容,即题目的描述,是一个markdown格式的文档.probelm.yaml
文件.这个是题目的配置信息. 比如标题和标签等。 testdata 子目录,对应网站里的测试数据部分里的文件, 里面至少有一个config.yaml文件 用来说明测试的类型.具体内容见后面的例子 如果题目有测试用例,则每个用例至少要提供一个in文件和一个输出文件(但有些测试类型不用,详情见后) additional_file子目录用来存放给做题者用的额外文件,比如头文件,图片,pdf文档等,在题目的 markdown 文档中可以用下面的格式为这些文件提供下载链接:[提示文字](file://xxx.txt)
下面为手工录入各种题型的步骤,即在网站登录后点创建题目之后的操作.如下图所示
我们假定题目内容均为下面的markdown文档
# 要求
+
+输入两个整数,输出他们的和
+
+# 样例
+
+```input1
+123 500
+```
+
+```output1
+623
+```
+
题目网址: http://82.157.98.222:8888/p/P10000
新建题目之后编辑题目内容,输入题号和标题,然后点创建按钮。如下图所示. 此时出现下面的图,点创建文件,文件名为 1.in
, 表示用例 1 的输入 编辑 1.in
的内容为两个整数比如 2 和 3 ,空格分开,如下图所示,然后点确定 类似办法创建一个 1.out
文件,内容为 5 ,注意数字编号必须和 in 文件一致,创建之后的文件列表和下面类似.
这样第一个用例的输入和预期输出就录入完毕,现在可以做本题了 本题的 AC 代码为: # include < iostream >
+using namespace std ;
+int main ( int argc , char* argv []){
+ int a , b ;
+ cin >> a >> b ;
+ cout << ( a + b ) ;
+ return 0 ;
+}
+
题目网址: http://82.157.98.222:8888/p/P10001 本类型和类型一的区别在于出题者要向做题者提供一个额外的头文件,做题者的主函数里可以包含这个头文件以调用出题者提供的某些函数,或者实现头文件里指定的函数.
题目内容的录入以及测试数据的录入和类型一样 本题要额外上传两个文件.分别为 tools.h
和 config.yaml
,如下图所示
tools.h
的内容为
# include < iostream >
+using namespace std ;
+
+int add ( int x , int y ) ; //留待做题者实现
+
+int main ( int argc , char* argv []){
+ int a , b ;
+ cin >> a >> b ;
+ cout << add ( a , b ) ;
+ return 0 ;
+}
+
这个头文件里实现了一个主函数,并且声明了需要做题者实现的函数add,当然,出题者应该在题目要求里写明这个函数的原型以及把tools.h文件上传到附加文件列表中,以方便做题者. 题面里可以用如下格式为用户提供下载链接,中括号内的内容可以自己写,[tools.h](file://tools.h) 如下面所示
config.yaml文件的内容为
type : default
+filename : null
+user_extra_files :
+ - tools.h
+
本题的ac代码为
# include " tools.h "
+int add ( int x , int y ){
+ return x + y ;
+}
+
可见本类型的题目,做题者包含给定的头文件后,可以不需要自己实现主函数,只需要专心实现给定的函数即可.
例题网址:http://82.157.98.222:8888/p/P10002 本题型的特点是不需要手工给出每个用例的预期输出,但是要自己编写一个样本程序,测试时会把用户的输出和样本程序的输出进行对比。
仍以两数求和为例
题目内容和类型一类似 测试数据部分只需要提供1.in 编写一个样本程序 checker.cc
,内容如下: # include " testlib.h "
+int main ( int argc , char * argv []) {
+ registerTestlibCmd ( argc , argv ) ;
+ int a = inf . readInt () ; // 读取输入流的第一个整数
+ int b = inf . readInt () ; // 读取输入流的下一个整数
+ int d = a + b ;
+ int c = ouf . readInt () ; // 读取输出流的下一个整数
+ if ( a + b != c )
+ quitf ( _wa , " %d + %d expected %d, found %d " , a , b , d , c ) ; //输出错误的具体信息,便于做题者调试
+ else
+ quitf ( _ok , " answer of %d + %d is %d " , a , b , c ) ;
+}
+
config.yaml文件的内容如下: checker_type : testlib
+checker : checker.cc
+cases :
+ - input : 1.in
+ output : /dev/null # 无输出
+
最终的测试文件列表如下所示:
当程序有错误时,输出的效果如下
可见这里输出了错误细节,便于做题者调试
本题的ac代码和类型一的一样,内容为
# include < iostream >
+using namespace std ;
+int main ( int argc , char* argv []){
+ int a , b ;
+ cin >> a >> b ;
+ cout << ( a + b ) ;
+ return 0 ;
+}
+
如果不希望自己录入输入数据,而是在每次测试时自动动态生成的话,可以将题目类型设为interactive
,并提供一个对拍程序.仍以求和为例 例题网址: http://82.157.98.222:8888/p/P10005
最后测试数据部分的文件列表如下图所示
checker.cc
,内容为:# include " testlib.h "
+# include < iostream >
+using namespace std ;
+
+int main ( int argc , char* argv []) {
+ setName ( " Interactor A+B " ) ;
+ registerInteraction ( argc , argv ) ;
+ //自动生成两个随机整数
+ rnd . setSeed ( time ( NULL )) ;
+ int a = rnd . next ( 1000 ) ;
+ int b = rnd . next ( 1000 ) ;
+ // 本程序的输出将作为用户程序的输入
+ cout << a << " " << b << endl ;
+ int c ;
+ // 用户程序的最后输出将作为本程序的输入
+ cin >> c ;
+ //对比用户结果和预期结果
+ if ( a + b != c )
+ quitf ( _wa , " %d + %d expected %d, found %d " , a , b , a + b , c ) ; //输出错误的具体信息,便于做题者调试
+ else
+ quitf ( _ok , " answer of %d + %d is %d " , a , b , c ) ;
+}
+
config.yaml
文件的内容为:type : interactive
+interactor : checker.cc
+cases :
+- input : /dev/null # no input and no output, dynamic generated
+ output : /dev/null
+- input : /dev/null # no input and no output, dynamic generated
+ output : /dev/null
+
AC 代码和类型一中的相同
例题网址:http://82.157.98.222:8888/p/P10003 有时希望指定输入和输出文件,此时测试文件 1.in
和 1.out
和类型一类似, 但是要提供config.yaml文件,内容类似于下
则运行时测试环境会自动把每个输入文件复制到test.in中,输出内容和test.out的内容进行对比. ac的代码如下:
# include < fstream >
+using namespace std ;
+int main ( int argc , char* argv []){
+ int a , b ;
+ ifstream ifs ( " test.in " ) ;
+ ifs >> a >> b ;
+ ofstream ofs ( " test.out " ) ;
+ ofs << ( a + b ) ;
+ return 0 ;
+}
+
例题网址: https://hydro.ac/d/system_test/p/7
提供好题目和各个子任务的输入、输出文件 建议文件名格式为 data<id>-<数字>
id为子任务编号 config.yaml文件的内容参考如下 time : 100ms
+memory : 8m
+subtasks :
+ - score : 20
+ id : 0
+ cases :
+ - input : data1-1.in
+ output : data1-1.ans
+ - input : data1-2.in
+ output : data1-2.ans
+ - input : data1-3.in
+ output : data1-3.ans
+ - input : data1-4.in
+ output : data1-4.ans
+ - input : data1-5.in
+ output : data1-5.ans
+ - score : 20
+ id : 1
+ cases :
+ - input : data2-1.in
+ output : data2-1.ans
+ - input : data2-2.in
+ output : data2-2.ans
+ - input : data2-3.in
+ output : data2-3.ans
+ - input : data2-4.in
+ output : data2-4.ans
+ - input : data2-5.in
+ output : data2-5.ans
+ - score : 20
+ id : 2
+ cases :
+ - input : data3-1.in
+ output : data3-1.ans
+ - input : data3-2.in
+ output : data3-2.ans
+ - input : data3-3.in
+ output : data3-3.ans
+ - input : data3-4.in
+ output : data3-4.ans
+ - input : data3-5.in
+ output : data3-5.ans
+ - score : 20
+ id : 3
+ if : [ 2 ]
+ cases :
+ - input : data4-1.in
+ output : data4-1.ans
+ - input : data4-2.in
+ output : data4-2.ans
+ - input : data4-3.in
+ output : data4-3.ans
+ - input : data4-4.in
+ output : data4-4.ans
+ - input : data4-5.in
+ output : data4-5.ans
+ - score : 20
+ id : 4
+ if : [ 1 , 3 ]
+ cases :
+ - input : data5-1.in
+ output : data5-1.ans
+ - input : data5-2.in
+ output : data5-2.ans
+ - input : data5-3.in
+ output : data5-3.ans
+ - input : data5-4.in
+ output : data5-4.ans
+ - input : data5-5.in
+ output : data5-5.ans
+
可以看出if 用来指定前置子任务. 此外,如果某个子任务没有提供cases部分时,测试时会自动寻找类似于 data<id>-x.in
和data<id>-x.out
的文件,id为子任务编号 上面的例子故意设计为子任务编号和用例文件中的编号不同,所有每个子任务都需要手工指定对应的cases.
注意新版的客观题,格式已经更新。
例题网址:http://82.157.98.222:8888/p/P10004 客观题只需要题面和config.yaml文件. 例子如下:
1. 填空题
+
+1+1 = {{ input(1) }}
+
+2. 选择题
+
+{{ select(2) }}
+- 1+1=2
+- 1+1=3
+- 1+1=4
+
+3. 多选题
+
+{{ multiselect(3) }}
+- A
+- B
+- C
+
+
上传的 config.yaml
内容为
type : objective # 表明该题为客观题
+answers : # 列举出每一题的正确选项与对应的得分
+ ' 1 ' : [ ' 2 ' , 50 ]
+ ' 2 ' : [[ ' A ' , ' B ' ], 30 ] # 填空题支持多答案,满足其一得分
+ ' 3 ' : [[ ' A ' , ' B ' ], 20 ] # 多选题答案为数组,有部分分
+
+
题目运行效果如下:
做完之后点提交,效果如下
可见评分结果正确.
对所有编程题目,题面是必须录入的,如果指定了测试程序时,可以不需要录入输出数据. 如果设置测试方式为interactive,输入数据也不需要手工录入. 想指特殊的测试方式时,一般需要上传一个config.yaml文件,并设置对应字段的值. 对编程题,本文档中用到的字段有
type字段一般为default, 对全自动对拍题,设为interactive
checker_type: testlib checker: checker.cc 用来指定自定义的测试程序,即对拍程序
filename: test用来指定对test.in文件和test.out文件进行读写.
cases:
用来指定测试用例.
更详细的介绍见 https://hydro.js.org/docs/user/testdata/
+
+
+
diff --git a/docs/user/problem-format.html b/docs/user/problem-format.html
new file mode 100644
index 00000000..39bee634
--- /dev/null
+++ b/docs/user/problem-format.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+ Hydro Problem Format | Hydro
+
+
+
+
+
+ Skip to main content
Hydro Problem Format 为了便于系统间进行数据交换,Hydro 定义了一种基于 zip 的标准格式用于题目传输。压缩包内文件结构如下:
喵? tree
+.
+├── 任意文件名的文件夹
+│ ├── problem.yaml
+│ ├── problem_zh.md
+│ ├── testdata
+│ │ ├── config.yaml
+│ │ ├── a1.in
+│ │ ├── a1.out
+│ │ ├── a2.in
+│ │ ├── a2.out
+│ │ ├── a3.in
+│ │ └── a3.out
+│ └── additional_file
+│ ├── a.png
+│ └── b.pdf
+└── ...
+
其中 problem.yaml 内容如下:
title : 题目名
+tag :
+- 标签1
+- 标签2
+pid : 题号(字母+数字)
+
problem_*.md 中为 markdown 格式的题面,语言代号支持完整形式(如 zh_CN),也支持短形式(如 zh)。若同时存在多个语言的题面,Hydro 将会自动识别并提供切换功能。
testdata 文件夹中存放所有测试数据文件,命名规则和配置文件格式请参照【测试数据格式】章节。
additional_file 中存储附加文件,通常用于存放图片,PDF 等文件。这些文件可以在题面中使用 file://文件名 的路径访问。
Prev
测试数据格式
Next
复制题目
+
+
+
diff --git a/docs/user/problem.html b/docs/user/problem.html
new file mode 100644
index 00000000..d41fd744
--- /dev/null
+++ b/docs/user/problem.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+ 题目 | Hydro
+
+
+
+
+
+ Skip to main content
题目 拥有 PERM_CREATE_PROBLEM 的用户均可以新建题目。 请点击题库页面右下角的 创建题目
按钮。
Tips
题目 ID 不能全为数字。若留空则使用自动分配的数字题号。
详见下方题面编辑部分,以及 laomai 编写的说明
上传 Hydro 导出的题目压缩包即可。
如果您的压缩包较大无法上传我们也提供cli导入方法:
hydrooj cli problem import <domainId> <file/path> # 将 <file(压缩文件)/path(解压后的文件夹)> 的Hydro格式题目包导入至 <domainId> 域中。
+
Hydro 提供了一个小工具 loj-downloadopen in new window ,可从基于原版 SYZOJ/SYZOJ-NG 搭建的源站下载到符合Hydro格式的题目压缩包。 工具使用方法请前往使用教程查看,自行摸索并确保在网络通畅的环境下使用。
见插件 fps-importer 。
见插件 import-qduoj。
题面使用 Markdown 语法,并进行了部分扩展。
支持对样例数据分组显示:
```input1
+1 2
+```
+
+```output1
+3
+```
后接的数字为测试点编号,将自动合并,并左右分栏显示。
支持从附加文件引用资源。(您可以先创建题目,上传相关文件后再编辑该题目)
附加文件下载链接: [file](file://input.in)
从附加文件引用一张图片: ![img](file://foo.jpg)
从附加文件引用 pdf 作为题面:@[pdf](file://foo.pdf)
(部分情况下若无法使用,请尝试 @[pdf](file://foo.pdf?noDisposition=1)
) 从附加文件引用 word 文档作为题面: @[doc](file://foo.docx)
(依赖 onlyoffice 插件) Tips
如果您在使用外部的存储服务,部分服务商可能会强制发送 Content-Disposition
导致文件直接被下载而非预览。详询对应服务商。
https://cloud.tencent.com/document/product/436/96243 https://help.aliyun.com/zh/oss/user-guide/how-to-ensure-an-object-is-previewed-when-you-access-the-object 题面支持合并表格:
| 1 | 1 | 3 | 4 | 5 |
+| --- | --- | --- | --- | --- |
+| 1 | 1 | 2 | 2 | 6 |
+| 1 | 1 | 2 | 2 | 7 |
+| 1 | 4 | 3 | 5 | 5 |
+
将被渲染为:
支持内嵌 HTML:(用来对付部分 Markdown 搞不定的东西)
<span bgcolor="red">foo</span>
+
可点击右侧分类面板快速添加标签,也可以用英文半角逗号分隔多个标签。
您可以在题目右侧“文件”面板上传测试数据和附加文件。(支持拖拽文件至相应位置进行上传)测试数据格式 。
1. 填空题
+
+1+1 = {{ input(1) }}
+
+2. 选择题
+
+{{ select(2) }}
+- 1+1=2
+- 1+1=3
+- 1+1=4
+
+3. 多选题
+
+{{ multiselect(3) }}
+- A
+- B
+- C
+
仅需要配置 config.yaml 即可,不需要上传其他文件。
type : objective # 表明该题为客观题
+answers : # 列举出每一题的正确选项与对应的得分
+ ' 1 ' : [ ' 2 ' , 50 ] # 填空题/选择题,单答案
+ ' 2 ' : # 填空题/选择题,多答案,不同答案对应不同分数,注意空格缩进
+ ' A ' : 30 # 也可以使用相同分数,即同时存在多个正确答案
+ ' B ' : 10
+ ' 3 ' : [[ ' A ' , ' B ' ], 20 ] # 多选题答案为数组,有部分分
+
Prev
权限系统
Next
测试数据格式
+
+
+
diff --git a/docs/user/testdata.html b/docs/user/testdata.html
new file mode 100644
index 00000000..2bea95e1
--- /dev/null
+++ b/docs/user/testdata.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+ 测试数据格式 | Hydro
+
+
+
+
+
+ Skip to main content
测试数据格式 Tips
您可以直接选择文件(支持多选)上传或将文件拖拽至相应位置上传。 若上传文件为 zip 格式,将会自动进行解压操作。
对于一般的题目,您只需提供 .in
和 .out/.ans
文件,以下是一个例子。 请务必确保文件名中含有数字。形如 sample.in
的文件是不会被自动识别的。
喵? tree
+.
+├── a1.in
+├── a1.out
+├── a2.in
+├── a2.out
+├── a3.in
+└── a3.out
+
测试数据将被自动识别,并使用 1S 256MB 的限制。
Tips
推荐您通过 评测设置 在线编辑题目配置,可以拥有更好的编辑体验。
上传 config.yaml
文件即可,文件格式如下(下方所有样例均为可选项,若无说明则预填写的内容即为默认值):
# 题目类型,可以为 default(比对输出,可以含spj), objective(客观题), interactive(交互题)
+type : default
+
+# 全局时空限制(此处的限制优先级低于测试点的限制)
+time : 1s
+memory : 128m
+
+# 输入输出文件名(例:使用 foo.in 和 foo.out),若使用标准 IO 删除此配置项即可
+filename : foo
+
+# 此部分设置当题目类型为 default 时生效
+# 比较器类型,支持的值有 default(直接比对,忽略行末空格和文件末换行), ccr, cena, hustoj, lemon, qduoj, syzoj, testlib(比较常用)
+checker_type : default
+# 比较器文件(当比较器类型不为 default 时填写)
+# 文件路径(位于压缩包中的路径)
+# 将通过扩展名识别语言,与编译命令处一致。在默认配置下,C++ 扩展名应为 .cc 而非 .cpp
+checker : chk.cc
+
+# 此部分设置当题目类型为interactive时生效
+# 交互器路径(位于压缩包中的路径)
+interactor : interactor.cc
+
+# Extra files 额外文件
+# These files will be copied to the working directory 这些文件将被复制到工作目录。
+# 提示:您无需手动上传 testlib.h。
+user_extra_files :
+ - extra_input.txt
+judge_extra_files :
+ - extra_file.txt
+
+# Test Cases 测试数据列表
+# If neither CASES or SUBTASKS are set(or config.yaml doesn't exist), judge will try to locate them automaticly.
+# 如果 CASES 和 SUBTASKS 都没有设置或 config.yaml 不存在, 系统会自动尝试识别数据点。
+# We support these names for auto mode: 自动识别支持以下命名方式:
+# 1. [name(optional)][number].(in/out/ans) RegExp: /^([a-zA-Z]*)([0-9]+).in$/
+# examples:
+# - c1.in / c1.out
+# - 1.in / 1.out
+# - c1.in / c1.ans
+# 2. input[number].txt / output[number].txt RegExp: /^(input)([0-9]+).txt$/
+# - example: input1.txt / input2.txt
+#
+# The CASES option has higher priority than the SUBTASKS option!
+# 在有 CASES 设置项时,不会读取 SUBTASKS 设置项!
+#
+# The CASES option has been deprecated in the new version, please use the more personalized SUBTASKS!
+# CASES 已于新版本中被废弃,请使用个性化程度更高的SUBTASKS!
+# score: 50 # 单个测试点分数
+# time: 1s # 时间限制
+# memory: 256m # 内存限制
+# cases:
+# - input: abc.in
+# output: def.out
+# - input: ghi.in
+# output: jkl.out
+# 或使用Subtask项:
+subtasks :
+ - score : 30
+ type : min # 可选 min/max/sum,分别表示取所有测试点最小值、所有测试点最大值、所有测试点之和
+ time : 1s
+ memory : 64m
+ cases :
+ - time : 0.5s
+ memory : 32m # 可对单个测试点单独设置时间限制和内存限制
+ input : a.in
+ output : a.out
+ - input : b.in
+ output : b.out
+ - score : 70
+ time : 0.5s
+ memory : 32m
+ if : [ 0 ] # 可选,传入数组,表示仅在subtask0通过时此subtask才计分
+ cases :
+ - input : c.in
+ output : c.out
+ - input : d.in
+ output : d.out
+
+# 提交语言限制
+# 列举出所有本题允许使用的语言对应的代码(需要和评测机 lang.yaml 内的语言代码相同)
+# 使用语言ID而非名称!对于有子类的选项,请详细至子分类!
+langs :
+ - c
+ - cc
+ - cc.cc11o2
+ - pas
+
+# 时间内存倍率
+# 对某语言设置时间或内存倍率(需要和评测机 lang.yaml 内的语言代码相同)
+# 部分语言默认已存在倍率,请前往控制面板中查看!
+# 使用语言ID而非名称!对于有子类的选项,请详细至子分类!
+time_limit_rate :
+ py.py3 : 2
+memory_limit_rate :
+ java : 1.5
+
可以在 此题库open in new window 中找到各种类型题目的配置示例。
Prev
题目
Next
Hydro Problem Format
+
+
+
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 00000000..98d24cb7
Binary files /dev/null and b/favicon.ico differ
diff --git a/favicon.png b/favicon.png
new file mode 100644
index 00000000..fc4452e8
Binary files /dev/null and b/favicon.png differ
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..9620c314
--- /dev/null
+++ b/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ Hydro
+
+
+
+
+
+
+
+
+
diff --git a/plugins/elastic.html b/plugins/elastic.html
new file mode 100644
index 00000000..864854a6
--- /dev/null
+++ b/plugins/elastic.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ Elastic search | Hydro
+
+
+
+
+
+ Skip to main content
Elastic search Tips
此插件需配合第三方软件 Elasticsearch 使用,如仅安装插件不配置/不安装第三方软件 会导致系统无法正常运行,Elasticsearch 并非轻量化软件,如您的服务器不满足该软件要求不建议安装。
安装 Elasticsearch 后安装 @hydrooj/elastic-search
插件。
进入 HydroOJ 控制面板,在系统设置内正确填写 endpoint
。
然后在脚本管理中找到重建题目索引,点击运行,参数留空即可。
至此,搜索功能应当可以正常使用。
Prev
migrate
Next
recaptcha
+
+
+
diff --git a/plugins/fps-importer.html b/plugins/fps-importer.html
new file mode 100644
index 00000000..b7cc3cee
--- /dev/null
+++ b/plugins/fps-importer.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ fps-importer | Hydro
+
+
+
+
+
+ Skip to main content
fps-importer 在题库右侧“创建题目”一栏中选择“从 FPS 文件导入”。 在打开的窗口中,您可以上传:
fps 格式的 xml 文件 zip 文件,其中包含了一个或多个 fps 格式的 xml 文件 由于防止解析 fps 文件消耗大量内存,系统默认拒绝导入超过 64MiB 的文件; xml 文件需要为 UTF8 编码,否则可能出现中文题面乱码; 在新版本 fps-importer 中,管理员可以修改导入文件大小限制,但请注意,我们仍不建议您导入过大的题目包。 若您的文件超过大小限制,可考虑先在本地使用 Easy-Fps-Viewer 等工具进行拆分。
Prev
插件
Next
hydrojudge
+
+
+
diff --git a/plugins/geoip.html b/plugins/geoip.html
new file mode 100644
index 00000000..545e8c7b
--- /dev/null
+++ b/plugins/geoip.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ GeoIP | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/plugins/hydrojudge.html b/plugins/hydrojudge.html
new file mode 100644
index 00000000..68dcffb1
--- /dev/null
+++ b/plugins/hydrojudge.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+ hydrojudge | Hydro
+
+
+
+
+
+ Skip to main content
hydrojudge Tips
您可以通过一键安装脚本快速安装独立评测机,详情请前往 部署Hydro 查看。
在配置评测机之前,请确认您的站点已经可以访问并正常登录/注册。
您应该预先下载您所要支持的语言的编译器,若您在配置完评测机后 升级/重新安装 了编译器,您需要重新启动沙箱。 关于编译器说明,请参照 编译器 章节。
如果不使用自动脚本,您需要按照如下方式手动安装沙箱服务: 前往 criyle/go-judgeopen in new window 下载对应 cpu 架构的 go-judge。 go-judge 需要在后台运行并监听 127.0.0.1:5050
。如果系统使用的 cgroup 版本为 1 或者使用的为非 systemd init 的发行版,请以 root 权限 运行。 可使用 pm2 进行管理。
Tips
由于用附加组件安装的评测机与 Hydro 必须在同一台服务器上,每一个 Hydro 实例最多只能有一台评测机由附加组件安装。
在安装 Hydro 的机器上运行下面的指令安装 @hydrooj/hydrojudge
:
yarn global add @hydrooj/hydrojudge
+hydrooj addon add @hydrooj/hydrojudge
+
重启 Hydro 后 hydrojudge 即可正常运行。
Tips
该方法可以帮助您在任意服务器上部署评测机。
首先需要创建一个有 PRIV_JUDGE 权限的账户,具体方法参照 此处 。(在部署 Hydro 的服务器上运行)
然后在运行评测机的服务器上安装 HydroJudge :
. <( curl https://hydro.ac/setup.sh ) --judge
+
创建目录 ~/.config/hydro
,在该目录下创建文件 judge.yaml
,配置文件格式如下:
hosts :
+ localhost :
+ type : hydro # vj4 用户请在此处填写 vj4
+ server_url : http://localhost/ # Hydro 运行的网址
+ uname : judge # 评测账号用户名
+ password : abc123 # 评测账号密码
+ detail : true # 默认为 true
+
设置完之后,使用下面的指令即可开始运行(可以使用 pm2 管理):
HydroJudge 会发布不定期更新。您可以使用 yarn global upgrade-interactive --latest
来检测并进行更新。
在 系统设置>hydrojudge 中有一栏 Disable builtin judge,将它勾上,然后重启 Hydro 即可。
根据开启的方法关闭即可。
关闭后运行下面指令即可。
yarn global remove @hydrooj/hydrojudge
+hydrooj addon remove @hydrooj/hydrojudge
+
在 系统设置>hydrojudge 修改对应的参数,然后重启 Hydro 和 hydrojudge 即可。
如果有需要修改单题测试点数量上限等设置,可以在 ~/.config/hydro/judge.yaml
的末尾添加下列内容:
testcases_max : 100 # 单题最多测试点数量
+total_time_limit : 120 # 单题最大总测试时长
+parallelism : 2 # 单评测机评测进程数量
+# 更多可选配置均可添加在此处,格式与前面的三排类似
+
在 此处open in new window 的设置均可添加到此处。
对于已安装内置评测机的用户(无论内置评测机是否启动),在 控制面板>系统设置 中修改 judge.langs 配置项即可;对于没有安装内置评测机的用户,需要在 ~/.config/hydro/langs.yaml
中配置。
文件格式参照 此处open in new window 。
如果您添加了新的语言,您还需要前往 控制面板>系统设置 中修改 Language Highlight ID 与 Monaco language modes。 分别表示选择对应的语言后的高亮设置(基于 PrismJS)和 Monaco 编辑器语法规则设置。
修改完后请重启 Hydro 和 hydrojudge 。
参照 测试数据格式 配置。
Warning
如果不调整沙箱的空间大小,当您的评测使用文件 IO 且输入输出文件较大时可能会引发错误。
对于 2022/8/12 前安装的用户:
在服务器上运行下面的代码找到 hydro-sandbox 的运行目录:
pm2 info hydro-sandbox | grep " exec cwd "
+
将 mount.yamlopen in new window 下载并放置在 sandbox 的运行目录下。然后修改第 64 行和第 68 行的 size
和 nr_inodes
的大小至您想要的大小,保存后重启 sandbox 即可完成更改。
对于 2022/8/12 后安装的用户:
编辑 /root/.hydro/mount.yaml
,修改 size 即可。
确认您安装了支持彩色输出的编译器; 在系统设置中,将 C/C++ 编译命令后加上 -fdiagnostics-color=always
例:
c :
+ compile : /usr/bin/gcc -O2 -Wall -std=c99 -o ${name} foo.c -lm -fdiagnostics-color=always
+
2022/8/12 后安装的实例默认已开启无限栈空间,无需手动操作
在很多时候系统默认为程序提供的栈空间并不能满足我们的需求,此时我们需要手动为用户程序提供更大的栈空间。
修改 pm2 中 hydro-sandbox 的启动参数为 ulimit -s unlimited && /usr/bin/hydro-sandbox
:
pm2 del hydro-sandbox
+pm2 start bash --name hydro-sandbox -- -c " ulimit -s unlimited && hydro-sandbox "
+
禁用 CPU 频率缩放与 Intel 睿频加速技术,防止 CPU 频率波动。
禁用内存地址空间随机化,以使得存在内存寻址错误的代码能够得到更多可重复的结果,可以通过在 /etc/sysctl.conf
中添加下面这行并运行 sudo sysctl -p
应用:
kernel.randomize_va_space = 0
+
在控制面板上出现内容为 You are using cgroup v2 without kernel 5.19+. This could result in inaccurate memory usage measurements.
警告时,意味着当前系统的内存消耗计量存在误差。
部分 Linux 设备默认使用 cgroup2,而在 5.19 版本前的内核的 cgroup2 中移除了精确计量内存消耗的接口。 若要获得更精确的内存计量,推荐启用 cgroup v1 (您可以通过检查 /sys/fs/cgroup/memory/memory.memsw.usage_in_bytes
是否存在来验证是否当前系统是否启用了 cgroup v1 ):
以 Ubuntu 的默认引导器 GRUB 2 为例,编辑 /etc/default/grub
: 在其中
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
+
后,加入 `cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0,变为:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0"
+
运行以下命令更新 GRUB 2 的配置,然后重新启动。
Prev
fps-importer
Next
migrate
+
+
+
diff --git a/plugins/index.html b/plugins/index.html
new file mode 100644
index 00000000..ed588d52
--- /dev/null
+++ b/plugins/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+ 插件 | Hydro
+
+
+
+
+
+ Skip to main content
插件 Hydro 支持使用插件扩展自身所支持的功能。
Warning
插件对站点的所有内容具有完全的访问权限,请不要启用来历不明的插件。
Tips
部分插件(斜体标注)需配合第三方软件使用,如仅安装不配置/不安装第三方软件 会导致系统无法正常运行,详情请前往左侧插件详情查看。
Hydro 官方目前提供了以下附加组件:
ID 描述 @hydrooj/blog 博客功能 @hydrooj/fps-importer 导入 fps 格式的题目 @hydrooj/geoip 显示用户登录地(需要IP库支持) @hydrooj/hydrojudge 评测组件 @hydrooj/import-qduoj 导入 QDUOJ 导出的题库 @hydrooj/import-hoj 导入 HOJ 导出的题库 @hydrooj/login-with-github 允许用户使用 GitHub 登录 @hydrooj/login-with-google 允许用户使用 Google 登录 @hydrooj/migrate 从 vijos4/HustOJ/SYZOJ/UniversalOJ 升级 @hydrooj/recaptcha 注册时启用 reCAPTCHA 验证码 @hydrooj/ui-default Hydro 的默认用户界面 @hydrooj/onlyoffice 显示 doc/docx 格式题目 @hydrooj/sonic 基于 sonic 的题目搜索增强(需安装 sonic) @hydrooj/elastic-search 基于 Elastic 的题目搜索增强(需安装 Elastic) @hydrooj/vjudge Codeforces/SPOJ/UOJ/POJ/Luogu @hydrooj/prom-client 导出系统状态至 Prometheus
大部分插件的配置均可在安装后于 控制面板>系统设置 中找到。
部分插件若安装后没有正确配置可能会影响系统正常使用!
先全局安装所需模块,再向 hydrooj 注册即可。例:安装 @hydrooj/geoip
yarn global add @hydrooj/geoip
+hydrooj addon add @hydrooj/geoip
+
或者,如果你正在安装一个其他途径获取的插件(自行创建等),请直接使用文件夹 绝对路径 : (文件夹路径即为 包含 package.json 的文件夹)
hydrooj addon add /root/xxx
+
请不要将插件与插件嵌套摆放,否则可能会导致一些不可预知的问题。
安装完插件后需要重启 hydrooj 以使插件生效。
yarn global upgrade-interactive --latest
+
yarn global remove @hydrooj/geoip
+hydrooj addon remove @hydrooj/geoip
+
Next
fps-importer
+
+
+
diff --git a/plugins/migrate.html b/plugins/migrate.html
new file mode 100644
index 00000000..ad008d61
--- /dev/null
+++ b/plugins/migrate.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ migrate | Hydro
+
+
+
+
+
+ Skip to main content
migrate Warning
迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 HUSTOJ 的数据。 请注意备份相关文件。
请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 HUSTOJ 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 HUSTOJ 数据库相同。
安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateHustoj
的脚本。 其参数格式如下:
{ " host " : " localhost " , " port " : 3306 , " name " : " jol " , " username " : "" , " password " : "" , " domainId " : " system " , " contestType " : "" , " dataDir " : "" , " uploadDir " : "" }
+
host: 数据库地址 port: 数据库端口 name: 数据库名,一般为 jol
username&password: 账号密码,若无则填写空字符串 domainId: 迁入的域,默认为 system
contestType: oi
或者 acm
,视情况而定 dataDir: HUSTOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理) uploadDir: HUSTOJ 中 上传文件的位置(这里存储着上传的图片和文件等信息,默认已指定 /home/judge/src/web/upload/
,如果此路径与您路径相同,请不要填写此项) 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 HUSTOJ 的管理员账号登录实例。
SYZOJ 与 HUSTOJ 迁移方法类似,迁移脚本应运行名为 migrateSyzoj
的脚本外,SYZOJ无需 contestType
参数。 其参数格式如下:
{ " host " : " localhost " , " port " : 3306 , " name " : " syzoj " , " username " : "" , " password " : "" , " domainId " : " system " , " dataDir " : "" }
+
host: 数据库地址 port: 数据库端口 name: 数据库名,一般为 syzoj
username&password: 账号密码,若无则填写空字符串 domainId: 迁入的域,默认为 system
dataDir: SYZOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理) 由于SYZOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 SYZOJ 的管理员账号登录实例。
UniversalOJ (常称作UOJ社区版)与前两者迁移方法类似,迁移脚本应运行名为 migrateUniversalOJ
的脚本。
由于其升级过程较为麻烦,安装脚本已提供自动升级服务,如您需要可运行安装脚本一键迁移,手动迁移请在开发群中提问。
由于UniversalOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 UniversalOJ 的管理员账号登录实例。
Warning
迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 vj4 的数据。 请注意备份相关文件。
请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 vj4 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 vj4 数据库相同。 若您使用 vj4-docker ,可更改 docker-compose.yml
将数据库映射至其他本机端口。
安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateVijos
的脚本。 其参数格式如下:
{ " host " : " localhost " , " port " : 27017 , " name " : " vj4 " , " username " : "" , " password " : "" }
+
host: 数据库地址 port: 数据库端口 name: 数据库名 username&password: 账号密码,若无则填写空字符串 Tips
vj4-docker 中数据库名为 vj4,无账号密码。
当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 vj4 的管理员账号登录实例。
Warning
若您的 vj4 是由 vj2 或 tyvj 升级而来,在迁移完成后请不要卸载该插件,否则可能导致部分用户无法登录。
Prev
hydrojudge
Next
Elastic search
+
+
+
diff --git a/plugins/recaptcha.html b/plugins/recaptcha.html
new file mode 100644
index 00000000..196e67b5
--- /dev/null
+++ b/plugins/recaptcha.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+ recaptcha | Hydro
+
+
+
+
+
+
+
+
+
diff --git a/plugins/sonic.html b/plugins/sonic.html
new file mode 100644
index 00000000..fceddc55
--- /dev/null
+++ b/plugins/sonic.html
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+ Sonic | Hydro
+
+
+
+
+
+ Skip to main content
Sonic 使用 root 用户执行如下命令:
nix-env -iA nixpkgs.sonic-server
+
使用 root 用户执行如下命令:
yarn global add @hydrooj/sonic
+hydrooj addon add @hydrooj/sonic
+
在 /root/.sonic/config.cfg
(没有的自行建立,也可以换成其他的你喜欢的路径)按照以下配置示例写入配置。
配置示例:
# Sonic
+# Fast, lightweight and schema-less search backend
+# Configuration file
+# Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg
+
+
+[server]
+
+log_level = "error"
+
+
+[channel]
+
+inet = "127.0.0.1:1491" # 默认监听本机
+tcp_timeout = 300
+
+auth_password = "SecretPassword"
+
+[channel.search]
+
+query_limit_default = 10
+query_limit_maximum = 100
+query_alternates_try = 4
+
+suggest_limit_default = 5
+suggest_limit_maximum = 20
+
+
+[store]
+
+[store.kv]
+
+path = "/data/sonic/store/kv/"
+
+retain_word_objects = 1000
+
+[store.kv.pool]
+
+inactive_after = 1800
+
+[store.kv.database]
+
+flush_after = 900
+
+compress = true
+parallelism = 2
+max_files = 100
+max_compactions = 1
+max_flushes = 1
+write_buffer = 16384
+write_ahead_log = true
+
+[store.fst]
+
+path = "/data/sonic/store/fst/"
+
+[store.fst.pool]
+
+inactive_after = 300
+
+[store.fst.graph]
+
+consolidate_after = 180
+
+max_size = 2048
+max_words = 250000
+
执行如下命令:
pm2 start sonic -- -c /root/.sonic/config.cfg
+pm2 save
+
进入 HydroOJ 控制面板,配置 sonic 后端地址。
如果您直接复制配置示例,那么按照以下内容配置:
host: 127.0.0.1
port: 1491
auth: SecretPassword
修改完成后,重启 HydroOJ。
执行命令 pm2 restart hydrooj
。
进入 HydroOJ 控制面板,在脚本管理中找到重建题目索引,点击运行,参数留空即可。
至此,搜索功能应当可以正常使用。
请更新到 HydroOJ 最新版本后,再运行重建题目索引。
Prev
recaptcha
Next
VJudge
+
+
+
diff --git a/plugins/vjudge.html b/plugins/vjudge.html
new file mode 100644
index 00000000..de758b61
--- /dev/null
+++ b/plugins/vjudge.html
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+ VJudge | Hydro
+
+
+
+
+
+ Skip to main content
VJudge Warning
此文档已过时,仅作留存使用,以下教程仅为示例,如想了解详细安装方法请前往 FAQS(常用教程) 查看具体使用指南。
部分支持的远程站点对提交数量/访问次数/访问来源有一定限制,Hydro 不保证 VJudge 的 100% 可用性。
安装插件后创建名为 codeforces 的域,进入数据库 db.domain.updateOne({_id:'codeforces'},{$set:{mount:'codeforces'}});
在 codeforces 的域设置中,将 allowedLangs
如下配置(在新版即在允许提交的语言中选中所有 codeforces
开头的语言):
codeforces,codeforces.43,codeforces.52,codeforces.50,codeforces.54,codeforces.59,codeforces.61,codeforces.65,codeforces.9,codeforces.28,codeforces.32,codeforces.12,codeforces.60,codeforces.36,codeforces.48,codeforces.19,codeforces.3,codeforces.4,codeforces.51,codeforces.13,codeforces.6,codeforces.7,codeforces.31,codeforces.40,codeforces.41,codeforces.67,codeforces.49,codeforces.20,codeforces.34,codeforces.55
+
在 vjudge 表中插入如下条目:
{ type : ' codeforces ' , handle : ' <codeforces login handle> ' , password : ' <codeforces login password> ' }
+
将如下配置添加至 langs 设置末尾:
codeforces :
+ execute : none
+ display : Codeforces
+ domain :
+ - codeforces # Allow domain 'codeforces' to use these languages
+codeforces.43 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : GNU GCC C11 5.1.0
+ comment : //
+codeforces.52 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : Clang++17 Diagnostics
+ comment : //
+codeforces.50 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : GNU G++14 6.4.0
+ comment : //
+codeforces.54 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : GNU G++17 7.3.0
+ comment : //
+codeforces.59 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : Microsoft Visual C++ 2017
+ comment : //
+codeforces.61 :
+ highlight : cpp astyle-c
+ monaco : cpp
+ display : GNU G++17 9.2.0 (64 bit, msys 2)
+ comment : //
+codeforces.65 :
+ highlight : cpp astyle-cs
+ monaco : csharp
+ display : C# 8, .NET Core 3.1
+ comment : //
+codeforces.9 :
+ highlight : cpp astyle-cs
+ monaco : csharp
+ display : C# Mono 6.8
+ comment : //
+codeforces.28 :
+ highlight : d
+ monaco : plain
+ display : D DMD32 v2.091.0
+ comment : //
+codeforces.32 :
+ highlight : go
+ display : Go 1.15.6
+ comment : //
+codeforces.12 :
+ highlight : haskell
+ display : Haskell GHC 8.10.1
+ comment : --
+codeforces.60 :
+ highlight : java astyle-java
+ monaco : java
+ display : Java 11.0.6
+ comment : //
+codeforces.36 :
+ highlight : java astyle-java
+ monaco : java
+ display : Java 1.8.0_241
+ comment : //
+codeforces.48 :
+ highlight : kotlin
+ display : Kotlin 1.4.0
+ comment : //
+codeforces.19 :
+ highlight : ocaml
+ monaco : plain
+ display : OCaml 4.02.1
+ comment : [ ' (* ' , ' *) ' ]
+codeforces.3 :
+ highlight : pascal
+ display : Delphi 7
+ comment : //
+codeforces.4 :
+ highlight : pascal
+ display : Free Pascal 3.0.2
+ comment : //
+codeforces.51 :
+ highlight : pascal
+ display : PascalABC.NET 3.4.2
+ comment : //
+codeforces.13 :
+ highlight : perl
+ display : Perl 5.20.1
+ comment : ' # '
+codeforces.6 :
+ highlight : php
+ display : PHP 7.2.13
+ comment : //
+codeforces.7 :
+ highlight : python
+ display : Python 2.7.18
+ comment : ' # '
+codeforces.31 :
+ highlight : python
+ display : Python 3.9.1
+ comment : ' # '
+codeforces.40 :
+ highlight : python
+ display : PyPy 2.7 (7.3.0)
+ comment : ' # '
+codeforces.41 :
+ highlight : python
+ display : PyPy 3.7 (7.3.0)
+ comment : ' # '
+codeforces.67 :
+ highlight : ruby
+ display : Ruby 3.0.0
+ comment : ' # '
+codeforces.49 :
+ highlight : rust
+ display : Rust 1.49.0
+ comment : //
+codeforces.20 :
+ highlight : scala
+ display : Scala 2.12.8
+ comment : //
+codeforces.34 :
+ highlight : javascript
+ display : JavaScript V8 4.8.0
+ comment : //
+codeforces.55 :
+ highlight : javascript
+ display : Node.js 12.6.3
+ comment : //
+
之后再重启 Hydro 即可。
Prev
Sonic
Next
GeoIP
+
+
+
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 00000000..ab7930f8
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,5 @@
+
+User-agent:*
+Disallow:
+
+Sitemap: https://hydro.js.org/sitemap.xml
diff --git a/search-pro.worker.js b/search-pro.worker.js
new file mode 100644
index 00000000..88274a69
--- /dev/null
+++ b/search-pro.worker.js
@@ -0,0 +1,2 @@
+const nt="ENTRIES",V="KEYS",T="VALUES",F="";class D{set;_type;_path;constructor(t,s){const n=t._tree,u=Array.from(n.keys());this.set=t,this._type=s,this._path=u.length>0?[{node:n,keys:u}]:[]}next(){const t=this.dive();return this.backtrack(),t}dive(){if(this._path.length===0)return{done:!0,value:void 0};const{node:t,keys:s}=E(this._path);if(E(s)===F)return{done:!1,value:this.result()};const n=t.get(E(s));return this._path.push({node:n,keys:Array.from(n.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const t=E(this._path).keys;t.pop(),!(t.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:t})=>E(t)).filter(t=>t!==F).join("")}value(){return E(this._path).node.get(F)}result(){switch(this._type){case T:return this.value();case V:return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}const E=e=>e[e.length-1],ut=(e,t,s)=>{const n=new Map;if(t===void 0)return n;const u=t.length+1,o=u+s,i=new Uint8Array(o*u).fill(s+1);for(let r=0;r{const d=o*i;t:for(const l of e.keys())if(l===F){const a=u[d-1];a<=s&&n.set(r,[e.get(l),a])}else{let a=o;for(let h=0;hs)continue t}R(e.get(l),t,s,n,u,a,i,r+l)}};class C{_tree;_prefix;_size=void 0;constructor(t=new Map,s=""){this._tree=t,this._prefix=s}atPrefix(t){if(!t.startsWith(this._prefix))throw new Error("Mismatched prefix");const[s,n]=x(this._tree,t.slice(this._prefix.length));if(s===void 0){const[u,o]=M(n);for(const i of u.keys())if(i!==F&&i.startsWith(o)){const r=new Map;return r.set(i.slice(o.length),u.get(i)),new C(r,t)}}return new C(s,t)}clear(){this._size=void 0,this._tree.clear()}delete(t){return this._size=void 0,ot(this._tree,t)}entries(){return new D(this,nt)}forEach(t){for(const[s,n]of this)t(s,n,this)}fuzzyGet(t,s){return ut(this._tree,t,s)}get(t){const s=I(this._tree,t);return s!==void 0?s.get(F):void 0}has(t){const s=I(this._tree,t);return s!==void 0&&s.has(F)}keys(){return new D(this,V)}set(t,s){if(typeof t!="string")throw new Error("key must be a string");return this._size=void 0,O(this._tree,t).set(F,s),this}get size(){if(this._size)return this._size;this._size=0;const t=this.entries();for(;!t.next().done;)this._size+=1;return this._size}update(t,s){if(typeof t!="string")throw new Error("key must be a string");this._size=void 0;const n=O(this._tree,t);return n.set(F,s(n.get(F))),this}fetch(t,s){if(typeof t!="string")throw new Error("key must be a string");this._size=void 0;const n=O(this._tree,t);let u=n.get(F);return u===void 0&&n.set(F,u=s()),u}values(){return new D(this,T)}[Symbol.iterator](){return this.entries()}static from(t){const s=new C;for(const[n,u]of t)s.set(n,u);return s}static fromObject(t){return C.from(Object.entries(t))}}const x=(e,t,s=[])=>{if(t.length===0||e==null)return[e,s];for(const n of e.keys())if(n!==F&&t.startsWith(n))return s.push([e,n]),x(e.get(n),t.slice(n.length),s);return s.push([e,t]),x(void 0,"",s)},I=(e,t)=>{if(t.length===0||e==null)return e;for(const s of e.keys())if(s!==F&&t.startsWith(s))return I(e.get(s),t.slice(s.length))},O=(e,t)=>{const s=t.length;t:for(let n=0;e&&n{const[s,n]=x(e,t);if(s!==void 0){if(s.delete(F),s.size===0)W(n);else if(s.size===1){const[u,o]=s.entries().next().value;q(n,u,o)}}},W=e=>{if(e.length===0)return;const[t,s]=M(e);if(t.delete(s),t.size===0)W(e.slice(0,-1));else if(t.size===1){const[n,u]=t.entries().next().value;n!==F&&q(e.slice(0,-1),n,u)}},q=(e,t,s)=>{if(e.length===0)return;const[n,u]=M(e);n.set(u+t,s),n.delete(u)},M=e=>e[e.length-1],it=(e,t)=>{const s=e._idToShortId.get(t);if(s!=null)return e._storedFields.get(s)},rt=/[\n\r -#%-*,-/:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]+/u,S="or",$="and",ct="and_not",lt=(e,t)=>{e.includes(t)||e.push(t)},P=(e,t)=>{for(const s of t)e.includes(s)||e.push(s)},G=({score:e},{score:t})=>t-e,ht=()=>new Map,k=e=>{const t=new Map;for(const s of Object.keys(e))t.set(parseInt(s,10),e[s]);return t},N=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0,dt={[S]:(e,t)=>{for(const s of t.keys()){const n=e.get(s);if(n==null)e.set(s,t.get(s));else{const{score:u,terms:o,match:i}=t.get(s);n.score=n.score+u,n.match=Object.assign(n.match,i),P(n.terms,o)}}return e},[$]:(e,t)=>{const s=new Map;for(const n of t.keys()){const u=e.get(n);if(u==null)continue;const{score:o,terms:i,match:r}=t.get(n);P(u.terms,i),s.set(n,{score:u.score+o,terms:u.terms,match:Object.assign(u.match,r)})}return s},[ct]:(e,t)=>{for(const s of t.keys())e.delete(s);return e}},at=(e,t,s,n,u,o)=>{const{k:i,b:r,d}=o;return Math.log(1+(s-t+.5)/(t+.5))*(d+e*(i+1)/(e+i*(1-r+r*n/u)))},ft=e=>(t,s,n)=>{const u=typeof e.fuzzy=="function"?e.fuzzy(t,s,n):e.fuzzy||!1,o=typeof e.prefix=="function"?e.prefix(t,s,n):e.prefix===!0;return{term:t,fuzzy:u,prefix:o}},H=(e,t,s,n)=>{for(const u of Object.keys(e._fieldIds))if(e._fieldIds[u]===s){e._options.logger("warn",`SlimSearch: document with ID ${e._documentIds.get(t)} has changed before removal: term "${n}" was not present in field "${u}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}},gt=(e,t,s,n)=>{if(!e._index.has(n)){H(e,s,t,n);return}const u=e._index.fetch(n,ht),o=u.get(t);o==null||o.get(s)==null?H(e,s,t,n):o.get(s)<=1?o.size<=1?u.delete(t):o.delete(s):o.set(s,o.get(s)-1),e._index.get(n).size===0&&e._index.delete(n)},mt={k:1.2,b:.7,d:.5},pt={idField:"id",extractField:(e,t)=>e[t],tokenize:e=>e.split(rt),processTerm:e=>e.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(e,t)=>{typeof console?.[e]=="function"&&console[e](t)},autoVacuum:!0},J={combineWith:S,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:mt},Ft={combineWith:$,prefix:(e,t,s)=>t===s.length-1},_t={batchSize:1e3,batchWait:10},U={minDirtFactor:.1,minDirtCount:20},yt={..._t,...U},Y=(e,t=S)=>{if(e.length===0)return new Map;const s=t.toLowerCase();return e.reduce(dt[s])||new Map},B=(e,t,s,n,u,o,i,r,d=new Map)=>{if(u==null)return d;for(const l of Object.keys(o)){const a=o[l],h=e._fieldIds[l],m=u.get(h);if(m==null)continue;let p=m.size;const f=e._avgFieldLength[h];for(const c of m.keys()){if(!e._documentIds.has(c)){gt(e,h,c,s),p-=1;continue}const g=i?i(e._documentIds.get(c),s,e._storedFields.get(c)):1;if(!g)continue;const _=m.get(c),y=e._fieldLength.get(c)[h],b=at(_,p,e._documentCount,y,f,r),z=n*a*g*b,A=d.get(c);if(A){A.score+=z,lt(A.terms,t);const w=N(A.match,s);w?w.push(l):A.match[s]=[l]}else d.set(c,{score:z,terms:[t],match:{[s]:[l]}})}}return d},At=(e,t,s)=>{const n={...e._options.searchOptions,...s},u=(n.fields||e._options.fields).reduce((c,g)=>({...c,[g]:N(n.boost,g)||1}),{}),{boostDocument:o,weights:i,maxFuzzy:r,bm25:d}=n,{fuzzy:l,prefix:a}={...J.weights,...i},h=e._index.get(t.term),m=B(e,t.term,t.term,1,h,u,o,d);let p,f;if(t.prefix&&(p=e._index.atPrefix(t.term)),t.fuzzy){const c=t.fuzzy===!0?.2:t.fuzzy,g=c<1?Math.min(r,Math.round(t.term.length*c)):c;g&&(f=e._index.fuzzyGet(t.term,g))}if(p)for(const[c,g]of p){const _=c.length-t.term.length;if(!_)continue;f?.delete(c);const y=a*c.length/(c.length+.3*_);B(e,t.term,c,y,g,u,o,d,m)}if(f)for(const c of f.keys()){const[g,_]=f.get(c);if(!_)continue;const y=l*c.length/(c.length+_);B(e,t.term,c,y,g,u,o,d,m)}return m},X=(e,t,s={})=>{if(typeof t!="string"){const a={...s,...t,queries:void 0},h=t.queries.map(m=>X(e,m,a));return Y(h,a.combineWith)}const{tokenize:n,processTerm:u,searchOptions:o}=e._options,i={tokenize:n,processTerm:u,...o,...s},{tokenize:r,processTerm:d}=i,l=r(t).flatMap(a=>d(a)).filter(a=>!!a).map(ft(i)).map(a=>At(e,a,i));return Y(l,i.combineWith)},K=(e,t,s={})=>{const n=X(e,t,s),u=[];for(const[o,{score:i,terms:r,match:d}]of n){const l=r.length,a={id:e._documentIds.get(o),score:i*l,terms:Object.keys(d),match:d};Object.assign(a,e._storedFields.get(o)),(s.filter==null||s.filter(a))&&u.push(a)}return u.sort(G),u},Ct=(e,t,s={})=>{s={...e._options.autoSuggestOptions,...s};const n=new Map;for(const{score:o,terms:i}of K(e,t,s)){const r=i.join(" "),d=n.get(r);d!=null?(d.score+=o,d.count+=1):n.set(r,{score:o,terms:i,count:1})}const u=[];for(const[o,{score:i,terms:r,count:d}]of n)u.push({suggestion:o,terms:r,score:i/d});return u.sort(G),u};class Et{_options;_index;_documentCount;_documentIds;_idToShortId;_fieldIds;_fieldLength;_avgFieldLength;_nextId;_storedFields;_dirtCount;_currentVacuum;_enqueuedVacuum;_enqueuedVacuumConditions;constructor(t){if(t?.fields==null)throw new Error('SlimSearch: option "fields" must be provided');const s=t.autoVacuum==null||t.autoVacuum===!0?yt:t.autoVacuum;this._options={...pt,...t,autoVacuum:s,searchOptions:{...J,...t.searchOptions||{}},autoSuggestOptions:{...Ft,...t.autoSuggestOptions||{}}},this._index=new C,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=U,this.addFields(this._options.fields)}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}get documentCount(){return this._documentCount}get termCount(){return this._index.size}toJSON(){const t=[];for(const[s,n]of this._index){const u={};for(const[o,i]of n)u[o]=Object.fromEntries(i);t.push([s,u])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:t,serializationVersion:2}}addFields(t){for(let s=0;s{if(l!==1&&l!==2)throw new Error("SlimSearch: cannot deserialize an index created with an incompatible version");const h=new Et(a);h._documentCount=t,h._nextId=s,h._documentIds=k(n),h._idToShortId=new Map,h._fieldIds=u,h._fieldLength=k(o),h._avgFieldLength=i,h._storedFields=k(r),h._dirtCount=d||0,h._index=new C;for(const[m,p]of h._documentIds)h._idToShortId.set(p,m);for(const[m,p]of e){const f=new Map;for(const c of Object.keys(p)){let g=p[c];l===1&&(g=g.ds),f.set(parseInt(c,10),k(g))}h._index.set(m,f)}return h},Q=Object.entries,wt=Object.fromEntries,j=(e,t)=>{const s=e.toLowerCase(),n=t.toLowerCase(),u=[];let o=0,i=0;const r=(l,a=!1)=>{let h="";i===0?h=l.length>20?`… ${l.slice(-20)}`:l:a?h=l.length+i>100?`${l.slice(0,100-i)}… `:l:h=l.length>20?`${l.slice(0,20)} … ${l.slice(-20)}`:l,h&&u.push(h),i+=h.length,a||(u.push(["mark",t]),i+=t.length,i>=100&&u.push(" …"))};let d=s.indexOf(n,o);if(d===-1)return null;for(;d>=0;){const l=d+n.length;if(r(e.slice(o,d)),o=l,i>100)break;d=s.indexOf(n,o)}return i<100&&r(e.slice(o),!0),u},Z=/[\u4e00-\u9fa5]/g,tt=(e={})=>({fuzzy:.2,prefix:!0,processTerm:t=>{const s=t.match(Z)||[],n=t.replace(Z,"").toLowerCase();return n?[n,...s]:[...s]},...e}),xt=(e,t)=>t.contents.reduce((s,[,n])=>s+n,0)-e.contents.reduce((s,[,n])=>s+n,0),kt=(e,t)=>Math.max(...t.contents.map(([,s])=>s))-Math.max(...e.contents.map(([,s])=>s)),et=(e,t,s={})=>{const n={};return K(t,e,tt({boost:{h:2,t:1,c:4},...s})).forEach(u=>{const{id:o,terms:i,score:r}=u,d=o.includes("@"),l=o.includes("#"),[a,h]=o.split(/[#@]/),m=i.sort((f,c)=>f.length-c.length).filter((f,c)=>i.slice(c+1).every(g=>!g.includes(f))),{contents:p}=n[a]??={title:"",contents:[]};if(d)p.push([{type:"customField",key:a,index:h,display:m.map(f=>u.c.map(c=>j(c,f))).flat().filter(f=>f!==null)},r]);else{const f=m.map(c=>j(u.h,c)).filter(c=>c!==null);if(f.length&&p.push([{type:l?"heading":"title",key:a,...l&&{anchor:h},display:f},r]),"t"in u)for(const c of u.t){const g=m.map(_=>j(c,_)).filter(_=>_!==null);g.length&&p.push([{type:"text",key:a,...l&&{anchor:h},display:g},r])}}}),Q(n).sort(([,u],[,o])=>"max"==="total"?xt(u,o):kt(u,o)).map(([u,{title:o,contents:i}])=>{if(!o){const r=it(t,u);r&&(o=r.h)}return{title:o,contents:i.map(([r])=>r)}})},st=(e,t,s={})=>Ct(t,e,tt(s)).map(({suggestion:n})=>n),v=wt(Q(JSON.parse("{\"/\":{\"documentCount\":224,\"nextId\":224,\"documentIds\":{\"0\":\"v-8daa1a0e\",\"1\":\"v-8daa1a0e#联系我们\",\"2\":\"v-8daa1a0e#开源许可\",\"3\":\"v-8daa1a0e#附加条款\",\"4\":\"v-8daa1a0e#鸣谢\",\"5\":\"v-74379e72\",\"6\":\"v-74379e72#好消息-本页和各大浏览器均达成了合作-使用-ctrl-f-即可快速搜索关键词\",\"7\":\"v-74379e72#更多教程请点击右上角的常用教程查看。\",\"8\":\"v-74379e72#用户qq群-1085853538\",\"9\":\"v-74379e72#如何快速上手了解系统功能\",\"10\":\"v-74379e72#什么是-oj\",\"11\":\"v-74379e72#arch-linux-开发模式安装时出现-err-stream-premature-close-premature-close-错误\",\"12\":\"v-74379e72#为什么我安装完成之后仍然无法访问\",\"13\":\"v-74379e72#为什么我配置完反向代理-caddy-nginx-之后无法登录-出现csrftokenerror\",\"14\":\"v-74379e72#怎么备份-还原备份-迁移数据\",\"15\":\"v-74379e72#恢复备份时出现-data-file-hydro-directory-not-empty\",\"16\":\"v-74379e72#更新升级\",\"17\":\"v-74379e72#怎么导入题目-创建题目\",\"18\":\"v-74379e72#如何限制未登录用户访问\",\"19\":\"v-74379e72#怎么添加页脚备案号\",\"20\":\"v-74379e72#比赛作业里面的时间是什么含义-oi排名跟普通排名有何区别\",\"21\":\"v-74379e72#脚本把-oj-装在哪里了\",\"22\":\"v-74379e72#题目的限时和内存限制的精度是怎样的\",\"23\":\"v-74379e72#我想让-python-支持-numpy-等等库-怎么办\",\"24\":\"v-74379e72#使用安装脚本后忘记-mongodb-的账号密码怎么办\",\"25\":\"v-74379e72#如何关闭、打开用户注册\",\"26\":\"v-74379e72#用户名为-hydro-的用户是干什么的-密码是什么-可以登录么\",\"27\":\"v-74379e72#如何修改网站图标\",\"28\":\"v-74379e72#如何重置数据\",\"29\":\"v-74379e72#评测显示-总时限超过-60s-评测取消\",\"30\":\"v-74379e72#如何在背景中添加线条特效\",\"31\":\"v-74379e72#使用-hydro-要花多少钱\",\"32\":\"v-74379e72#execve-no-such-file-or-directory\",\"33\":\"v-74379e72#怎么自定义用户标签\",\"34\":\"v-74379e72#为什么我无法批量下载多个文件\",\"35\":\"v-74379e72#为什么我的提交页面没有语言可选\",\"36\":\"v-74379e72#the-yarn-global-commands-have-been-remove-in-2-x-consider-using-yarn-dlx-or-a-third-party-plugin-instead\",\"37\":\"v-74379e72#我是机房用户-大量用户同-ip-操作触发了频率限制-怎么解决\",\"38\":\"v-744497ce\",\"39\":\"v-1a155670\",\"40\":\"v-1a155670#评测端交互流程\",\"41\":\"v-1a155670#websocket-连接建立流程\",\"42\":\"v-1a155670#语言配置下发\",\"43\":\"v-1a155670#评测任务推送\",\"44\":\"v-1a155670#测试数据下载\",\"45\":\"v-1a155670#评测结果上报\",\"46\":\"v-82f2a624\",\"47\":\"v-7445cd33\",\"48\":\"v-7445cd33#安装依赖\",\"49\":\"v-7445cd33#安装-hydro\",\"50\":\"v-7445cd33#插件\",\"51\":\"v-7445cd33#启动-hydro\",\"52\":\"v-7445cd33#更新\",\"53\":\"v-0a853913\",\"54\":\"v-0a853913#document\",\"55\":\"v-0a853913#document-status\",\"56\":\"v-0a853913#record\",\"57\":\"v-0a853913#user\",\"58\":\"v-0a853913#oplog\",\"59\":\"v-0a853913#blacklist\",\"60\":\"v-0a853913#system\",\"61\":\"v-0a853913#task\",\"62\":\"v-0a853913#event\",\"63\":\"v-0a853913#schedule\",\"64\":\"v-0a853913#opcount\",\"65\":\"v-0a853913#token\",\"66\":\"v-5c0c76d7\",\"67\":\"v-19b5347a\",\"68\":\"v-19b5347a#示例\",\"69\":\"v-1c6d3a3e\",\"70\":\"v-1c6d3a3e#变量命名规则\",\"71\":\"v-1c6d3a3e#函数命名规则\",\"72\":\"v-55131a51\",\"73\":\"v-55131a51#对接其他平台\",\"74\":\"v-5ddc85e1\",\"75\":\"v-5ddc85e1#step1-初始化项目\",\"76\":\"v-5ddc85e1#可选-在本机环境编写插件\",\"77\":\"v-5ddc85e1#step2-准备编写组件\",\"78\":\"v-5ddc85e1#step4-template\",\"79\":\"v-5ddc85e1#step5-locale\",\"80\":\"v-147825fb\",\"81\":\"v-147825fb#功能对比\",\"82\":\"v-147825fb#截图\",\"83\":\"v-147825fb#现在开始\",\"84\":\"v-67d16688\",\"85\":\"v-67d16688#附加组件列表\",\"86\":\"v-67d16688#安装\",\"87\":\"v-67d16688#查看已注册的插件列表\",\"88\":\"v-67d16688#更新\",\"89\":\"v-67d16688#卸载\",\"90\":\"v-d67234a8\",\"91\":\"v-6dd45d9b\",\"92\":\"v-6dd45d9b#从-fps-文件导入题目\",\"93\":\"v-16bdf429\",\"94\":\"v-a08ef0ec\",\"95\":\"v-a08ef0ec#准备\",\"96\":\"v-a08ef0ec#安装\",\"97\":\"v-a08ef0ec#作为附加组件\",\"98\":\"v-a08ef0ec#作为独立进程\",\"99\":\"v-a08ef0ec#更新\",\"100\":\"v-a08ef0ec#关闭\",\"101\":\"v-a08ef0ec#作为附加组件-1\",\"102\":\"v-a08ef0ec#作为独立进程-1\",\"103\":\"v-a08ef0ec#卸载\",\"104\":\"v-a08ef0ec#评测设置\",\"105\":\"v-a08ef0ec#作为附加组件-2\",\"106\":\"v-a08ef0ec#作为独立进程-2\",\"107\":\"v-a08ef0ec#修改编译选项-添加新语言支持\",\"108\":\"v-a08ef0ec#测试数据格式\",\"109\":\"v-a08ef0ec#调整沙箱空间大小\",\"110\":\"v-a08ef0ec#c-c-彩色编译错误信息\",\"111\":\"v-a08ef0ec#开大程序运行栈空间\",\"112\":\"v-a08ef0ec#提高测评精度\",\"113\":\"v-a08ef0ec#内存计量不准确\",\"114\":\"v-669bced4\",\"115\":\"v-669bced4#从-hustoj-升级\",\"116\":\"v-669bced4#从-syzoj-升级\",\"117\":\"v-669bced4#从-universaloj-升级\",\"118\":\"v-669bced4#从-vijos-升级\",\"119\":\"v-fa72264c\",\"120\":\"v-52692a96\",\"121\":\"v-52692a96#安装\",\"122\":\"v-52692a96#安装-sonic-server\",\"123\":\"v-52692a96#安装-sonic-插件\",\"124\":\"v-52692a96#启动\",\"125\":\"v-52692a96#配置\",\"126\":\"v-52692a96#后端地址配置\",\"127\":\"v-52692a96#重启-hydrooj\",\"128\":\"v-52692a96#重建题目索引\",\"129\":\"v-52692a96#faq\",\"130\":\"v-52692a96#安装后题目搜索不正常\",\"131\":\"v-3096c190\",\"132\":\"v-3096c190#codeforces\",\"133\":\"v-fe9aee22\",\"134\":\"v-fe9aee22#服务器选择\",\"135\":\"v-fe9aee22#部署\",\"136\":\"v-fdd5d9ea\",\"137\":\"v-fdd5d9ea#进阶\",\"138\":\"v-4def954c\",\"139\":\"v-4def954c#_2022-10-27-后使用脚本安装的实例已自动配置-caddy-反向代理-请直接编辑位于-hydro-caddyfile-的配置文件\",\"140\":\"v-6b4a62ea\",\"141\":\"v-6b4a62ea#使用-s3-作为存储后端\",\"142\":\"v-68002798\",\"143\":\"v-6d3257b0\",\"144\":\"v-0a40e55e\",\"145\":\"v-0a40e55e#资源-cdn\",\"146\":\"v-0a40e55e#全站-cdn\",\"147\":\"v-cceda784\",\"148\":\"v-cceda784#创建用户\",\"149\":\"v-cceda784#设置全站管理员\",\"150\":\"v-cceda784#设置用户权限\",\"151\":\"v-cceda784#更改用户密码\",\"152\":\"v-cceda784#创建评测账号\",\"153\":\"v-cceda784#黑名单相关\",\"154\":\"v-cceda784#命令列表\",\"155\":\"v-2250b6d9\",\"156\":\"v-2250b6d9#进入数据库\",\"157\":\"v-2250b6d9#快速备份与恢复\",\"158\":\"v-2250b6d9#手动备份\",\"159\":\"v-2250b6d9#手动恢复备份\",\"160\":\"v-023b4bae\",\"161\":\"v-023b4bae#修改页面翻译或是添加新语言\",\"162\":\"v-023b4bae#修改页面模板\",\"163\":\"v-69f3a96a\",\"164\":\"v-1bffc66e\",\"165\":\"v-1bffc66e#pm2\",\"166\":\"v-1bffc66e#进程名称\",\"167\":\"v-1bffc66e#pm2-基本指令\",\"168\":\"v-1bffc66e#更新\",\"169\":\"v-1bffc66e#查看已安装版本\",\"170\":\"v-1bffc66e#清除缓存\",\"171\":\"v-4e9d6767\",\"172\":\"v-4e9d6767#day-1-准备工作\",\"173\":\"v-4e9d6767#day-0-准备工作\",\"174\":\"v-4e9d6767#day-1-热身赛\",\"175\":\"v-4e9d6767#day-2-正式赛\",\"176\":\"v-666426ae\",\"177\":\"v-666426ae#题目难度\",\"178\":\"v-666426ae#参与比赛\",\"179\":\"v-666426ae#发布讨论\",\"180\":\"v-666426ae#认领作业\",\"181\":\"v-62edc12e\",\"182\":\"v-62edc12e#操作流程\",\"183\":\"v-62edc12e#限制\",\"184\":\"v-0566f368\",\"185\":\"v-0566f368#简介\",\"186\":\"v-0566f368#创建域\",\"187\":\"v-0566f368#初始化讨论节点\",\"188\":\"v-0566f368#访问控制\",\"189\":\"v-0566f368#创建比赛-作业\",\"190\":\"v-0566f368#创建训练\",\"191\":\"v-5e09d0a1\",\"192\":\"v-5e09d0a1#privilege\",\"193\":\"v-5e09d0a1#permission\",\"194\":\"v-5e09d0a1#角色\",\"195\":\"v-5e09d0a1#加入域\",\"196\":\"v-1d7ad3e6\",\"197\":\"v-1d7ad3e6#零-hydro题目存储格式\",\"198\":\"v-1d7ad3e6#一-制做最简单的oj题目\",\"199\":\"v-1d7ad3e6#二、函数交互型题目\",\"200\":\"v-1d7ad3e6#三-半对拍-自己指定评测程序并修改测试输出格式\",\"201\":\"v-1d7ad3e6#五-文件读写测试\",\"202\":\"v-1d7ad3e6#六-子任务测试\",\"203\":\"v-1d7ad3e6#七-客观题制做\",\"204\":\"v-1d7ad3e6#八-小结\",\"205\":\"v-dc52bc6a\",\"206\":\"v-07f380c3\",\"207\":\"v-07f380c3#创建题目\",\"208\":\"v-07f380c3#导入题目\",\"209\":\"v-07f380c3#从-hydro-导入\",\"210\":\"v-07f380c3#从-syzoj-导入\",\"211\":\"v-07f380c3#从-fps-文件导入\",\"212\":\"v-07f380c3#从-qduoj-导入\",\"213\":\"v-07f380c3#编辑\",\"214\":\"v-07f380c3#题面\",\"215\":\"v-07f380c3#标签\",\"216\":\"v-07f380c3#文件\",\"217\":\"v-07f380c3#客观题\",\"218\":\"v-07f380c3#题面-1\",\"219\":\"v-07f380c3#测试数据\",\"220\":\"v-51b3f914\",\"221\":\"v-51b3f914#自动模式\",\"222\":\"v-51b3f914#使用配置文件\",\"223\":\"v-723d0d85\"},\"fieldIds\":{\"h\":0,\"t\":1,\"c\":2},\"fieldLength\":{\"0\":[1,31],\"1\":[1,23],\"2\":[1,17],\"3\":[1,72],\"4\":[1,11],\"5\":[1],\"6\":[7],\"7\":[2],\"8\":[2],\"9\":[2,26],\"10\":[3,63],\"11\":[10,7],\"12\":[2,10],\"13\":[6,4],\"14\":[4,14],\"15\":[7,10],\"16\":[1,27],\"17\":[3,15],\"18\":[2,9],\"19\":[2,17],\"20\":[3,22],\"21\":[4,30],\"22\":[2,13],\"23\":[7,18],\"24\":[4,6],\"25\":[3,26],\"26\":[6,14],\"27\":[2,44],\"28\":[2,11],\"29\":[5,6],\"30\":[2,175],\"31\":[4,8],\"32\":[6,5],\"33\":[2,20],\"34\":[2,6],\"35\":[2,10],\"36\":[19,4],\"37\":[6,27],\"38\":[1,2],\"39\":[1,3],\"40\":[1,20],\"41\":[2,113],\"42\":[1,8],\"43\":[1,75],\"44\":[1,28],\"45\":[1,56],\"46\":[1,22],\"47\":[1,64],\"48\":[1,45],\"49\":[2,21],\"50\":[1,19],\"51\":[2,37],\"52\":[1,10],\"53\":[1],\"54\":[1,21],\"55\":[2,12],\"56\":[1,10],\"57\":[1,9],\"58\":[1,2],\"59\":[1],\"60\":[1],\"61\":[1,2],\"62\":[1,5],\"63\":[1,2],\"64\":[1,2],\"65\":[1,3],\"66\":[1,3],\"67\":[3,8],\"68\":[1,63],\"69\":[1],\"70\":[1,38],\"71\":[1,12],\"72\":[1,8],\"73\":[1,164],\"74\":[3,4],\"75\":[2,50],\"76\":[2,28],\"77\":[2,204],\"78\":[2,25],\"79\":[2,7],\"80\":[1,59],\"81\":[1,83],\"82\":[1],\"83\":[1,45],\"84\":[1,6],\"85\":[1,78],\"86\":[1,28],\"87\":[1,4],\"88\":[1,6],\"89\":[1,7],\"90\":[2,25],\"91\":[2],\"92\":[3,36],\"93\":[1,11],\"94\":[1,6],\"95\":[1,41],\"96\":[1],\"97\":[1,18],\"98\":[1,51],\"99\":[1,10],\"100\":[1],\"101\":[1,11],\"102\":[1,2],\"103\":[1,8],\"104\":[1],\"105\":[1,9],\"106\":[1,26],\"107\":[2,35],\"108\":[1,4],\"109\":[1,43],\"110\":[3,23],\"111\":[1,24],\"112\":[1,24],\"113\":[1,68],\"114\":[1],\"115\":[3,75],\"116\":[3,46],\"117\":[3,21],\"118\":[3,64],\"119\":[1,31],\"120\":[1],\"121\":[1],\"122\":[1,10],\"123\":[3,10],\"124\":[1,97],\"125\":[1],\"126\":[1,19],\"127\":[2,5],\"128\":[1,9],\"129\":[1],\"130\":[1,5],\"131\":[1,18],\"132\":[1,148],\"133\":[2,6],\"134\":[1,86],\"135\":[1,91],\"136\":[1,86],\"137\":[1,85],\"138\":[3],\"139\":[9,80],\"140\":[1,13],\"141\":[3,74],\"142\":[1,46],\"143\":[1,2],\"144\":[1,11],\"145\":[2,14],\"146\":[2,42],\"147\":[2,22],\"148\":[1,34],\"149\":[1,11],\"150\":[1,11],\"151\":[1,13],\"152\":[1,15],\"153\":[1,39],\"154\":[1,57],\"155\":[1],\"156\":[1,38],\"157\":[1,13],\"158\":[1,18],\"159\":[1,23],\"160\":[1,16],\"161\":[2,16],\"162\":[2,47],\"163\":[1,60],\"164\":[1],\"165\":[1,6],\"166\":[1,29],\"167\":[2,57],\"168\":[1,17],\"169\":[1,9],\"170\":[1,7],\"171\":[1,7],\"172\":[3,47],\"173\":[3,75],\"174\":[3,4],\"175\":[3,6],\"176\":[1],\"177\":[1,15],\"178\":[1,11],\"179\":[1,19],\"180\":[1,17],\"181\":[1,4],\"182\":[1,10],\"183\":[1,8],\"184\":[1],\"185\":[1,17],\"186\":[1,40],\"187\":[1,6],\"188\":[1,21],\"189\":[2,25],\"190\":[1,55],\"191\":[1,12],\"192\":[1,21],\"193\":[1,12],\"194\":[1,35],\"195\":[1,11],\"196\":[1,39],\"197\":[2,58],\"198\":[2,59],\"199\":[2,68],\"200\":[3,113],\"201\":[2,48],\"202\":[3,54],\"203\":[2,52],\"204\":[2,39],\"205\":[3,60],\"206\":[1],\"207\":[1,17],\"208\":[1],\"209\":[3,19],\"210\":[3,11],\"211\":[3,4],\"212\":[3,4],\"213\":[1],\"214\":[1,87],\"215\":[1,3],\"216\":[1,6],\"217\":[1],\"218\":[1,18],\"219\":[1,30],\"220\":[1],\"221\":[1,33],\"222\":[1,220],\"223\":[1]},\"averageFieldLength\":[1.8080357142857146,30.859358169572506],\"storedFields\":{\"0\":{\"h\":\"\",\"t\":[\"Hydro 是一个高效的信息学在线测评系统。特点:易于部署(且提供安装脚本),轻量,功能强大且易于扩展。\",\"Github 仓库\",\"欢迎 star 本项目,这是对开发者的鼓励。 项目的开发与维护需要资金,欢迎进行捐助。 Hydro 提供收费的功能定制服务,如您需要可与我们联系。 相关文档若说明的不够详细,请提交 Pull Request 或联系开发组说明。 Bug 和功能建议请在 Issues 提出。\",\"在 Gitpod 打开已配置完成的测试环境\",\"Hydro Online Judge\"]},\"1\":{\"h\":\"联系我们\",\"t\":[\"Email i@undefined.moe Telegram @undefinedmoe Hydro 用户群:1085853538\",\"注1:Hydro 为开源框架,任何人均能够在遵守协议的情况下使用这套框架。 版权申诉相关问题请联系对应网站管理者,(通常为其 UID=2 的用户),与开发者无关。\",\"注2:加入用户群请先阅读《提问的智慧》。 同时群内可能存在部分令您感到不适或感到冒犯的内容。若对此有顾虑请勿加群。\"]},\"2\":{\"h\":\"开源许可\",\"t\":[\"本项目中的 examples/ install/ packages/ui-default/ 下的内容仅采用 AGPL-3.0 进行授权。 项目其余部分使用双重许可:\",\"您可以在遵守 AGPL-3.0 许可证和下述附加条款章节的前提下免费使用这些代码:\",\"如确需闭源,您也可以联系我们购买其他授权。\"]},\"3\":{\"h\":\"附加条款\",\"t\":[\"基于 AGPL3 协议第七条,您在使用本项目时,需要遵守以下额外条款:\",\"不可移除本项目的版权声明与作者/来源署名;(AGPL3 7(b))\",\"当重分发经修改后的本软件时,需要在软件名或版本号中采用可识别的方式进行注明;(AGPL3 7(c))\",\"除非得到许可,不得以宣传为目的使用作者姓名;(AGPL3 7(d))\",\"即: 在您部署 Hydro 时,需要保留底部的 Powered by Hydro 字样,其中的 Hydro 字样需指向 hydro.js.org/本仓库/fork 之一的链接。 若您对源码做出修改/扩展,同样需要以 AGPL-3.0-or-later 开源,您可以以 Powered by Hydro, Modified by xxx 格式在页脚注明。 此限制对以下模块仍然有效:\",\"Hydro 插件;\",\"包括但不限于使用 http 协议与 Hydro 进行交互的组件;\",\"若您需要对这些模块闭源处理,请考虑联系我们以购买许可。 鉴于 Mirai 处的 不和谐事件 对此项目做如下声明:\",\"项目开源不代表开发者有义务为您提供服务。\",\"在提问前请先阅读《提问的智慧》。\",\"若有必要,开发者有权对您停止任何技术支持。\",\"开发组会 尽可能 保证用户可以进行平滑升级,但无法保证不在新版本引入影响使用的漏洞,且内部实现可能会在不发布任何通知的情况下进行重命名/修改/删除。\",\"如果您对以上条目感到不适,建议您停止使用本项目。\"]},\"4\":{\"h\":\"鸣谢\",\"t\":[\"排名不分先后,按照链接字典序。\",\"Github 为 Hydro 提供了代码托管与自动构建。\",\"criyle 提供评测沙箱实现。\",\"Vijos 为 Hydro 提供了UI框架。\"]},\"5\":{\"h\":\"常见问题集合\"},\"6\":{\"h\":\"好消息!本页和各大浏览器均达成了合作,使用 Ctrl-F 即可快速搜索关键词!\"},\"7\":{\"h\":\"更多教程请点击右上角的常用教程查看。\"},\"8\":{\"h\":\"用户QQ群 1085853538\"},\"9\":{\"h\":\"如何快速上手了解系统功能?\",\"t\":[\"参照本文 https://hydro.ac/discuss/6172ceeed850d38c79ae18f9 无服务器快速体验系统功能。 如果你没有二开很多功能的需求,推荐直接使用在线服务。超过两万题的题库可以直接复制使用,无需购置云服务器,无需手动维护,更省心。 如果你有需要绑定自己的域名或是改 Logo 等等自定义需求,也可在管理面板中开通高级功能自助操作。\",\"系统中的用户只有编辑、禁用功能,没有删除功能,这是为了从根源上防止出现“教学事故”,请不要要求增加相关功能,如果认为自己绝不会误操作,请自行开发相关功能。\"]},\"10\":{\"h\":\"什么是 OJ?\",\"t\":[\"现在你所使用的评测系统也仅仅是一个程序,并没有人工智能。因此很多地方需要你来迁就它,如果不这样做,你的答案即使本质上是正确的,由于形式的错误造成系统不能理解,也会导致错误。 系统运行过程如下:\",\"教师在系统中添加题目,并严格定义题目提供输入数据的格式和要求的输出数据格式。\",\"教师根据题目定义的格式向系统中添加若干组测试数据,每组数据都包含输入数据和对应的输出。\",\"学生阅读题目,并根据自己的理解提交程序。\",\"系统编译并运行学生的程序,再将老师事先提供的输入数据“喂”给学生的程序,看它会输出什么。\",\"如果学生程序的输出与老师之前提供的输出完全一致,一字不差,则认为学生的程序是正确的,否则则认为该程序错误。\",\"如果运行过程中出现内存、时间上超出题目限制的情况,则中断程序的运行,并认为答案不正确。\",\"在了解了上面的情况以后,同学们应该理解,如果题目没有要求程序输出“Please Input Two Number”之类的提示信息,那么自行输出这些文字将导致你的程序输出与老师事先告诉系统的输出不能做到“一字不差”,因而将导致系统报答案错误。 如果题目要求每两行输出之间要空一行,结果你没有空,会是格式错误,反之亦然。 也许你会觉得,哦,这系统太烂了,这点东西都不能自动识别;实际上正是这样才能有效训练大家编程的精确性、养成良好的代码习惯。很多程序高手都跟你一样,是从对这个系统吐槽开始学习如何认真仔细的、一丝不苟的进行编程的。 系统为了能用统一的方式运行所有同学的答案,不得不对所有人提交的答案的形式进行限定。 对于学习C、C++语言的同学来说,所有提交给系统的答案必须包含并且只有一个main函数,这个main函数必须返回int类型,并且最好返回0,因为操作系统对非零的返回值认为是运行出错。 编译错误发生时,点击“编译错误”的文字链接可以得到详细解释。\"]},\"11\":{\"h\":\"Arch Linux 开发模式安装时出现 [ERR_STREAM_PREMATURE_CLOSE]: Premature close 错误\",\"t\":[\"删除 .yarnrc.yml 和 .yarn 后再试。\"]},\"12\":{\"h\":\"为什么我安装完成之后仍然无法访问?\",\"t\":[\"如果您使用的是 阿里云/腾讯云 等服务商,请确保安全组放行了 80 和 443 端口。\"]},\"13\":{\"h\":\"为什么我配置完反向代理(caddy/nginx)之后无法登录(出现CsrfTokenError)?\",\"t\":[\"反向代理时请确保设置了正确的 Host Header。详细说明\"]},\"14\":{\"h\":\"怎么备份/还原备份/迁移数据?\",\"t\":[\"hydrooj backuphydrooj restore backup-xxx.zip\",\"百度学习 crontab 的用法后,可以使用 sudo crontab -e 定制自动备份计划。\"]},\"15\":{\"h\":\"恢复备份时出现 '/data/file/hydro': Directory not empty\",\"t\":[\"关闭 minio (pm2 stop minio) 后手动删除 /data/file/hydro 文件夹再重试。\"]},\"16\":{\"h\":\"更新升级\",\"t\":[\"yarn global upgrade-interactive --latest 然后按空格选中除 pm2 之外的所有包更新,回车确认。 然后 pm2 restart hydrooj 重启服务。 重启后 pm2 logs hydrooj --lines 100 没有看到报错并看到了 Server started 则一切正常。\",\"Hydro 的所有历史版本,都可以无损升级到最新版本。如果老系统更新有疑问,随时加官方群咨询群主。\"]},\"17\":{\"h\":\"怎么导入题目/创建题目?\",\"t\":[\"题目列表右侧有相应入口。\",\"切记:不要导入过多你暂时用不上的题目,正确的方式是每次训练、作业,导入所需的5-10个题目,比赛作业结束后让题目成为训练题库的一部分。这样能保证题库中题号靠前的题目难度依次上升,适合后来的同学自行训练。不要贪图题目数量而忽视其质量。自己看不懂解法的题目,少用、慎用。\"]},\"18\":{\"h\":\"如何限制未登录用户访问?\",\"t\":[\"管理域 -> 管理权限 将 Guest 权限组的 查看此域 权限禁用。\"]},\"19\":{\"h\":\"怎么添加页脚备案号?\",\"t\":[\"在系统设置 footer_extra_html 内添加一行 XX 备 XX 号 \"]},\"20\":{\"h\":\"比赛作业里面的时间是什么含义,OI排名跟普通排名有何区别?\",\"t\":[\"时间是指参与人员做出对应题目“花费”的时间: 即:做出题目的时刻 – 比赛开始的时刻 + 惩罚时间 惩罚时间 = 做对之前错误的提交数 * 20分钟。 普通排名按做对的题目数和“花费”的时间进行排名。 OI排名,按得分排名,题目可以按通过的比例进行记分,每题100分。如果希望数据的分值不平均分配,可以使用 config 配置。\"]},\"21\":{\"h\":\"脚本把 OJ 装在哪里了?\",\"t\":[\"Hydro 的默认位置可以运行 yarn global dir 得到。(不要直接改代码,更新会覆盖此处的所有修改,请使用插件API) 默认的数据库文件放置在 /data/db,但是不要直接复制文件,而是推荐用 hydrooj backup 进行备份。 测试数据等文件存储于 /data/file。 配置文件位于 /root/.config/hydro 和 /root/.hydro。 对于正在运行中的生产服务器,任何操作前请做好离线备份。 备份文件一定要解压查看内部是否包含全部数据,关注备份的大小(大系统备份应该有上百兆),有条件找虚拟机实测还原是否成功\"]},\"22\":{\"h\":\"题目的限时和内存限制的精度是怎样的?\",\"t\":[\"题目限时允许设定的字面精度是 1ms,但是由于操作系统内核参数的限定,实测的精度通常为4ms。 内存限制的精度是1MB,对于本地native的编译型语言c/c++/pascal/freebasic/clang等是考察程序本身的内存申请空间; 对于虚拟机和脚本语言,则包含了虚拟机本身或解释器本身的内存消耗。\"]},\"23\":{\"h\":\"我想让 Python 支持 numpy 等等库,怎么办?\",\"t\":[\"如果你是 2022/8/12 日前安装,使用 pip3 install numpy 后 pm2 restart hydro-sandbox 否则参照请参照 编译器 章节。\"]},\"24\":{\"h\":\"使用安装脚本后忘记 MongoDB 的账号密码怎么办?\",\"t\":[\"看 /root/.hydro/config.json 。\"]},\"25\":{\"h\":\"如何关闭、打开用户注册?\",\"t\":[\"用户注册由 Guest 用户(uid 为 0)的 PRIV_REGISTER_USER 权限控制,默认允许注册。 使用 hydrooj cli user setPriv 0 0 即可关闭注册。 若要重新打开,可使用 hydrooj cli user setPriv 0 8。\",\"变更后,请重启 hydrooj 服务:pm2 restart hydrooj\"]},\"26\":{\"h\":\"用户名为 Hydro 的用户是干什么的?密码是什么?可以登录么?\",\"t\":[\"用户名为 Hydro 的用户(uid 为 1)仅用于发送系统消息(与 QQ 中的 10000 类似),无法登录。\"]},\"27\":{\"h\":\"如何修改网站图标?\",\"t\":[\"使用 hydrooj addon create 创建一个插件,这会自动创建 /root/addon 目录。 进入 /root/addon/public 目录,将您的站点图标放置于该文件夹下。 您需要将以下文件放在该目录中(适配不同浏览器):\",\"favicon-16x16.png\",\"favicon-32x32.png\",\"favicon-96x96.png\",\"favicon.ico (32x32)\",\"android-chrome-192x192.png\",\"apple-touch-icon-180x180.png\",\"分辨率应尽可能对应,但不强制要求。以上图片将在浏览器标签页图片上显示。 您还需要将以下文件放在该目录:\",\"nav_logo_dark.png\",\"以上图片将在页面左上角 logo 显示。 之后前往系统设置,找到 nav_logo_dark 设置项,改为 /nav_logo_dark.png ,重启 Hydro 即可应用更改。\",\"记得清理浏览器缓存。\"]},\"28\":{\"h\":\"如何重置数据?\",\"t\":[\"Warning\",\"此操作会删除所有用户/题目/比赛等数据。请谨慎操作!\",\"将 此脚本 下载到服务器运行。\",\"您可按需更改,显示顺序与配置中的排列顺序相同。\"]},\"29\":{\"h\":\"评测显示“总时限超过 60s,评测取消”\",\"t\":[\"在系统设置中修改 total_time_limit 为允许的单题最大评测时长即可。\"]},\"30\":{\"h\":\"如何在背景中添加线条特效?\",\"t\":[\"在系统设置中找到 footer_extra_html 项,加上如下内容:(写在一行内,不要多加换行)\",\"基于 https://github.com/hustcc/canvas-nest.js ,MIT\",\" \"]},\"31\":{\"h\":\"使用 Hydro 要花多少钱?\",\"t\":[\"不要钱,我们是 AGPL 的。如果你钱多,可以 给我发个红包。\"]},\"32\":{\"h\":\"execve: no such file or directory\",\"t\":[\"脚本安装默认只装了一小部分编译器。请参照 编译器 章节安装配置其他编译器。\"]},\"33\":{\"h\":\"怎么自定义用户标签?\",\"t\":[\"进入 MongoDB,执行下面的操作即可(根据具体情况替换尖括号中的部分):\",\"use hydro db.user.update({\\\"_id\\\": <用户 UID>}, {$set: {\\\"badge\\\": \\\"<标签内容>#<背景颜色(HEX)>#<文字颜色(HEX)>\\\"}}) \"]},\"34\":{\"h\":\"为什么我无法批量下载多个文件?\",\"t\":[\"请使用现代浏览器进行操作,并尝试给网站设置 https。 否则请选择逐个下载文件(Ctrl+点击文件名)。\"]},\"35\":{\"h\":\"为什么我的提交页面没有语言可选?\",\"t\":[\"题目 -> 评测设置 -> 允许的语言 域设置 -> 编辑域资料 -> 允许的语言 这两个地方,应该填英文逗号分隔的语言ID,不会填请留空。\"]},\"36\":{\"h\":\"The 'yarn global' commands have been remove in 2.x - consider using 'yarn dlx' or a third-party plugin instead\",\"t\":[\"如果你搞不明白这个问题,请老实用安装脚本,不要折腾开发模式。\"]},\"37\":{\"h\":\"我是机房用户,大量用户同 IP 操作触发了频率限制,怎么解决?\",\"t\":[\"方案一: 通过在内网架设代理服务器,将内网 ip 发送至服务端。(推荐)\\n方案二: 使用形如 hydrooj cli system set limit.user_login 999 的命令设置新的频率限制(可在错误页面查看具体是触发了哪条限制)\\n方案三: 使用 pm2 start hydrooj -- --benchmark 启动,关闭所有频率限制(不推荐)\"]},\"38\":{\"h\":\"API\",\"t\":[\"此处列出部分系统通信协议。\"]},\"39\":{\"h\":\"评测端通信协议\",\"t\":[\"当前版本 v1 。\"]},\"40\":{\"h\":\"评测端交互流程\",\"t\":[\"GET /judge/files (检查登陆状态是否有效,若无效则跳转登录逻辑,通常每六小时执行一次)\",\"WEBSOCKET /judge/conn (主交互通道)\",\"若登录失效,则进行登录操作。\",\"POST /login {\\\"uname\\\":\\\"USERNAME\\\",\\\"password\\\":\\\"PASSWORD\\\",\\\"rememberme\\\":true} \"]},\"41\":{\"h\":\"WebSocket 连接建立流程\",\"t\":[\"WEBSOCKET /judge/conn Authorization: Bearer COOKIE_SID \",\"连接建立后,评测端向 Web 汇报当前节点状态(可选) 注:下方信息仅作数据格式展示用,不保证真实有效。\",\"{ \\\"key\\\": \\\"status\\\", \\\"info\\\": { \\\"mid\\\": \\\"MACHINE_ID\\\", \\\"memory\\\": { \\\"total\\\": 25189552128, \\\"free\\\": 660258800, \\\"used\\\": 24529293328, \\\"active\\\": 1558973164, \\\"available\\\": 23636676608, \\\"buffers\\\": 3075653000, \\\"cached\\\": 1000000000, \\\"slab\\\": 1000000000, \\\"buffcache\\\": 1000000000, \\\"swaptotal\\\": 0, \\\"swapused\\\": 0, \\\"swapfree\\\": 0 }, \\\"cpu\\\": { \\\"manufacturer\\\": \\\"Intel\\\", \\\"brand\\\": \\\"Xeon® Platinum 8269CY\\\", \\\"vendor\\\": \\\"Intel\\\", \\\"family\\\": \\\"6\\\", \\\"model\\\": \\\"85\\\", \\\"stepping\\\": \\\"7\\\", \\\"speed\\\": 2.5, \\\"cores\\\": 32, \\\"physicalCores\\\": 32, \\\"processors\\\": 2, \\\"flags\\\": \\\"fpu vme de pse tsc ...\\\", \\\"cache\\\": { \\\"l1d\\\": 32768, \\\"l1i\\\": 32768, \\\"l2\\\": 262144, \\\"l3\\\": 6291456 } }, \\\"load\\\": { \\\"avgLoad\\\": 0.01, \\\"currentLoad\\\": 0.01, \\\"currentLoadUser\\\": 0.01, \\\"currentLoadSystem\\\": 0.01, \\\"currentLoadNice\\\": 0.01, \\\"currentLoadIdle\\\": 0.01, \\\"currentLoadIrq\\\": 0.01 }, \\\"osinfo\\\": { \\\"platform\\\": \\\"linux\\\", \\\"distro\\\": \\\"Ubuntu\\\", \\\"release\\\": \\\"22.04.2 LTS\\\", \\\"codename\\\": \\\"Jammy Jellyfish\\\", \\\"kernel\\\": \\\"5.15.0-84-generic\\\", \\\"arch\\\": \\\"x64\\\", \\\"hostname\\\": \\\"judge\\\", \\\"codepage\\\": \\\"UTF-8\\\", } } } \",\"建立连接后每隔 30s,评测端发送 {\\\"key\\\":\\\"ping\\\"}。\"]},\"42\":{\"h\":\"语言配置下发\",\"t\":[\"在连接建立后,Web 端会向 Judge 分发服务端的语言设置。如果客户端需要进行特殊设置,可忽略此条消息。\"]},\"43\":{\"h\":\"评测任务推送\",\"t\":[\"Web 端会通过 WebSocket 向评测端推送评测任务。\",\"{ \\\"task\\\": { \\\"type\\\": \\\"judge\\\", \\\"_id\\\": \\\"RECORD_ID\\\", \\\"lang\\\": \\\"cc.cc11\\\", \\\"uid\\\": SUBMITTER_UID, \\\"code\\\": \\\"USER_SUBMITTED_CODE\\\", \\\"domainId\\\": \\\"SUBMISSION_DOMAIN_ID\\\", \\\"pid\\\": PROBLEM_ID, \\\"contest\\\": \\\"CONTEST_ID (optional)\\\", \\\"input\\\": \\\"INPUT\\\", \\\"source\\\": \\\"SOURCE_ID\\\", \\\"meta\\\": { \\\"rejudge\\\": false, \\\"problemOwner\\\": OWNER_UID }, \\\"data\\\": [ { \\\"name\\\": \\\"FILE_NAME\\\", \\\"size\\\": SIZE_IN_BYTES, \\\"lastModified\\\": \\\"2023-11-15T08:14:57.535Z\\\", \\\"etag\\\": \\\"ETAG\\\" } ] } } \",\"注1:如果比赛 ID 为 000000000000000000000000 则表示此提交为自测提交,自测提交使用 input 字段值作为程序输入。 注2:source 字段为缓存 ID,同 source 字段的提交使用相同的缓存目录。 注3:source 字段包含且仅包含一个字符 /,建议使用 domainId/pid。 注4:测试数据的 etag 用来识别本地缓存的文件是否与云端一致,可使用 hash 或是修改时间的时间戳。\"]},\"44\":{\"h\":\"测试数据下载\",\"t\":[\"若推送的评测任务中使用了的测试数据缺失,Judge 端会向 Web 请求缺失或是修改的文件。\",\"POST /d/:domainId/judge/files Cookie: sid=COOKIE_SID {\\\"pid\\\":PROBLEM_ID,\\\"files\\\":[\\\"a.in\\\",\\\"a.out\\\"]} \",\"服务端返回如下:\",\"{ \\\"links\\\": { \\\"a.in\\\": \\\"https://cdn.hydro.ac/d/DOMAIN_ID/pid/1/a.in\\\", \\\"a.out\\\": \\\"https://cdn.hydro.ac/d/DOMAIN_ID/pid/1/a.out\\\" } } \"]},\"45\":{\"h\":\"评测结果上报\",\"t\":[\"{ \\\"key\\\": \\\"next/end\\\", \\\"domainId\\\": \\\"DOMAIN_ID\\\", \\\"rid\\\": \\\"RECORD_ID\\\", \\\"message\\\": \\\"JUDGE_MESSAGE\\\", \\\"compilerText\\\": \\\"COMPILER_OUTPUT\\\", \\\"status\\\": STATUS_CODE, \\\"score\\\": SCORE, \\\"time\\\": TIME_IN_MS, \\\"memory\\\": MEMORY_IN_KB, \\\"progress\\\": PROGRESS_PERCENTAGE, \\\"addProgress\\\": PROGRESS_PERCENTAGE, \\\"case\\\": { \\\"id\\\": ID, \\\"subtaskId\\\": SUBTASK_ID, \\\"score\\\": SCORE, \\\"status\\\": STATUS_CODE, \\\"message\\\": \\\"CHECKER_MESSAGE\\\" } } \",\"除 key, domainId, rid 三个字段外,其他字段均为可选。关于 STATUS_CODE 含义请查看 hydro-dev/Hydro/packages/utils/lib/status 。\\n当 key 为 end 时表示评测任务已经完成,结果确定,Web 端可进行 AC 数计量,登记成绩表等操作。\"]},\"46\":{\"h\":\"权限节点\",\"t\":[\"Hydro 的权限使用位运算处理。 例:若某用户具有 PRIV_EDIT_SYSTEM 与 PRIV_SET_PERM 权限,应设置为 (1<<0)|(1<<1) (即 3)\",\"可以看 代码 中关于此部分的内容。\",\"扩展阅读:权限结构\"]},\"47\":{\"h\":\"开发环境部署\",\"t\":[\"开发环境仅适合需要进行大量深度修改或希望贡献代码的用户。 如果您没有过 TypeScript 项目的开发经验,非常不建议自建开发环境,请基于插件系统进行你所需要的功能添加与修改。 使用自动脚本安装也可以基于插件系统完成大部分的定制需求(参照左侧【使用 TypeScript 编写插件】章节)。 如果您需要编译 UI,请确认您的开发环境至少拥有 8GB 内存。\",\"功能对比\",\"生产模式\",\"开发模式\",\"快速起步\",\"✅\",\"❌\",\"插件 API\",\"✅\",\"✅\",\"底层代码修改\",\"❌\",\"✅\",\"热重载\",\"❌\",\"✅\",\"性能优化\",\"✅\",\"❌\",\"兼容性\",\"✅\",\"❌\",\"技术支持\",\"✅\",\"❌\",\"部署难度\",\"简单\",\"复杂\",\"升级\",\"简单\",\"复杂\",\"技能要求\",\"低\",\"高\",\"空闲内存要求\",\"2G\",\"8G\",\"可切换至开发模式\",\"是\",\"=\",\"可切换至生产模式\",\"=\",\"需重写代码\",\"Tips\",\"使用开发环境默认您有良好的国际互联网连接。以下报错信息均为网络问题导致,您可以尝试换源/使用代理/切换网络环境。\",\"Failed to connect\",\"Connection reset\",\"connect timeout\",\"开发组不会为您解决任何网络问题。\",\"在开发之前,请务必确认您使用了支持 TypeScript 的 IDE 环境,这可以极大降低开发难度。\"]},\"48\":{\"h\":\"安装依赖\",\"t\":[\"系统要求:Hydro开发环境目前仅支持 Linux 系统,如您使用 Windows 请使用 WSL2 。\",\"MongoDB:Hydro 需要 MongoDB 提供数据库服务。\",\"NodeJS:请安装 NodeJS >=18 版本。(若使用 apt 请使用 nodesource 提供的源替代官方源) (推荐使用 nix ,可通过. <(curl https://hydro.ac/nix.sh) 快速安装)\",\"yarn:安装 yarn 前请先完成 NodeJS 安装。 nix-env -iA nixpkgs.yarn 或 npm install -g yarn\",\"若需要使用 hydrojudge 请参照 hydrojudge 插件说明部分完成沙箱的安装配置。\"]},\"49\":{\"h\":\"安装 Hydro\",\"t\":[\"git clone https://github.com/hydro-dev/Hydro.git /root/Hydro --recursive # 下载至 /root/Hydro 文件夹 cd /root/Hydro # 进入工作目录 yarn # 安装依赖包 yarn build:ui:production # 编译前端 \"]},\"50\":{\"h\":\"插件\",\"t\":[\"开发环境部署完成后默认不启用任何插件。\",\"所有官方插件均随源码仓库下载到安装文件夹的 packages 子文件夹下,可以通过下面的命令启用官方插件(以启用 @hydrooj/ui-default 为例):\",\"yarn hydrooj addon add @hydrooj/ui-default \",\"对于非官方插件,下载后通过下面的命令启用即可(以启用位置在 /root/addon 下的插件为例):\",\"yarn hydrooj addon add /root/addon \"]},\"51\":{\"h\":\"启动 Hydro\",\"t\":[\"支持如下启动参数:\",\"--port=2333 指定启动端口\",\"--debug 启用开发模式\",\"--watch 启用热重载(实验性)\",\"使用 yarn debug --port=2333 --watch 启动 Hydro,并在后台运行 yarn build:ui:dev,可以对前端源码进行实时转译,在反复修改时可节省编译时间。启动完成后,您可以在 8000 端口访问到 Hydro 实例,且前端的任何更改将即时生效。(后端热重载可能存在 bug,部分模块修改后可能仍需重启才能生效) 请注意:此功能仅在启用了 @hydrooj/ui-default 插件的情况下才会生效。\",\"首次启动会要求您填写数据库连接信息。请根据您数据库的安装填写(若无密码则留空) 请按照下文说明创建管理员账户即可正常使用。\"]},\"52\":{\"h\":\"更新\",\"t\":[\"需要更新的时候进入对应仓库文件夹执行 git pull,然后重新 yarn && yarn build:ui:production 即可。\"]},\"53\":{\"h\":\"数据库结构\"},\"54\":{\"h\":\"document\",\"t\":[\"基础列:(domainId, docId, docType), owner, title, content 存储所有文档,包括题目,比赛,训练等等,使用 docType 字段区分文档类型,docType 的定义可参照 packages/hydrooj/src/model/document.ts 。\"]},\"55\":{\"h\":\"document.status\",\"t\":[\"基础列:(domainId, docId, docType, uid), owner, title, content 存储用户在对应文档下留下的信息,如题目的提交状态,比赛的成绩等等。\"]},\"56\":{\"h\":\"record\",\"t\":[\"基础列:((_id), domainId), uid, code, lang, score, status 存储用户的提交记录。\"]},\"57\":{\"h\":\"user\",\"t\":[\"基础列:(_id), uname, unameLower, mail, mailLower, priv 在系统中的所有用户。\"]},\"58\":{\"h\":\"oplog\",\"t\":[\"存储系统日志。\"]},\"59\":{\"h\":\"blacklist\"},\"60\":{\"h\":\"system\"},\"61\":{\"h\":\"task\",\"t\":[\"用于提交队列等。\"]},\"62\":{\"h\":\"event\",\"t\":[\"用于处理 Hydro 的内部事件通讯,请勿手动操作。\"]},\"63\":{\"h\":\"schedule\",\"t\":[\"定时任务相关。\"]},\"64\":{\"h\":\"opcount\",\"t\":[\"用于记录用户的访问情况,作频率限制用\"]},\"65\":{\"h\":\"token\",\"t\":[\"存储临时信息,如登陆状态,注册验证码等\"]},\"66\":{\"h\":\"前端修改\",\"t\":[\"参考 前端修改。\"]},\"67\":{\"h\":\"使用 TypeScript 编写插件\",\"t\":[\"请注意:在阅读本节之前,请确认您已阅读【使用 TypeScript 编写插件】一节并已完成了插件的创建。\"]},\"68\":{\"h\":\"示例\",\"t\":[\"import { Context, Time } from 'hydrooj'; export async function apply(ctx: Context) { // handler 表示路由事件 // after 表示在主逻辑完成后运行,同时支持 before, before-operation, 参照 【插件编写】 章节 【请求流程】 // RecordDetail 为需要捕获的路由名 // #get 表示仅捕获 GET 请求,若无此后缀表示捕获该路由的所有请求 ctx.on('handler/after/RecordDetail#get', (h) => { // handler 系列钩子的一参数为对应的 Handler 实例 // 不允许查看 24 小时以前的提交记录 if (h.rdoc._id.getTimestamp() < new Date(Date.now() - Time.day)) { h.rdoc.code = ''; } }); } \",\"import { Context } from 'hydrooj'; async function getAnnounce(domainId: string, limit = 5) { // 获取公告... return adocs; } export async function apply(ctx: Context) { ctx.withHandlerClass('HomeHandler', (HomeHandler) => { // 修改 HomeHandler 中的一个方法(添加公告) HomeHandler.prototype.getAnnounce = getAnnounce; }); } \"]},\"69\":{\"h\":\"命名规则\"},\"70\":{\"h\":\"变量命名规则\",\"t\":[\"在 Hydro 中的大部分变量有固定命名规则:\",\"pdoc: 题目\",\"tdoc: 比赛/作业/训练\",\"rdoc: 提交记录\",\"ddoc: 讨论\",\"drdoc: 讨论的回复\",\"drrdoc: 讨论的二级回复\",\"mdoc: 站内信息\",\"psdoc: 题目的提交状态\",\"tsdoc: 比赛/作业的提交状态 ...\",\"以及它们的变种:\",\"pdocs: 包含若干题目的数组\",\"pdict: 键为题目 id,题目详情为值的对象 ...\",\"更多细节可在 packages/hydrooj/src/interface.ts 中找到。\"]},\"71\":{\"h\":\"函数命名规则\",\"t\":[\"get() 获取内容,返回对应值或 null\",\"getList() 获取内容,返回 dict 类对象\",\"getMulti() 获取数据库查询的指针\",\"edit() 更新内容\"]},\"72\":{\"h\":\"接入第三方账号系统\",\"t\":[\"Hydro 支持接入第三方的账号系统,并且有以下内置模块可用:\",\"@hydrooj/login-with-github\",\"@hydrooj/login-with-google\"]},\"73\":{\"h\":\"对接其他平台\",\"t\":[\"在阅读本节之前,请确保你已阅读 【插件开发】 章节。\",\"以 Github 登录为例:\",\"import { Context, ForbiddenError, Handler, superagent, SystemModel, TokenModel, UserFacingError, ValidationError, } from 'hydrooj'; declare module 'hydrooj' { interface SystemKeys { 'login-with-github.id': string; 'login-with-github.secret': string; 'login-with-github.endpoint': string; } } // 当用户点击 【使用 XX 登录】 按钮时,此函数会被执行 async function get(this: Handler) { // 从系统设置中获取基础设置,并储存状态信息(完成登录逻辑后应该跳转到哪一页) const [appid, [state]] = await Promise.all([ SystemModel.get('login-with-github.id'), TokenModel.add(TokenModel.TYPE_OAUTH, 600, { redirect: this.request.referer }), ]); // 将用户重定向至第三方平台请求授权。 this.response.redirect = `https://github.com/login/oauth/authorize?client_id=${appid}&state=${state}&scope=read:user,user:email`; } // 当用户在三方系统中完成授权,需要重定向到 /oauth/xxx/callback,这时所有返回的参数作为 callback 的一参数传入。 async function callback({ state, code }) { // 获取系统设置和之前的状态。 const [[appid, secret, endpoint, url], s] = await Promise.all([ SystemModel.getMany([ 'login-with-github.id', 'login-with-github.secret', 'login-with-github.endpoint', 'server.url', ]), TokenModel.get(state, TokenModel.TYPE_OAUTH), ]); if (!s) throw new ValidationError('token'); // 使用从 url 中返回的 token 请求第三方的 API,获取用户信息,作为函数返回。 // 在 OAuth 协议中,需要使用 state 和 code 换取 access_token 再调用 API,这在不同系统中可能设计不同。 // 系统会根据返回的用户信息自动查找已有用户或是创建新用户。 const res = await superagent.post(`${endpoint || 'https://github.com'}/login/oauth/access_token`) .send({ client_id: appid, client_secret: secret, code, redirect_uri: `${url}oauth/github/callback`, state, }) .set('accept', 'application/json'); if (res.body.error) { throw new UserFacingError( res.body.error, res.body.error_description, res.body.error_uri, ); } const t = res.body.access_token; const userInfo = await superagent.get(`${endpoint ? `${endpoint}/api` : 'https://api.github.com'}/user`) .set('User-Agent', 'Hydro-OAuth') .set('Accept', 'application/vnd.github.v3+json') .set('Authorization', `token ${t}`); const ret = { _id: `${userInfo.body.id}@github.local`, email: userInfo.body.email, bio: userInfo.body.bio, // 提供多个用户名,若需创建用户则从前往后尝试,直到用户名可用 uname: [userInfo.body.name, userInfo.body.login].filter((i) => i), avatar: `github:${userInfo.body.login}`, }; await TokenModel.del(s._id, TokenModel.TYPE_OAUTH); if (!ret.email) throw new ForbiddenError(\\\"You don't have a verified email.\\\"); return ret; } // 注册此模块。 export function apply(ctx: Context) { ctx.provideModule('oauth', 'github', { text: 'Login with Github', callback, get, }); ctx.i18n.load('zh', { 'Login With Github': '使用 Github 登录', }); } \"]},\"74\":{\"h\":\"使用 TypeScript 编写插件\",\"t\":[\"前置条件:NodeJS>=18 此教程将以编写剪贴板插件为例进行说明。\"]},\"75\":{\"h\":\"Step1 初始化项目\",\"t\":[\"使用 hydrooj addon create 快速在 /root/addon 下初始化一个插件或是在一个空文件夹中运行 yarn init 并按照提示填写相关信息。\",\"# 使用 yarn init 的样例 /workspace/hydro-plugin $ yarn init yarn init v1.22.4 question name (hydro-plugin): @hydrooj/pastebin question version (1.0.0): 0.0.1 question description: HydroOJ的剪贴板组件 question entry point (index.js): index.ts question repository url: https://github.com/hydro-dev/pastebin.git question author: undefined question license (MIT): MIT question private: success Saved package.json \"]},\"76\":{\"h\":\"可选:在本机环境编写插件\",\"t\":[\"有时我们希望使用本机的 IDE 编写插件上传到服务器(我们也推荐这么做,编辑器提供的代码补全可以很大程度简化开发流程),可以进行如下操作:\",\"在本机安装 NodeJS 和 yarn 。\",\"参照步骤 1 使用 yarn init 创建一个项目。\",\"使用 VSCode 打开插件文件夹。\",\"使用 yarn add hydrooj -D 安装相关开发组件。\",\"参照下文进行插件开发工作\",\"将本地的文件夹上传至服务器,并使用 hydrooj addon add 插件绝对路径 启用上传的插件。\"]},\"77\":{\"h\":\"Step2 准备编写组件\",\"t\":[\"分析:剪贴板组件需要以下功能:\",\"与数据库交互来存储/检索相应文档。\",\"提供 /paste/create 路由以创建新文档。\",\"提供 /paste/show/:ID 来查看已创建的文档。\",\"根据用户ID进行鉴权,允许将文档设置为私密以防止他人查看。\",\"在路由中定义所有的函数应均为异步函数,支持的函数有:prepare, get, post, post[Operation], cleanup 具体流程如下:\",\"先执行 prepare(args) (如果存在) args 为传入的参数集合(包括 QueryString, Body, Path)中的全部参数, 再执行 prepare(args) (如果存在) 检查请求类型: 为 GET ? -> 执行 get(args) 为 POST ? -> 执行 post(args) -> 含有 operation 字段? -> 执行 post[Operation] 执行 cleanup() \",\"如果在 this.response.template 指定模板则渲染,否则直接返回 this.response.body 中的内容。\",\"在表单提交时的 operation 字段使用下划线,函数名使用驼峰命名。\",\"如 对应 postConfirmDelete 函数。\",\"应当提供 apply 函数,并与定义的 Handler 一同挂载到 global.Hydro.handler[模块名] 位置。 apply 函数将在初始化阶段被调用。\",\"// @noErrors // @module: esnext // @filename: index.ts import { db, definePlugin, Handler, NotFoundError, param, PermissionError, PRIV, Types, } from 'hydrooj'; const coll = db.collection('paste'); interface Paste { _id: string; owner: number; content: string; isPrivate: boolean; } declare module 'hydrooj' { interface Model { pastebin: typeof pastebinModel; } interface Collections { paste: Paste; // 声明数据表类型 } } async function add(userId: number, content: string, isPrivate: boolean): Promise { const pasteId = String.random(16); // Hydro 提供了此方法,创建一个长度为16的随机字符串 // 使用 mongodb 为数据库驱动,相关操作参照其文档 const result = await coll.insertOne({ _id: pasteId, owner: userId, content, isPrivate, }); return result.insertedId; // 返回插入的文档ID } async function get(pasteId: string): Promise { return await coll.findOne({ _id: pasteId }); } // 暴露这些接口,使得 cli 也能够正常调用这些函数; const pastebinModel = { add, get }; global.Hydro.model.pastebin = pastebinModel; // 创建新路由 class PasteCreateHandler extends Handler { // Get请求时触发该函数 async get() { // 检查用户是否登录,此处为多余(因为底部注册路由时已声明所需权限) // 此方法适用于权限的动态检查 // this.checkPriv(PRIV.PRIV_USER_PROFILE); this.response.template = 'paste_create.html'; // 返回此页面 } // 使用 Types.Content 检查输入 @param('content', Types.Content) @param('private', Types.Boolean) // 从用户提交的表单中取出content和private字段 // domainId 为固定传入参数 async post(domainId: string, content: string, isPrivate = false) { // 在HTML表单提交的多选框中,选中值为 'on',未选中则为空,需要进行转换 const pasteid = await pastebinModel.add(this.user._id, content, !!isPrivate); // 将用户重定向到创建完成的url this.response.redirect = this.url('paste_show', { id: pasteid }); // 相应的,提供了 this.back() 方法用于将用户重定向至前一个地址(通常用于 Ajax 或是部分更新操作) } } class PasteShowHandler extends Handler { @param('id', Types.String) async get(domainId: string, id: string) { const doc = await pastebin.get(id); if (!doc) throw new NotFoundError(id); if (doc.isPrivate && this.user._id !== doc.owner) { throw new PermissionError(); } this.response.body = { doc }; this.response.template = 'paste_show.html'; } @param('id', Types.String) async postDelete(domainId: string, id: string) { // 当提交表单并存在 operation 值为 delete 时执行。 // 本例中未实现删除功能,仅作为说明。 } } // Hydro会在服务初始化完成后调用该函数。 export async function apply() { // 注册一个名为 paste_create 的路由,匹配 '/paste/create', // 使用PasteCreateHandler处理,访问改路由需要PRIV.PRIV_USER_PROFILE权限 // 提示:路由匹配基于 path-to-regexp ctx.Route('paste_create', '/paste/create', PasteCreateHandler, PRIV.PRIV_USER_PROFILE); ctx.Route('paste_show', '/paste/show/:id', PasteShowHandler); } \"]},\"78\":{\"h\":\"Step4 template\",\"t\":[\"模板采用 nunjucks 语法。放置于 templates/ 文件夹下。 会在请求结束时根据 response.template 的值选择模板,并使用 response.body 的值进行渲染,存入 response.body 中。 若 response.template 为空或 request.headers['accept'] == 'application/json',则跳过渲染步骤。\"]},\"79\":{\"h\":\"Step5 locale\",\"t\":[\"用于提供多国翻译。格式与 Hydro 的 locale 文件夹格式相同。\"]},\"80\":{\"h\":\"介绍\",\"t\":[\"为什么使用 Hydro?\",\"安全:使用 Linux 容器技术(只读文件系统,命名空间和 cgroup )进行隔离,杜绝卡评测;\",\"高效:Hydro 使用了沙箱复用技术,拥有极高的评测效率;\",\"扩展:Hydro 支持安装额外模块进行扩展;\",\"强大:配合 Judge 模块(或 HydroJudge 独立评测机),可支持 spj,交互题,提交答案题,文件IO 等多种特性;\",\"自定:所有权限节点均可自由设置;\",\"易上手:无需改动源代码,系统设置中预留了大量可自行修改的内容;管理逻辑简洁;\",\"社区:Hydro 正在持续维护中;\",\"如果您正在使用 HustOJ,可以导出题目为 FPS 文件后使用 fps-importer 插件 直接导入 Hydro。\",\"如果您正在使用 QDUOJ, 可以导出题目为 QDUOJ-zip 格式后使用 import-qduoj 插件直接导入 Hydro。\",\"如果您正在使用 Vijos / SYZOJ / HustOJ / UniversalOJ, 可以直接使用 migrate 插件 导入所有数据至 Hydro。\"]},\"81\":{\"h\":\"功能对比\",\"t\":[\"Hydro 支持很多其他系统无法支持的题型,可在 https://hydro.ac/d/system_test/p 中查看并免费下载使用样例。(需要登录) 下方对比了 Hydro 与其他主流 OJ 系统的功能。(只进行在不修改源代码情况下的对比)\",\"+:支持 =:部分支持 ?: 未知 -:不支持 \",\"功能\",\"Hydro\",\"HustOJ\",\"SYZOJ[1]\",\"QDUOJ\",\"Vijos\",\"安装\",\"一键脚本\",\"一键脚本\",\"手动搭建\",\"docker\",\"docker\",\"数据库\",\"MongoDB\",\"MySQL\",\"MariaDB\",\"Postgres\",\"MongoDB\",\"测试数据存储\",\"本地/S3 [2]\",\"本地\",\"本地\",\"本地\",\"数据库\",\"多评测机\",\"+\",\"=[3]\",\"=[4]\",\"=\",\"+\",\"测试数据同步\",\"按需抓取\",\"全量同步\",\"全量同步\",\"全量同步\",\"按需抓取\",\"比赛\",\"ACM/OI/IOI/乐多\",\"ACM/OI\",\"ACM/OI/IOI\",\"ACM/OI/IOI\",\"ACM/OI\",\"封榜\",\"+\",\"+\",\"-\",\"-\",\"-\",\"作业功能\",\"+\",\"+\",\"-\",\"-\",\"+\",\"修改编译命令/添加语言\",\"+\",\"=[5]\",\"-\",\"-\",\"+\",\"权限系统 [6]\",\"+\",\"=\",\"-\",\"-\",\"+\",\"训练计划(题单)\",\"+\",\"+\",\"-[7]\",\"-\",\"+\",\"团队\",\"+ [8]\",\"-\",\"-\",\"-\",\"+\",\"Hack\",\"+\",\"-\",\"-\",\"-\",\"-\",\"SpecialJudge\",\"+ [9]\",\"+\",\"+\",\"-\",\"=\",\"Subtask\",\"+\",\"-\",\"+\",\"-\",\"-\",\"交互题\",\"+\",\"-\",\"+\",\"-\",\"-\",\"RemoteJudge\",\"CF/SPOJ/UOJ/POJ/Luogu\",\"HDU/PKU\",\"-\",\"-\",\"-\",\"题目导入\",\"fps/syzoj/qduoj/hydro\",\"fps/qduoj\",\"syzoj\",\"fps/qduoj\",\"-\"]},\"82\":{\"h\":\"截图\"},\"83\":{\"h\":\"现在开始\",\"t\":[\"点击 部署 ,开始部署您的 OJ 吧!\",\"SYZOJ 和 Lyrio (曾用名 syzoj-ng,loj.ac 当前所用系统) 是两套不同的系统,这意味着使用 SYZOJ 无法再导入 loj.ac 的题目,同时 Lyrio 无比赛功能。 ↩︎\",\"S3 指所有兼容 Amazon S3 协议的服务,包括腾讯COS,阿里OSS 等。 ↩︎\",\"安装配置繁琐,且需要手动在服务器间同步数据。 ↩︎\",\"需要手动在服务器间同步数据。 ↩︎\",\"仅能修改部分编译参数,添加语言需要修改源代码。 ↩︎\",\"此处的权限系统指 除用户/管理员二元化权限之外的 的更细粒度的权限划分。 ↩︎\",\"部分二次开发版本有此功能。 ↩︎\",\"通过域功能,允许用户创建域并在域内拥有管理员权限。域之间仅共享账号数据,也可使用域内小组进行权限控制。 ↩︎\",\"支持所有主流 SPJ 格式。 ↩︎\"]},\"84\":{\"h\":\"插件\",\"t\":[\"Hydro 支持使用插件扩展自身所支持的功能。\",\"Warning\",\"插件对站点的所有内容具有完全的访问权限,请不要启用来历不明的插件。\"]},\"85\":{\"h\":\"附加组件列表\",\"t\":[\"Tips\",\"部分插件(斜体标注)需配合第三方软件使用,如仅安装不配置/不安装第三方软件会导致系统无法正常运行,详情请前往左侧插件详情查看。\",\"Hydro 官方目前提供了以下附加组件:\",\"ID\",\"描述\",\"@hydrooj/blog\",\"博客功能\",\"@hydrooj/fps-importer\",\"导入 fps 格式的题目\",\"@hydrooj/geoip\",\"显示用户登录地(需要IP库支持)\",\"@hydrooj/hydrojudge\",\"评测组件\",\"@hydrooj/import-qduoj\",\"导入 QDUOJ 导出的题库\",\"@hydrooj/import-hoj\",\"导入 HOJ 导出的题库\",\"@hydrooj/login-with-github\",\"允许用户使用 GitHub 登录\",\"@hydrooj/login-with-google\",\"允许用户使用 Google 登录\",\"@hydrooj/migrate\",\"从 vijos4/HustOJ/SYZOJ/UniversalOJ 升级\",\"@hydrooj/recaptcha\",\"注册时启用 reCAPTCHA 验证码\",\"@hydrooj/ui-default\",\"Hydro 的默认用户界面\",\"@hydrooj/onlyoffice\",\"显示 doc/docx 格式题目\",\"@hydrooj/sonic\",\"基于 sonic 的题目搜索增强(需安装 sonic)\",\"@hydrooj/elastic-search\",\"基于 Elastic 的题目搜索增强(需安装 Elastic)\",\"@hydrooj/vjudge\",\"Codeforces/SPOJ/UOJ/POJ/Luogu\",\"@hydrooj/prom-client\",\"导出系统状态至 Prometheus\",\"大部分插件的配置均可在安装后于 控制面板>系统设置 中找到。\",\"部分插件若安装后没有正确配置可能会影响系统正常使用!\"]},\"86\":{\"h\":\"安装\",\"t\":[\"先全局安装所需模块,再向 hydrooj 注册即可。例:安装 @hydrooj/geoip\",\"yarn global add @hydrooj/geoip hydrooj addon add @hydrooj/geoip \",\"或者,如果你正在安装一个其他途径获取的插件(自行创建等),请直接使用文件夹 绝对路径: (文件夹路径即为 包含 package.json 的文件夹)\",\"hydrooj addon add /root/xxx \",\"请不要将插件与插件嵌套摆放,否则可能会导致一些不可预知的问题。\",\"安装完插件后需要重启 hydrooj 以使插件生效。\"]},\"87\":{\"h\":\"查看已注册的插件列表\",\"t\":[\"hydrooj addon list \"]},\"88\":{\"h\":\"更新\",\"t\":[\"yarn global upgrade-interactive --latest \"]},\"89\":{\"h\":\"卸载\",\"t\":[\"yarn global remove @hydrooj/geoip hydrooj addon remove @hydrooj/geoip \"]},\"90\":{\"h\":\"Elastic search\",\"t\":[\"Tips\",\"此插件需配合第三方软件 Elasticsearch 使用,如仅安装插件不配置/不安装第三方软件会导致系统无法正常运行,Elasticsearch 并非轻量化软件,如您的服务器不满足该软件要求不建议安装。\",\"安装 Elasticsearch 后安装 @hydrooj/elastic-search 插件。\",\"进入 HydroOJ 控制面板,在系统设置内正确填写 endpoint 。\",\"然后在脚本管理中找到重建题目索引,点击运行,参数留空即可。\",\"至此,搜索功能应当可以正常使用。\"]},\"91\":{\"h\":\"fps-importer\"},\"92\":{\"h\":\"从 fps 文件导入题目\",\"t\":[\"在题库右侧“创建题目”一栏中选择“从 FPS 文件导入”。 在打开的窗口中,您可以上传:\",\"fps 格式的 xml 文件\",\"zip 文件,其中包含了一个或多个 fps 格式的 xml 文件\",\"由于防止解析 fps 文件消耗大量内存,系统默认拒绝导入超过 64MiB 的文件;\\nxml 文件需要为 UTF8 编码,否则可能出现中文题面乱码;\\n在新版本 fps-importer 中,管理员可以修改导入文件大小限制,但请注意,我们仍不建议您导入过大的题目包。\\n若您的文件超过大小限制,可考虑先在本地使用 Easy-Fps-Viewer 等工具进行拆分。\"]},\"93\":{\"h\":\"GeoIP\",\"t\":[\"插件需要 MaxMind 的 Geolite2-City.mmdb 支持,在安装插件后需要将mmdb拷贝至插件同一目录下方可启用,如果你不知道这是什么,请勿安装。\"]},\"94\":{\"h\":\"hydrojudge\",\"t\":[\"Tips\",\"您可以通过一键安装脚本快速安装独立评测机,详情请前往 部署Hydro 查看。\"]},\"95\":{\"h\":\"准备\",\"t\":[\"在配置评测机之前,请确认您的站点已经可以访问并正常登录/注册。\",\"您应该预先下载您所要支持的语言的编译器,若您在配置完评测机后 升级/重新安装 了编译器,您需要重新启动沙箱。 关于编译器说明,请参照 编译器 章节。\",\"如果不使用自动脚本,您需要按照如下方式手动安装沙箱服务: 前往 criyle/go-judge 下载对应 cpu 架构的 go-judge。 go-judge 需要在后台运行并监听 127.0.0.1:5050 。如果系统使用的 cgroup 版本为 1 或者使用的为非 systemd init 的发行版,请以 root 权限运行。 可使用 pm2 进行管理。\"]},\"96\":{\"h\":\"安装\"},\"97\":{\"h\":\"作为附加组件\",\"t\":[\"Tips\",\"由于用附加组件安装的评测机与 Hydro 必须在同一台服务器上,每一个 Hydro 实例最多只能有一台评测机由附加组件安装。\",\"在安装 Hydro 的机器上运行下面的指令安装 @hydrooj/hydrojudge:\",\"yarn global add @hydrooj/hydrojudge hydrooj addon add @hydrooj/hydrojudge \",\"重启 Hydro 后 hydrojudge 即可正常运行。\"]},\"98\":{\"h\":\"作为独立进程\",\"t\":[\"Tips\",\"该方法可以帮助您在任意服务器上部署评测机。\",\"首先需要创建一个有 PRIV_JUDGE 权限的账户,具体方法参照 此处。(在部署 Hydro 的服务器上运行)\",\"然后在运行评测机的服务器上安装 HydroJudge :\",\". <(curl https://hydro.ac/setup.sh) --judge \",\"创建目录 ~/.config/hydro,在该目录下创建文件 judge.yaml,配置文件格式如下:\",\"hosts: localhost: type: hydro # vj4 用户请在此处填写 vj4 server_url: http://localhost/ # Hydro 运行的网址 uname: judge # 评测账号用户名 password: abc123 # 评测账号密码 detail: true # 默认为 true \",\"设置完之后,使用下面的指令即可开始运行(可以使用 pm2 管理):\",\"hydrojudge \"]},\"99\":{\"h\":\"更新\",\"t\":[\"HydroJudge 会发布不定期更新。您可以使用 yarn global upgrade-interactive --latest 来检测并进行更新。\"]},\"100\":{\"h\":\"关闭\"},\"101\":{\"h\":\"作为附加组件\",\"t\":[\"在 系统设置>hydrojudge 中有一栏 Disable builtin judge,将它勾上,然后重启 Hydro 即可。\"]},\"102\":{\"h\":\"作为独立进程\",\"t\":[\"根据开启的方法关闭即可。\"]},\"103\":{\"h\":\"卸载\",\"t\":[\"关闭后运行下面指令即可。\",\"yarn global remove @hydrooj/hydrojudge hydrooj addon remove @hydrooj/hydrojudge \"]},\"104\":{\"h\":\"评测设置\"},\"105\":{\"h\":\"作为附加组件\",\"t\":[\"在 系统设置>hydrojudge 修改对应的参数,然后重启 Hydro 和 hydrojudge 即可。\"]},\"106\":{\"h\":\"作为独立进程\",\"t\":[\"如果有需要修改单题测试点数量上限等设置,可以在 ~/.config/hydro/judge.yaml 的末尾添加下列内容:\",\"testcases_max: 100 # 单题最多测试点数量 total_time_limit: 120 # 单题最大总测试时长 parallelism: 2 # 单评测机评测进程数量 # 更多可选配置均可添加在此处,格式与前面的三排类似 \",\"在 此处 的设置均可添加到此处。\"]},\"107\":{\"h\":\"修改编译选项/添加新语言支持\",\"t\":[\"对于已安装内置评测机的用户(无论内置评测机是否启动),在 控制面板>系统设置 中修改 judge.langs 配置项即可;对于没有安装内置评测机的用户,需要在 ~/.config/hydro/langs.yaml 中配置。\",\"文件格式参照 此处 。\",\"如果您添加了新的语言,您还需要前往 控制面板>系统设置 中修改 Language Highlight ID 与 Monaco language modes。 分别表示选择对应的语言后的高亮设置(基于 PrismJS)和 Monaco 编辑器语法规则设置。\",\"修改完后请重启 Hydro 和 hydrojudge 。\"]},\"108\":{\"h\":\"测试数据格式\",\"t\":[\"参照 测试数据格式 配置。\"]},\"109\":{\"h\":\"调整沙箱空间大小\",\"t\":[\"Warning\",\"如果不调整沙箱的空间大小,当您的评测使用文件 IO 且输入输出文件较大时可能会引发错误。\",\"对于 2022/8/12 前安装的用户:\",\"在服务器上运行下面的代码找到 hydro-sandbox 的运行目录:\",\"pm2 info hydro-sandbox | grep \\\"exec cwd\\\" \",\"将 mount.yaml 下载并放置在 sandbox 的运行目录下。然后修改第 64 行和第 68 行的 size 和 nr_inodes 的大小至您想要的大小,保存后重启 sandbox 即可完成更改。\",\"对于 2022/8/12 后安装的用户:\",\"编辑 /root/.hydro/mount.yaml,修改 size 即可。\"]},\"110\":{\"h\":\"C/C++ 彩色编译错误信息\",\"t\":[\"确认您安装了支持彩色输出的编译器;\",\"在系统设置中,将 C/C++ 编译命令后加上 -fdiagnostics-color=always\",\"例:\",\"c: compile: /usr/bin/gcc -O2 -Wall -std=c99 -o ${name} foo.c -lm -fdiagnostics-color=always \"]},\"111\":{\"h\":\"开大程序运行栈空间\",\"t\":[\"2022/8/12 后安装的实例默认已开启无限栈空间,无需手动操作\",\"在很多时候系统默认为程序提供的栈空间并不能满足我们的需求,此时我们需要手动为用户程序提供更大的栈空间。\",\"修改 pm2 中 hydro-sandbox 的启动参数为 ulimit -s unlimited && /usr/bin/hydro-sandbox :\",\"pm2 del hydro-sandbox pm2 start bash --name hydro-sandbox -- -c \\\"ulimit -s unlimited && hydro-sandbox\\\" \"]},\"112\":{\"h\":\"提高测评精度\",\"t\":[\"禁用 CPU 频率缩放与 Intel 睿频加速技术,防止 CPU 频率波动。\",\"禁用内存地址空间随机化,以使得存在内存寻址错误的代码能够得到更多可重复的结果,可以通过在 /etc/sysctl.conf 中添加下面这行并运行 sudo sysctl -p 应用:\",\"kernel.randomize_va_space = 0 \"]},\"113\":{\"h\":\"内存计量不准确\",\"t\":[\"在控制面板上出现内容为 You are using cgroup v2 without kernel 5.19+. This could result in inaccurate memory usage measurements. 警告时,意味着当前系统的内存消耗计量存在误差。\",\"部分 Linux 设备默认使用 cgroup2,而在 5.19 版本前的内核的 cgroup2 中移除了精确计量内存消耗的接口。 若要获得更精确的内存计量,推荐启用 cgroup v1 (您可以通过检查 /sys/fs/cgroup/memory/memory.memsw.usage_in_bytes 是否存在来验证是否当前系统是否启用了 cgroup v1 ):\",\"以 Ubuntu 的默认引导器 GRUB 2 为例,编辑 /etc/default/grub: 在其中\",\"GRUB_CMDLINE_LINUX_DEFAULT=\\\"quiet splash\\\" \",\"后,加入 `cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0,变为:\",\"GRUB_CMDLINE_LINUX_DEFAULT=\\\"quiet splash cgroup_enable=memory swapaccount=1 systemd.unified_cgroup_hierarchy=0\\\" \",\"运行以下命令更新 GRUB 2 的配置,然后重新启动。\",\"update-grub && reboot \"]},\"114\":{\"h\":\"migrate\"},\"115\":{\"h\":\"从 HUSTOJ 升级\",\"t\":[\"Warning\",\"迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 HUSTOJ 的数据。 请注意备份相关文件。\",\"请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 HUSTOJ 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 HUSTOJ 数据库相同。\",\"安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateHustoj 的脚本。 其参数格式如下:\",\"{\\\"host\\\":\\\"localhost\\\",\\\"port\\\":3306,\\\"name\\\":\\\"jol\\\",\\\"username\\\":\\\"\\\",\\\"password\\\":\\\"\\\",\\\"domainId\\\":\\\"system\\\",\\\"contestType\\\":\\\"\\\",\\\"dataDir\\\":\\\"\\\",\\\"uploadDir\\\":\\\"\\\"} \",\"host: 数据库地址\",\"port: 数据库端口\",\"name: 数据库名,一般为 jol\",\"username&password: 账号密码,若无则填写空字符串\",\"domainId: 迁入的域,默认为 system\",\"contestType: oi 或者 acm,视情况而定\",\"dataDir: HUSTOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理)\",\"uploadDir: HUSTOJ 中 上传文件的位置(这里存储着上传的图片和文件等信息,默认已指定 /home/judge/src/web/upload/ ,如果此路径与您路径相同,请不要填写此项)\",\"当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 HUSTOJ 的管理员账号登录实例。\"]},\"116\":{\"h\":\"从 SYZOJ 升级\",\"t\":[\"SYZOJ 与 HUSTOJ 迁移方法类似,迁移脚本应运行名为 migrateSyzoj 的脚本外,SYZOJ无需 contestType 参数。 其参数格式如下:\",\"{\\\"host\\\":\\\"localhost\\\",\\\"port\\\":3306,\\\"name\\\":\\\"syzoj\\\",\\\"username\\\":\\\"\\\",\\\"password\\\":\\\"\\\",\\\"domainId\\\":\\\"system\\\",\\\"dataDir\\\":\\\"\\\"} \",\"host: 数据库地址\",\"port: 数据库端口\",\"name: 数据库名,一般为 syzoj\",\"username&password: 账号密码,若无则填写空字符串\",\"domainId: 迁入的域,默认为 system\",\"dataDir: SYZOJ 中 data 文件夹的位置(这里存储着题目数据等关键信息,需要手动处理)\",\"由于SYZOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 SYZOJ 的管理员账号登录实例。\"]},\"117\":{\"h\":\"从 UniversalOJ 升级\",\"t\":[\"UniversalOJ (常称作UOJ社区版)与前两者迁移方法类似,迁移脚本应运行名为 migrateUniversalOJ 的脚本。\",\"由于其升级过程较为麻烦,安装脚本已提供自动升级服务,如您需要可运行安装脚本一键迁移,手动迁移请在开发群中提问。\",\"由于UniversalOJ脚本会将原站所有数据迁移,所以运行耗时较长。 当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 UniversalOJ 的管理员账号登录实例。\"]},\"118\":{\"h\":\"从 Vijos 升级\",\"t\":[\"Warning\",\"迁移会删除当前 Hydro 的所有数据(含用户账户信息)并移入 vj4 的数据。 请注意备份相关文件。\",\"请先完成 Hydro 的部署并完成对文件服务的配置(setting_file)。 在迁移数据之前,请先停止正在运行的 vj4 服务,仅保留其数据库开启。 请注意 Hydro 所在的数据库不应和源 vj4 数据库相同。 若您使用 vj4-docker ,可更改 docker-compose.yml 将数据库映射至其他本机端口。\",\"安装插件后,您应当能够在 控制面板>脚本管理 中找到名为 migrateVijos 的脚本。 其参数格式如下:\",\"{\\\"host\\\":\\\"localhost\\\",\\\"port\\\":27017,\\\"name\\\":\\\"vj4\\\",\\\"username\\\":\\\"\\\",\\\"password\\\":\\\"\\\"} \",\"host: 数据库地址\",\"port: 数据库端口\",\"name: 数据库名\",\"username&password: 账号密码,若无则填写空字符串\",\"Tips\",\"vj4-docker 中数据库名为 vj4,无账号密码。\",\"当脚本运行完成后,请重启 Hydro 实例,会自动完成之后的升级操作。 迁移后,请使用原 vj4 的管理员账号登录实例。\",\"Warning\",\"若您的 vj4 是由 vj2 或 tyvj 升级而来,在迁移完成后请不要卸载该插件,否则可能导致部分用户无法登录。\"]},\"119\":{\"h\":\"recaptcha\",\"t\":[\"Tips\",\"我们采用 reCAPTCHA v3 来检验注册者是否是人类,在注册过程中没有看见传统验证码属正常现象。\",\"前往 https://www.google.com/recaptcha/admin/create 创建 reCAPTCHA 密钥。 reCAPTCHA 类型请选择“reCAPTCHA 第 3 版”。\",\"创建成功后将客户端密钥和服务端密钥分别填入系统设置 recaptcha 栏下的 key 和 secret 中,重启 Hydro 后 reCAPTCHA 即可正常工作。\"]},\"120\":{\"h\":\"Sonic\"},\"121\":{\"h\":\"安装\"},\"122\":{\"h\":\"\",\"t\":[\"使用 root 用户执行如下命令:\",\"nix-env -iA nixpkgs.sonic-server \"]},\"123\":{\"h\":\"安装 sonic 插件\",\"t\":[\"使用 root 用户执行如下命令:\",\"yarn global add @hydrooj/sonic hydrooj addon add @hydrooj/sonic \"]},\"124\":{\"h\":\"启动\",\"t\":[\"在 /root/.sonic/config.cfg(没有的自行建立,也可以换成其他的你喜欢的路径)按照以下配置示例写入配置。\",\"配置示例:\",\"# Sonic # Fast, lightweight and schema-less search backend # Configuration file # Example: https://github.com/valeriansaliou/sonic/blob/master/config.cfg [server] log_level = \\\"error\\\" [channel] inet = \\\"127.0.0.1:1491\\\" # 默认监听本机 tcp_timeout = 300 auth_password = \\\"SecretPassword\\\" [channel.search] query_limit_default = 10 query_limit_maximum = 100 query_alternates_try = 4 suggest_limit_default = 5 suggest_limit_maximum = 20 [store] [store.kv] path = \\\"/data/sonic/store/kv/\\\" retain_word_objects = 1000 [store.kv.pool] inactive_after = 1800 [store.kv.database] flush_after = 900 compress = true parallelism = 2 max_files = 100 max_compactions = 1 max_flushes = 1 write_buffer = 16384 write_ahead_log = true [store.fst] path = \\\"/data/sonic/store/fst/\\\" [store.fst.pool] inactive_after = 300 [store.fst.graph] consolidate_after = 180 max_size = 2048 max_words = 250000 \",\"执行如下命令:\",\"pm2 start sonic -- -c /root/.sonic/config.cfg pm2 save \"]},\"125\":{\"h\":\"配置\"},\"126\":{\"h\":\"后端地址配置\",\"t\":[\"进入 HydroOJ 控制面板,配置 sonic 后端地址。\",\"如果您直接复制配置示例,那么按照以下内容配置:\",\"host: 127.0.0.1\",\"port: 1491\",\"auth: SecretPassword\",\"修改完成后,重启 HydroOJ。\"]},\"127\":{\"h\":\"重启 HydroOJ\",\"t\":[\"执行命令 pm2 restart hydrooj。\"]},\"128\":{\"h\":\"重建题目索引\",\"t\":[\"进入 HydroOJ 控制面板,在脚本管理中找到重建题目索引,点击运行,参数留空即可。\",\"至此,搜索功能应当可以正常使用。\"]},\"129\":{\"h\":\"FAQ\"},\"130\":{\"h\":\"安装后题目搜索不正常\",\"t\":[\"请更新到 HydroOJ 最新版本后,再运行重建题目索引。\"]},\"131\":{\"h\":\"VJudge\",\"t\":[\"Warning\",\"此文档已过时,仅作留存使用,以下教程仅为示例,如想了解详细安装方法请前往 FAQS(常用教程) 查看具体使用指南。\",\"部分支持的远程站点对提交数量/访问次数/访问来源有一定限制,Hydro 不保证 VJudge 的 100% 可用性。\"]},\"132\":{\"h\":\"Codeforces\",\"t\":[\"安装插件后创建名为 codeforces 的域,进入数据库 db.domain.updateOne({_id:'codeforces'},{$set:{mount:'codeforces'}});\",\"在 codeforces 的域设置中,将 allowedLangs 如下配置(在新版即在允许提交的语言中选中所有 codeforces 开头的语言):\",\"codeforces,codeforces.43,codeforces.52,codeforces.50,codeforces.54,codeforces.59,codeforces.61,codeforces.65,codeforces.9,codeforces.28,codeforces.32,codeforces.12,codeforces.60,codeforces.36,codeforces.48,codeforces.19,codeforces.3,codeforces.4,codeforces.51,codeforces.13,codeforces.6,codeforces.7,codeforces.31,codeforces.40,codeforces.41,codeforces.67,codeforces.49,codeforces.20,codeforces.34,codeforces.55 \",\"在 vjudge 表中插入如下条目:\",\"{type:'codeforces', handle:'', password:''} \",\"将如下配置添加至 langs 设置末尾:\",\"codeforces: execute: none display: Codeforces domain: - codeforces # Allow domain 'codeforces' to use these languages codeforces.43: highlight: cpp astyle-c monaco: cpp display: GNU GCC C11 5.1.0 comment: // codeforces.52: highlight: cpp astyle-c monaco: cpp display: Clang++17 Diagnostics comment: // codeforces.50: highlight: cpp astyle-c monaco: cpp display: GNU G++14 6.4.0 comment: // codeforces.54: highlight: cpp astyle-c monaco: cpp display: GNU G++17 7.3.0 comment: // codeforces.59: highlight: cpp astyle-c monaco: cpp display: Microsoft Visual C++ 2017 comment: // codeforces.61: highlight: cpp astyle-c monaco: cpp display: GNU G++17 9.2.0 (64 bit, msys 2) comment: // codeforces.65: highlight: cpp astyle-cs monaco: csharp display: C# 8, .NET Core 3.1 comment: // codeforces.9: highlight: cpp astyle-cs monaco: csharp display: C# Mono 6.8 comment: // codeforces.28: highlight: d monaco: plain display: D DMD32 v2.091.0 comment: // codeforces.32: highlight: go display: Go 1.15.6 comment: // codeforces.12: highlight: haskell display: Haskell GHC 8.10.1 comment: -- codeforces.60: highlight: java astyle-java monaco: java display: Java 11.0.6 comment: // codeforces.36: highlight: java astyle-java monaco: java display: Java 1.8.0_241 comment: // codeforces.48: highlight: kotlin display: Kotlin 1.4.0 comment: // codeforces.19: highlight: ocaml monaco: plain display: OCaml 4.02.1 comment: ['(*','*)'] codeforces.3: highlight: pascal display: Delphi 7 comment: // codeforces.4: highlight: pascal display: Free Pascal 3.0.2 comment: // codeforces.51: highlight: pascal display: PascalABC.NET 3.4.2 comment: // codeforces.13: highlight: perl display: Perl 5.20.1 comment: '#' codeforces.6: highlight: php display: PHP 7.2.13 comment: // codeforces.7: highlight: python display: Python 2.7.18 comment: '#' codeforces.31: highlight: python display: Python 3.9.1 comment: '#' codeforces.40: highlight: python display: PyPy 2.7 (7.3.0) comment: '#' codeforces.41: highlight: python display: PyPy 3.7 (7.3.0) comment: '#' codeforces.67: highlight: ruby display: Ruby 3.0.0 comment: '#' codeforces.49: highlight: rust display: Rust 1.49.0 comment: // codeforces.20: highlight: scala display: Scala 2.12.8 comment: // codeforces.34: highlight: javascript display: JavaScript V8 4.8.0 comment: // codeforces.55: highlight: javascript display: Node.js 12.6.3 comment: // \",\"之后再重启 Hydro 即可。\"]},\"133\":{\"h\":\"部署 Hydro\",\"t\":[\"这里提供了几套方案帮助您建立自己的站点,请选择适合您的方案并继续。 搭建过程中如果遇到问题欢迎 联系我们 提问。\"]},\"134\":{\"h\":\"服务器选择\",\"t\":[\"不同服务商提供的 CPU 主频不同,下方数据仅供参考。 最低服务器配置: CPU: 1核 内存: 2G。(约可允许 100 人使用)请尽量不要使用突发性能实例或共享型实例,这可能会导致评测时间计量不准确\",\"CentOS 8 已于 2021-12-31 停止支持,后续不会为安全漏洞发布补丁,建议重装为其他操作系统。\",\"Tips\",\"兼容大部分 Linux 发行版,推荐使用 Debian 12 / Debian 11 / Ubuntu 22.04 (教程多,成功率高,上手简单),不支持 CentOS 及其各种变种:\",\"CentOS\",\"Alibaba Cloud Linux\",\"TencentOS\",\"OpenCloudOS\",\"如果你的机器内存较小(<=2GiB),请避免使用 Ubuntu 22.04,它会消耗较多的内存。建议使用 Debian 12 / Debian 11。 如果你有 Linux 运维经验,Hydro 同样支持在 Alpine Linux 上运行,Alpine Linux 系统启动后仅占用 ~100M 内存,是在低配置服务器上运行的更优方案。\",\"Warning\",\"虚拟机用户请注意:\",\"Hydro 使用的数据库依赖于 CPU 的 avx 指令集以提高运行性能,大部分虚拟机软件默认没有启用 avx 指令集,请参照您使用的虚拟机软件说明。\",\"虚拟机由于非独占 CPU,会导致评测时间计量精度降低。\",\"由于虚拟机本身的数据保存机制,突然断电很容易导致数据库损坏无法读取,请务必定期备份数据库,有条件请购买 UPS 保证供电稳定。\",\"Docker 用户请注意:\",\"使用安装脚本需要设置 USER 环境变量为 root。\",\"需要使用 --privileged 参数启动容器,否则评测机无法运行。\",\"开发组不对 docker 部署提供技术支持。\"]},\"135\":{\"h\":\"部署\",\"t\":[\"Tips\",\"Hydro 需要使用以下端口: 80, 443, 2019, 8888, 5050, 27017,请确保这些端口空闲。安装和安装后的所有操作均需要在 root 权限下进行!(sudo su)。 宝塔面板已知出现多次高危漏洞,为防止数据丢失,请不要在生产环境中使用!\",\"运行下面的脚本,等待几分钟即可(建议复制防止敲错):\",\"LANG=zh . <(curl https://hydro.ac/setup.sh) \",\"Tips\",\"如果有特殊需求,安装脚本支持一些可选的高级选项,以此方式调用: . <(curl https://hydro.ac/setup.sh) --foo --bar\",\"--no-caddy 不配置安装反向代理,只监听8888端口\",\"--judge 仅作为独立评测机安装\",\"阿里云/腾讯云/华为云等等用户安装后如果不能访问 请百度搜索 xx云 放行80端口 脚本默认使用的为清华大学镜像。 安装完成后,从 http://服务器ip/ 访问网页端,注册一个账号,之后在终端中使用\",\"hydrooj cli user setSuperAdmin 2 \",\"将首个注册用户设置为超级管理员。之后刷新页面,您应当能在上方导航栏看到控制面板入口。 进入控制面板,右侧系统设置,验证管理员密码后按需修改配置,注意 Server BaseURL 一项需要填写访问网站用的完整的 URL,以 / 结尾。(重要,务必正确填写,样例:https://hydro.ac/)\",\"系统安装后需要题库,可前往 https://hydro.ac/d/tk/p 免费专区进行下载,支持批量导入。\\n至此,基础功能安装已全部完成,另,如果你的服务部署在内网,且希望外网的用户可以访问,可以百度搜索 “端口映射” 相关教程。\"]},\"136\":{\"h\":\"编译器\",\"t\":[\"从 2022/8/12 开始,Hydro 为了避免宿主机环境变化对于评测的影响,对于 此后新安装的实例 默认使用 nix 管理环境。 如果你是在这之前安装的 Hydro,请使用 apt 安装编译器后使用 pm2 restart hydro-sandbox 重启沙箱,并忽略本章节。\",\"以下是 nix 的简要操作说明:\",\"使用 nix-env -iA nixpkgs.编译器名 安装新编译器,后重启沙箱 pm2 restart hydro-sandbox 生效。\",\"可以在 Nixos Search 中搜索你需要的编译器。 以下是常用编译器的示例:\",\"nix-env -iA nixpkgs.busybox nixpkgs.bash nixpkgs.diffutils nixpkgs.unzip # 基础组件,已预装,不建议删除 nix-env -iA nixpkgs.gcc nixpkgs.fpc # C/C++ 和 Pascal,已预装,不建议删除 nix-env -iA nixpkgs.ghc # Haskell nix-env -iA nixpkgs.rustc # Rust nix-env -iA nixpkgs.python2 # Python2 nix-env -iA nixpkgs.pythonPackages.numpy # Python2 Numpy 库 nix-env -iA nixpkgs.python3Minimal nix-env -iA nixpkgs.python3Packages.numpy nix-env -iA nixpkgs.php # PHP nix-env -iA nixpkgs.go # Golang nix-env -iA nixpkgs.nodejs # NodeJS nix-env -iA nixpkgs.openjdk_headless # Java nix-env -iA nixpkgs.ruby # Ruby nix-env -iA nixpkgs.mono # C# nix-env -iA nixpkgs.julia_17-bin # Julia \",\"使用 nix-env -q 查看已安装的列表,后使用 nix-env -e 编译器名 即可删除对应的编译器。 请注意不要误删 Hydro 基础组件,且操作完成后需要重启沙箱 pm2 restart hydro-sandbox 生效。\"]},\"137\":{\"h\":\"进阶\",\"t\":[\"如果你需要更加复杂的编译环境配置,我们建议使用编写单独的 nix 文件。\",\"{ system ? builtins.currentSystem, pkgs ? import { system = system; } }: pkgs.buildEnv { name = \\\"hydrojudge-rootfs\\\"; paths = with pkgs; [ coreutils bash diffutils nix zip unzip gcc # 上方包是评测所需要的,请勿删除, # 在下方列出你所需要的包,查找方式同上文: fpc python3 rustc ]; ignoreCollisions = true; pathsToLink = [ \\\"/\\\" ]; # 导出一些基本信息和部分编译器所需的 /etc/passwd postBuild = '' mkdir $out/buildInfo echo 'root:x:0:0:root:/root:/bin/bash' >$out/etc/passwd date >$out/buildInfo/timestamp ''; } \",\"复制以上文件,保存为 default.nix ,使用 nix-build 进行构建。 构建后会产生一个 result 文件夹,记住该文件夹所在的路径。 打开 ~/.hydro/mount.yaml 将其中 /root/.nix-profile 替换为编译出的 result 文件夹(切换到新的环境) 之后保存并重启沙箱。\",\"后续若需更改环境配置,仅需要修改 default.nix 文件之后 nix-build 重新构建,再重启沙箱即可生效。 构建过程中的缓存文件可以使用 nix-collect-garbage 进行清理。\",\"更详细的 nix 语言介绍,请参照 Nix Guide 和\\nNix Manual。\"]},\"138\":{\"h\":\"反向代理 / SSL 配置\"},\"139\":{\"h\":\"2022/10/27 后使用脚本安装的实例已自动配置 Caddy 反向代理,请直接编辑位于 的配置文件!\",\"t\":[\"Warning\",\"若使用反向代理,请注意系统设置中的 server.xff 和 server.xhost 设置项需要填写正确(小写),分别对应反向代理所添加的标头名(通常为 x-forwarded-for 和 x-forwarded-host,部分反代工具会使用 x-real-ip 替代 x-forwarded-for)。 server.xhost 设置项配置错误会导致用户无法登录等问题。(CsrfTokenError) server.xff 设置项配置错误会导致无法记录用户IP。\",\"除一键安装脚本在安装 Caddy 后会自动配置设置项,其他工具请在使用工具前先配置好系统设置!否则将造成用户无法登录、无法记录用户IP等问题。\",\"若您使用 Nginx,请注意配置 WebSocket 协议的反向代理,否则会导致评测状态无法自动刷新,在线 IDE 无法正常使用等问题。\",\"Hydro 支持使用 Caddy, HaProxy 等工具进行反向代理,此处 提供了一些配置样例。\",\"Hydro 推荐您使用 Caddy。以下为样例 Caddyfile。 提示:如果您的服务器位于国内,则需要进行备案后才能使用 80 和 443 端口。\",\"hydro.ac { log { output file /data/access.log { roll_size 1gb roll_keep_for 72h } format json } root * /root/.hydro/static @static { file { try_files {path} } } handle @static { file_server } handle { reverse_proxy http://127.0.0.1:8888 } } \"]},\"140\":{\"h\":\"存储\",\"t\":[\"Tips\",\"使用一键安装脚本部署的 Hydro 一般已自动完成存储配置。\",\"文件默认存储于本地的 /data/file/hydro 目录下,切换存储后端时需要手动复制或移动原有文件。 请根据你使用的存储端类型阅读对应教程。(同时欢迎使用其他存储类型的用户向我们提供详细的存储教程)\"]},\"141\":{\"h\":\"使用 S3 作为存储后端\",\"t\":[\"Tips\",\"如果关闭了 file.pathStyle 选项,请在 endPointForUser 和 endPointForJudge 设置中填写真实 url,/fs/ 端点将不可用。\",\"MinIO\",\"Warning\",\"新版本 MinIO 占用较大,如果您为轻量使用,我们不建议使用 MinIO 。旧版本 Hydro 用户大部分可直接切换至 file 模式,由 Hydro 代替读取。\",\"安装 MinIO 后进入 控制面板>manage_config。\",\"file.type: s3\",\"file.endPoint: http://127.0.0.1:9000(即 MinIO 启动时显示的 endPoint)\",\"file.accessKey: 参照 MinIO 配置\",\"file.secretKey: 参照 MinIO 配置\",\"file.bucket: hydro(MinIO 内部存储桶名称)\",\"file.region: us-east-1\",\"file.pathStyle: true\",\"file.endPointForUser: /fs/\",\"file.endPointForJudge: /fs/\",\"保存后重启,已有文件请自行复制。\",\"腾讯云COS\",\"进入 控制面板>系统设置>存储桶设置。\",\"file.type: s3\",\"file.endPoint: https://cos.<存储桶地域>.myqcloud.com (或是 https)\",\"file.accessKey: 您的腾讯云 API 密钥的 SecretId\",\"file.secretKey: 您的腾讯云 API 密钥的 SecretKey\",\"file.bucket: <存储桶名称>\",\"file.region: Auto\",\"file.pathStyle: false\",\"file.endPointForUser: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/\",\"file.endPointForJudge: https://<存储桶>.cos.<存储桶地域>.myqcloud.com/\",\"保存后重启,已有文件请自行复制。\",\"阿里云OSS\",\"// TODO & PRs Welcome\"]},\"142\":{\"h\":\"SMTP\",\"t\":[\"以 QQ 邮箱为例。\",\"SMTP_USER: 12345678@qq.com\",\"SMTP_PASS: 提供的 SMTP 密码\",\"SMTP_HOST: smtp.qq.com\",\"SMTP_PORT: 465/587 (请参照邮件服务商说明)\",\"SMTP_SECURE: 是否使用加密 TLS 连接(请参照邮件服务商说明,使用 STARTTLS 的服务商无需勾选)\",\"SMTP_FROM: 发送签名(提示:若不清楚请填写邮件地址,填错会导致邮件无法发送)\",\"已知能够完整兼容的服务商有:\",\"QQ 邮箱\",\"腾讯企业邮\",\"网易 163 邮箱\",\"飞书域名邮箱\",\"Zeptomail\",\"Zoho Mail\",\"Outlook\",\"Gmail\",\"新浪邮箱\",\"如果使用其他服务商且没有发现问题,欢迎向此列表 Pull Request。\"]},\"143\":{\"h\":\"常见问题\",\"t\":[\"已移动至 此处\"]},\"144\":{\"h\":\"使用内容分发网络\",\"t\":[\"如您希望改善 Hydro 的访问质量,在您的服务器带宽较小的情况下,您可以考虑使用内容分发网络,即 CDN ,通常情况下您仅需设置资源 CDN 即可大幅度改善访问质量,关于如何使用内容分发网络和使用中的任何问题请联系各大云厂商。\"]},\"145\":{\"h\":\"资源 CDN\",\"t\":[\"创建并配置好资源 CDN ,在控制面板中将 server.cdn 设置项修改为 CDN 域名。(如 https://cdn.hydro.ac/,以 / 结尾)。\"]},\"146\":{\"h\":\"全站 CDN\",\"t\":[\"如果您预算充足,可以使用全站 CDN。\",\"Warning\",\"全站 CDN 配置较为繁琐,如您没有相关使用经验请仅建立并配置资源 CDN ,配置资源 CDN 在大部分情况下即可大幅度改善访问质量。 因各服务商全站 CDN 配置方法不同,配置过程不同,需要配置的内容较多,以下仅为参考配置且配置补全,如果有任何问题建议先查阅云服务商文档及咨询云服务商工程师。\",\"缓存设置可以参考以下设置:\",\"类型\",\"内容\",\"缓存行为\",\"全部文件\",\"全部文件\",\"遵循源站\",\"文件后缀\",\"jpg,js,png,css,gif\",\"缓存一天\",\"同时设置添加回源HTTP请求头\",\"头部参数\",\"头部取值\",\"X-Forward-For\",\"参考所使用服务商CDN文档来设置用户来源IP\",\"且您应当修改系统设置中的 server.xff 值为 X-Forwarded-For,该设置是为了能够让系统正确获取到用户的IP地址。\"]},\"147\":{\"h\":\"Hydro Cli\",\"t\":[\"Tips\",\"在使用 cli 之前,请完成数据库配置。 指令中使用 <> 括起来的参数必须给出,用 [] 括起来的参数可以给出,若不给出则按照默认设置。用户请根据自己的情况替换掉用 <> 或是 [] 包括起来的部分(括号也应替换)\",\"cli 可以帮助用户在控制台下快捷地进行一些操作。 这些命令需要以在终端以 root 用户执行(安装时执行命令的位置)。 下面给出了一些常用的例子。\"]},\"148\":{\"h\":\"创建用户\",\"t\":[\"Tips\",\"很少使用。建议通过 控制面板>导入用户 功能代替\",\"hydrooj cli user create # 该用户的邮箱、用户名和密码 # 如创建邮箱为 hydro@hydro.local,用户名为 Hydro,密码为 hydrohydro ,UID 为 2 的用户: # 请确保 UID 为不小于 2 的正整数且未被占用,邮箱和用户名均不重复。 hydrooj cli user create hydro@hydro.local Hydro hydrohydro 2 \",\"若一切正常,运行该指令后您会从命令行窗口中看到该用户 uid。\"]},\"149\":{\"h\":\"设置全站管理员\",\"t\":[\"hydrooj cli user setSuperAdmin # 如设置 uid 为 2 的用户为管理员: hydrooj cli user setSuperAdmin 2 \"]},\"150\":{\"h\":\"设置用户权限\",\"t\":[\"hydrooj cli user setPriv \",\"关于参数 [priv] ,可阅读 此处。\"]},\"151\":{\"h\":\"更改用户密码\",\"t\":[\"hydrooj cli user setPassword # 如将 uid 为 1 的用户的密码改为 hydrohydro: hydrooj cli user setPassword 1 hydrohydro \"]},\"152\":{\"h\":\"创建评测账号\",\"t\":[\"先 创建一个账号。\",\"您需要留意运行此指令返回的数字,表示该用户的 uid,需要填入下面的指令中,然后给予该账号评测权限。\",\"hydrooj cli user setJudge \",\"完成后将配置的用户名及密码写入评测机配置文件,评测机即可连接到网页端。\"]},\"153\":{\"h\":\"黑名单相关\",\"t\":[\"用户封禁:\",\"hydrooj cli user setPriv 0 \",\"IP/邮箱域名封禁:\",\"# key 格式为 ip::xxx.xxx.xxx.xxx (封禁 IP 访问) 或是 mail::xxx.com (禁止 xxx.com 的邮箱注册) hydrooj cli blacklist add [duration] # 将 拉入黑名单,时长为 [duration] (以月为单位的整数,默认为 12,若 duration=0 则永久封禁) hydrooj cli blacklist get # 获取黑名单中有关 的信息 hydrooj cli blacklist del # 将 移出黑名单 \"]},\"154\":{\"h\":\"命令列表\",\"t\":[\"所有于 此文件夹 下的函数均可用 cli 调用。\",\"这里并没有列出所有可以运行的指令,因为其中很多功能我们更推荐通过 Web 访问。\",\"hydrooj cli user create [uid] [regip] [priv] # 创建邮箱为 ,用户名为 ,密码为 ,ID 为 [uid],注册 ip 为 [regip],权限为 [priv] 的用户 hydrooj cli user setUname # 将 ID 为 的用户的用户名设置为 hydrooj cli user setPriv # 将 ID 为 的用户的权限设为 hydrooj cli user setPassword # 将 ID 为 的用户的密码设置为 hydrooj cli user setEmail # 将 ID 为 的用户的邮箱设置为 hydrooj cli user setSuperAdmin # 将 ID 为 的用户设为全站管理员 hydrooj cli problem import # 将 的Hydro格式题目包导入至 域中 hydrooj cli problem export # 将 域中的所有题目包导出 hydrooj cli system set # 修改系统设置 值为 \"]},\"155\":{\"h\":\"数据库备份和恢复\"},\"156\":{\"h\":\"进入数据库\",\"t\":[\"Warning\",\"非常不推荐直接操作数据库!\",\"当你改动一个字段的时候,可能与其相关的部分忘记修改,改完觉得好像没什么问题,过段时间发现了一些异常,根本不会想到是你这次改数据库导致的,之后又不会修。\",\"直接修改数据库后,可能没有通知主程序,缓存仍然存在,表现为修改不生效。\",\"直接操作数据库的权限过大,若操作失误带来的影响通常是灾难性的。\",\"在绝大部分情况下均不需要/不可以直接操作数据库。若确需要,可使用 hydrooj db 命令打开数据库 shell,也可以从 ~/.hydro/config.json 查找数据库 connection string 并使用外部工具进行连接。\",\"注:MongoDB 的用户是附加在特定数据库中的,使用外部工具连接请确保使用了正确的 authSource 选项。\"]},\"157\":{\"h\":\"快速备份与恢复\",\"t\":[\"为了保证数据安全,请定期备份。\",\"若您使用自动脚本安装,可使用 hydrooj backup 快捷备份数据,备份完成后会在当前目录生成备份压缩包文件,您可使用 hydrooj restore <备份文件路径> 恢复之前备份的数据。\"]},\"158\":{\"h\":\"手动备份\",\"t\":[\"可使用 MongoDB 自带的 mongodump 进行数据库备份。并将 /data/file 文件夹备份即可。\",\"对于数据库,请请不要在数据库运行时直接拷贝数据库文件夹。请每次备份后检查生成的备份文件的大小和内容,确保备份成功。 请不要把备份数据和 Hydro 系统放在同一台机器上,这样数据丢失的风险仍然较高。\"]},\"159\":{\"h\":\"手动恢复备份\",\"t\":[\"使用 MongoDB 自带的 mongorestore 导入备份的数据库文件,并还原 /data/file 目录文件。\\n如果只是想不同机器之间迁移部署,只需要在停止 Hydro 和 MongoDB 服务后将相关文件夹(通常为 /data/db 与 /data/file 与 /root/.hydro/config.json )复制即可。\"]},\"160\":{\"h\":\"前端修改\",\"t\":[\"此指南将教您修改前端文件。\",\"如果您正在使用开发者模式,请直接修改 packages/ui-default/templates 下的文件。\",\"如果您使用安装脚本部署:\",\"请先使用 hydrooj addon create 创建一个本地插件(如果之前没有做过的话)。\"]},\"161\":{\"h\":\"修改页面翻译或是添加新语言:\",\"t\":[\"修改翻译:在 zh.yaml 内搜索您需要修改的翻译内容,并将 其所在行而非整个文件 修改后添加至 ~/addon/locales/zh.yaml 。\",\"添加语言:可参照 zh.yaml 格式创建一个新文件。欢迎社区参与多国化翻译工作。\"]},\"162\":{\"h\":\"修改页面模板:\",\"t\":[\"通常的,在您访问的 url 前加上 view-source:(如 view-source:https://hydro.ac 即可查看页面源代码,在第二行的 中 data-page 值即为页面名(首页例外,为 main.html)。 在 默认 templates 中找到对应文件,将文件的全部内容 复制到 ~/addon/templates/ 文件夹下后进行修改即可。\",\"特别的,创建题目时的默认模板位于 partials/problem_default.md,创建训练计划时的默认模板位于 partials/training_default.json,修改方式同上。\",\"以上所有更改均会在重启 Hydro 后生效。\"]},\"163\":{\"h\":\"导入用户\",\"t\":[\"目前支持 csv 格式(用 , 分隔)或 Excel 格式(用 TAB 分隔) 导入用户数据, 数据既可以用文本编辑器创建,也可以用 Excel 等软件来辅助创建。\",\"每行最少三列,最多五列,分别为: 邮箱,用户名,密码,显示名,用户信息。(显示名和用户信息为可选) 请使用 UTF-8 编码,否则中文可能会乱码。 如果使用 CSV 格式(逗号分隔),则用户信息列不可用。\",\"foo@undefined.moe user1 password1 bar@undefined.moe user2 password2 temp test@undefined.moe user3 password3 test {\\\"group\\\":\\\"class1\\\",\\\"studentId\\\":\\\"123\\\",\\\"school\\\":\\\"Hydro School\\\"} \",\"可以在粘贴后点击预览验证复制入的数据的有效性\",\"这将创建三个用户:\",\"user1 密码为 password1 , 邮箱 foo@undefined.moe;\",\"user2 密码为 password2 ,邮箱 bar@undefined.moe,显示名为 temp;\",\"user3 密码为 password3,邮箱 test@undefined.moe,显示名为 test,学校为 Hydro School,学号为 123,该用户将会被分配至当前域的 class1 小组内;\",\"Warning\",\"用户创建后无法删除,请谨慎操作\"]},\"164\":{\"h\":\"维护\"},\"165\":{\"h\":\"PM2\",\"t\":[\"使用一键安装脚本安装的 Hydro 使用 PM2 对进程进行管理。\"]},\"166\":{\"h\":\"进程名称\",\"t\":[\"可以通过下面的指令查看当前 PM2 正在管理的所有进程。\",\"pm2 ls \",\"一键安装脚本默认会创建下面几个进程:\",\"hydrooj: Hydro 主进程\",\"hydro-sandbox: Hydro 评测沙箱\",\"mongodb: MongoDB 数据库\",\"caddy: 反向代理\",\"后文的指令中将用 替代此处的进程名称,用 替代进程 ID(进程 ID 可通过 pm2 ls 查看)。(尖括号同样需要替换)\"]},\"167\":{\"h\":\"PM2 基本指令\",\"t\":[\"pm2 ls # 查看进程列表 pm2 start # 启动进程 pm2 stop # 关闭进程 pm2 restart # 重启进程 pm2 del # 删除进程 pm2 log --lines=100 # 查看该进程的后 100 行日志 pm2 attach # 与进程交互 pm2 save # 保存对 PM2 进行的修改(在添加、修改、删除进程后需要执行该指令) \",\"在部分环境(常见于 lxc 容器或是精简版系统)下,服务器重启后 Hydro 可能不能正常自启动,这时请使用 pm2 resurrect 手动载入进程列表。\",\"如果手动修改进程列表且已经覆盖掉保存的原列表,请使用 pm2 stop all && pm2 del all 清空所有进程之后重新运行安装脚本。原有数据不会丢失。\",\"Hydro 主进程同样支持多进程启动,但在中低端服务器(不超过4核)中没有必要使用多进程启动 Hydro,会降低性能且成倍提高内存占用。\",\"pm2 start hydrooj -i # 以 n 进程启动 Hydro 主进程 \"]},\"168\":{\"h\":\"更新\",\"t\":[\"Hydro 系统会不定期发布更新,可以使用下面的命令获取更新。\",\"无特殊情况请 不要更新PM2 !此操作可能导致进程列表丢失!\",\"yarn global upgrade-interactive --latest # 在交互式界面中选择想要更新的组件 pm2 restart hydrooj # 更新完后需重启 hydrooj \"]},\"169\":{\"h\":\"查看已安装版本\",\"t\":[\"cd `yarn global dir` && yarn list --pattern hydrooj \"]},\"170\":{\"h\":\"清除缓存\",\"t\":[\"yarn cache clean && nix-collect-garbage \"]},\"171\":{\"h\":\"现场赛指南\",\"t\":[\"本指南适用于希望进行线下赛,在内网部署评测设施的用户。 以下日期排期仅供参考,具体可根据实际情况自行安排。\",\"本文部分内容同样适用于 DOMJudge。\"]},\"172\":{\"h\":\"Day -1 准备工作\",\"t\":[\"请检查下述列表是否均按需求配置完成:\",\"关于选手机设置:\",\"选手机预装了 Linux 系统,并有对应的开发环境。\",\"推荐使用 CAICPC 作为安装镜像,直接选择第二项启动选项即可一键安装。\",\"选手机均连接到内网,且选手机之间无法互相访问,但可以访问公网服务器(若使用的路由器不支持该功能可以在选手机使用 iptables 拦截其他流量)。\",\"可使用 DHCP 配置选手机网络,但需保证地址租期足够长(推荐七天)。\",\"关于服务器设置:\",\"服务器使用固定 IP,并可以访问内网中任何设备(含选手机);\",\"服务器安装了较新内核的 Linux 系统。已知旧版本的内核在高负载的情况下可能出现锁死的问题 详情;\",\"关于 CAICPC 镜像:\",\"本镜像基于标准 ICPC 镜像修改而来。\",\"添加了状态上报,用于统一监测服务器状态;\",\"支持调用 VLC 截取屏幕和摄像头流供 live 模块使用;\",\"支持批量下发管理命令(一键锁屏/解锁/重启/显示座位号等等);\"]},\"173\":{\"h\":\"Day 0 准备工作\",\"t\":[\"使用安装脚本安装 Hydro。\",\"导入所需的比赛用户。\",\"安装 @hydrooj/onsite-toolkit 插件。\",\"参照 https://github.com/hydro-dev/xcpc-tools 说明安装独立模块。\",\"由志愿者打开所有选手机桌面上的 seat.txt 文件,填入座位号,保存,后台所见座位号应当同步刷新;\",\"如果需要根据座位号自动登录,此时导出 IP/队伍 表,在 onsite-toolkit 设置中填入。\",\"准备完成后,批量修改选手机为强密码!!!\",\"// TODO: tools 配置\",\"关于打印:\",\"打印功能在 xcpc-tools 中配置。\",\"在 server 端新建一个打印机 token,在赛场旁摆放一台电脑,安装对应的打印机驱动,以 client 模式运行 xcpc-tools,填入 token,即可连接。\",\"xcpc-tools 会自动抓取打印任务自动打印,默认每个文件最多打印五页,队伍名称和座位号会在纸张顶部。\",\"关于气球:\",\"气球通常由小票机进行打印。每当有队伍通过题目时,会打印一张小票;\",\"小票内含队伍名,座位号,气球颜色,该队伍当前的所有气球颜色等信息,志愿者拿到小票后根据其上内容分发气球。\",\"关于自动登录:\",\"启用后,在地址列表的用户均会自动登录上指定的对应账户,用户不可重新登录,不可登出,不可在其他 IP 登录。 操作前请确认列表中不含管理员账号和管理员所使用的机器 IP !\",\"可选:\",\"安装 grafana 和 netdata 用于监测服务器运行状态 以及给领导展示;\"]},\"174\":{\"h\":\"Day 1 热身赛\",\"t\":[\"热身赛通常使用至少一道可以反复提交爆破的题目,引导选手大量提交,测试服务器负载情况。\"]},\"175\":{\"h\":\"Day 2 正式赛\",\"t\":[\"如果需要发气球请提早给气球打气(通常比赛的前一小时气球组会非常忙)\",\"记得给打印机补纸,小票机同理。\",\"// TODO: 滚榜设置\"]},\"176\":{\"h\":\"用户文档\"},\"177\":{\"h\":\"题目难度\",\"t\":[\"Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。\",\"一般地,难度的数值越大,该题目越难。\",\"新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。\",\"越早递交评测的用户代码的评测结果对题目难度影响越大。\",\"题目的难度由算法计算得出,有可能出现不准确的结果。\"]},\"178\":{\"h\":\"参与比赛\",\"t\":[\"您可以在比赛的详细界面内点击“参与比赛”按钮进行参与。 比赛过程中“成绩表”会根据比赛规则显示排名。 在比赛截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。\"]},\"179\":{\"h\":\"发布讨论\",\"t\":[\"若您想发布一个讨论,请先进入一个讨论节点,之后点击“创建一个讨论”按钮并填写:\",\"标题;\",\"内容;\",\"是否高亮:若选择后,该贴的左边将有醒目的红色线条(需要“高亮讨论”权限);\",\"Pin:该讨论是否置顶(需要“置顶讨论”权限)。\",\"之后点击“创建”按钮进行发布。\"]},\"180\":{\"h\":\"认领作业\",\"t\":[\"您可以在作业的详情页面中,点击“认领作业”。\\n在作业开始之前,您无法查看作业中的题目。\\n在作业持续时间内,您与他人的做题情况会被实时统计在“成绩表”内。\\n在作业进入延期阶段后,您仍然可以提交题目,但成绩表内的分数将根据延期扣分规则按百分比折算。\\n在作业截止之后,您仍然可以订正其中的题目,但“成绩表”将停止更新。\"]},\"181\":{\"h\":\"复制题目\",\"t\":[\"复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛/作业/训练计划中使用这些题目。\"]},\"182\":{\"h\":\"操作流程\",\"t\":[\"进入需要复制的题目页面或是题目列表页面。\",\"点击右侧栏底部的“复制”按钮或是多选题目后点击右侧复制题目按钮。\",\"在弹出的窗口中输入需要复制到的域的 ID。\",\"点击“确定”后将自动跳转到复制后的题目连接。\"]},\"183\":{\"h\":\"\",\"t\":[\"不允许查看/修改复制后的题目的测试数据。\",\"不能复制一个复制来的题目。\",\"部分题目可能不允许复制。这遵循 域设置>编辑域资料 中的管理员设定。\"]},\"184\":{\"h\":\"域\"},\"185\":{\"h\":\"简介\",\"t\":[\"域功能类似团队,允许在一套系统中创建多个环境(如不同班级,或是不同功能,等等) 用户可以创建多个域。(需要用户有 PRIV_CREATE_DOMAIN 权限,默认仅开放给管理员账户)。 域间数据完全独立,仅用户信息相通(注册账户后,在该实例的所有域中均有效)。\"]},\"186\":{\"h\":\"创建域\",\"t\":[\"登录账号后,在“我的”选项卡中找到“我的域”,并点击“创建域”,填入以下信息:\",\"ID: 每个域有一个唯一的 ID,将会在域 URL 中体现。创建后无法修改。\",\"名称: 域的名字,创建后可以更改。\",\"公告: 域主页上显示的公告,创建后可以更改。\",\"avatar: 域头像,与用户头像同理,可以使用 gravatar:email 或 qq:id 或 github:name 或 url:link 的格式添加。将会在“我的域”界面内显示。\",\"创建域后,您将在此域中拥有管理员权限,可以在域内进行添加题目/创建比赛等操作。\"]},\"187\":{\"h\":\"初始化讨论节点\",\"t\":[\"您可以在“管理域”选项卡中点击“初始化讨论节点”按钮初始化讨论节点。\"]},\"188\":{\"h\":\"访问控制\",\"t\":[\"未登录用户将默认使用 guest 权限,登录用户将默认使用 default 权限。(所以将登陆用户设为 default 权限后并不会显示在“管理用户”页内,这也表示所有用户默认不会出现在管理列表中) 所以将一个用户的权限设为 default 和将用户移出该域是等价的。\",\"对于不在列表中的用户,点击右上角“添加用户”,在左侧选中用户,右侧选择权限组,再点击“确定”即可。\"]},\"189\":{\"h\":\"创建比赛/作业\",\"t\":[\"若您想要创建比赛/作业,您可以在“比赛”或“作业”选项卡中,在页面右侧找到“创建”按钮, 题目一栏支持根据题目ID或是题目名自动筛选。设置完后可点击“创建”按钮创建比赛(描述这类的框不知道写啥就随便填,不能留空)。\",\"Tips\",\"若因为删除作业/比赛内题目导致无法打开,可以通过 /contest//edit 或 /homework//edit(即在无法打开的页面页面后加上 /edit)直接访问编辑页并修正。\"]},\"190\":{\"h\":\"创建训练\",\"t\":[\"若您想要创建训练,您可以在“训练” 项卡中点击“新建训练计划”,填写以下信息:\",\"标题:该训练的标题;\",\"简介:该训练的简介,会与标题同时显示在列表页面中;\",\"说明:该训练的详细信息;\",\"计划:该训练的具体题目及计划信息,其格式如下:\",\"[ {章节详细信息}, {章节详细信息}, ... {章节详细信息} ] \",\"其中,“章节详细信息”的包含以下部分:\",\"_id:章节数字编号;\",\"title:章节标题;\",\"requireNids:训练此章节之前需要完成的章节数字编号,若无要求则留空,若有多个则使用逗号分隔;\",\"pids:此章节中包含的题目的 ID,若有多个则使用逗号分隔。\",\"举例:若要在训练中创建三个章节,章节中分别有 ID 为 1,2,3 的题目。其中章节一、二无前置条件,章节三需要同时完成章节一、二后才能进行,则格式如下:\",\"[ { \\\"_id\\\": 1, \\\"title\\\": \\\"入门\\\", \\\"requireNids\\\": [], \\\"pids\\\": [1] }, { \\\"_id\\\": 2, \\\"title\\\": \\\"精通\\\", \\\"requireNids\\\": [], \\\"pids\\\": [2] }, { \\\"_id\\\": 3, \\\"title\\\": \\\"大师\\\", \\\"requireNids\\\": [1,2], \\\"pids\\\": [3] } ] \",\"Tips\",\"若因为删除训练计划内题目导致训练计划无法打开,可以通过 /training//edit(即训练计划页面后加上 /edit)直接访问训练计划编辑页并修正配置文件。\"]},\"191\":{\"h\":\"权限系统\",\"t\":[\"Hydro 的权限系统使用双层结构,分别为 Privilege (PRIV) 和 Permission (PERM)。 权限在系统内部使用位运算表示,具体的定义与数值可以查看 源代码 。\"]},\"192\":{\"h\":\"Privilege\",\"t\":[\"Privilege 是用户在整套系统内拥有的权限,在所有域均生效。如创建用户,编辑系统设置,创建域,查看域等等。\",\"特别地,PRIV.PRIV_USER_PROFILE 控制一个账号是否能够作为普通账号登录。若不具有此权限,该账号将无法登录(被封禁)。\",\"常见需求:若不想让普通用户上传文件 可以关闭default角色的 PRIV_CREATE_FILE 权限\"]},\"193\":{\"h\":\"Permission\",\"t\":[\"Permission 是用户在单个域内拥有的权限,如创建题目/比赛,发布/删除讨论等等。\",\"如果 PERM.PERM_VIEW 被禁用,则该用户无法查看此域。\"]},\"194\":{\"h\":\"角色\",\"t\":[\"通常我们需要给特定的一组用户分配相同的权限。在用户量较多的时候这会非常混乱难以管理,为此我们设计了【角色】,便于批量操作与管理。 角色是针对域内权限(PERM)的。在系统内置了三个角色:\",\"guest (对未登录用户生效,含已封禁用户)\",\"default (对所有未指定角色的用户生效,包括未加入域的用户)\",\"root (拥有所有权限)\",\"通常情况下,如果需要对域做特殊的权限控制,应当新建一个用户组(例如 member)并将选定用户加入该用户组。 将角色移出域和将用户的角色设置为 default 是等价的。 若有需要,您也可以创建 teacher, admin 等其他角色。 考虑到系统中的用户可能非常多(数万甚至数十万),在用户列表中仅会显示权限不为 default 的用户。\"]},\"195\":{\"h\":\"加入域\",\"t\":[\"加入域的过程实际上是 用户通过某种方式自助将自己的权限组由 default 变更到另一权限组(如member) 的过程。\\n因此在入域申请链接的权限组中选择 guest 和 default 是没有意义的。\"]},\"196\":{\"h\":\"Hydro常见题型的制做心得\",\"t\":[\"作者: laomai qq: 29985091 网址: http://82.157.98.222:8888/ 日期: 2022/03/16\",\"本文为作者使用hydro时的实验记录,希望对大家有帮助.包括如下内容\",\"零. hydro题目存储格式 一. 制做最简单的oj题 二. 含有自定义头文件的oj题,即函数交互式的题目 三. 半自动对拍的oj题,即不需要录入预期输出的题 四. 完全对拍题,即不需要录入输入数据和输出数据的题 五. 指定输入文件和输出文件 六. 多个子任务 七. 客观题,即制做有标准答案的填空和选择题.\"]},\"197\":{\"h\":\"零. hydro题目存储格式\",\"t\":[\"如果想在本地建立好题目,然后批量上传的话. 下面的格式应该对你有帮助 每个题目应自占一个目录,目录名为题目编号比如1 ,2,3,4等等. 每个题目目录下一般有下面的元素:problem_zh.md 这个文件是就是题目的内容,即题目的描述,是一个markdown格式的文档.probelm.yaml 文件.这个是题目的配置信息. 比如标题和标签等。 testdata 子目录,对应网站里的测试数据部分里的文件, 里面至少有一个config.yaml文件 用来说明测试的类型.具体内容见后面的例子 如果题目有测试用例,则每个用例至少要提供一个in文件和一个输出文件(但有些测试类型不用,详情见后) additional_file子目录用来存放给做题者用的额外文件,比如头文件,图片,pdf文档等,在题目的 markdown 文档中可以用下面的格式为这些文件提供下载链接:[提示文字](file://xxx.txt)\",\"下面为手工录入各种题型的步骤,即在网站登录后点创建题目之后的操作.如下图所示 \",\"我们假定题目内容均为下面的markdown文档\",\"# 要求 输入两个整数,输出他们的和 # 样例 ```input1 123 500 ``` ```output1 623 ``` \"]},\"198\":{\"h\":\"一 制做最简单的OJ题目\",\"t\":[\"题目网址: http://82.157.98.222:8888/p/P10000\",\"新建题目之后编辑题目内容,输入题号和标题,然后点创建按钮。如下图所示.\",\"此时出现下面的图,点创建文件,文件名为 1.in, 表示用例 1 的输入\",\"编辑 1.in 的内容为两个整数比如 2 和 3 ,空格分开,如下图所示,然后点确定\",\"类似办法创建一个 1.out 文件,内容为 5 ,注意数字编号必须和 in 文件一致,创建之后的文件列表和下面类似.\",\"这样第一个用例的输入和预期输出就录入完毕,现在可以做本题了\",\"本题的 AC 代码为:\",\"#include using namespace std; int main(int argc,char* argv[]){ int a,b; cin>>a>>b; cout <<(a+b); return 0; } \"]},\"199\":{\"h\":\"二、函数交互型题目\",\"t\":[\"题目网址: http://82.157.98.222:8888/p/P10001 本类型和类型一的区别在于出题者要向做题者提供一个额外的头文件,做题者的主函数里可以包含这个头文件以调用出题者提供的某些函数,或者实现头文件里指定的函数.\",\"题目内容的录入以及测试数据的录入和类型一样\",\"本题要额外上传两个文件.分别为 tools.h 和 config.yaml ,如下图所示\",\"tools.h 的内容为\",\"#include using namespace std; int add(int x,int y); //留待做题者实现 int main(int argc,char* argv[]){ int a,b; cin>>a>>b; cout << add(a,b); return 0; } \",\"这个头文件里实现了一个主函数,并且声明了需要做题者实现的函数add,当然,出题者应该在题目要求里写明这个函数的原型以及把tools.h文件上传到附加文件列表中,以方便做题者. 题面里可以用如下格式为用户提供下载链接,中括号内的内容可以自己写,[tools.h](file://tools.h) 如下面所示\",\"config.yaml文件的内容为\",\"type: default filename: null user_extra_files: - tools.h \",\"本题的ac代码为\",\"#include \\\"tools.h\\\" int add(int x,int y){ return x+y; } \",\"可见本类型的题目,做题者包含给定的头文件后,可以不需要自己实现主函数,只需要专心实现给定的函数即可.\"]},\"200\":{\"h\":\"三,半对拍-自己指定评测程序并修改测试输出格式\",\"t\":[\"例题网址:http://82.157.98.222:8888/p/P10002 本题型的特点是不需要手工给出每个用例的预期输出,但是要自己编写一个样本程序,测试时会把用户的输出和样本程序的输出进行对比。\",\"仍以两数求和为例\",\"题目内容和类型一类似\",\"测试数据部分只需要提供1.in\",\"编写一个样本程序 checker.cc,内容如下:\",\"#include \\\"testlib.h\\\" int main(int argc, char * argv[]) { registerTestlibCmd(argc, argv); int a = inf.readInt(); // 读取输入流的第一个整数 int b = inf.readInt(); // 读取输入流的下一个整数 int d = a+b; int c = ouf.readInt(); // 读取输出流的下一个整数 if (a+b != c) quitf(_wa, \\\"%d + %d expected %d, found %d\\\", a, b,d,c); //输出错误的具体信息,便于做题者调试 else quitf(_ok, \\\"answer of %d + %d is %d\\\",a,b,c); } \",\"config.yaml文件的内容如下:\",\"checker_type: testlib checker: checker.cc cases: - input: 1.in output: /dev/null # 无输出 \",\"最终的测试文件列表如下所示:\",\"当程序有错误时,输出的效果如下\",\"可见这里输出了错误细节,便于做题者调试\",\"本题的ac代码和类型一的一样,内容为\",\"#include using namespace std; int main(int argc,char* argv[]){ int a,b; cin>>a>>b; cout <<(a+b); return 0; } \",\"如果不希望自己录入输入数据,而是在每次测试时自动动态生成的话,可以将题目类型设为interactive,并提供一个对拍程序.仍以求和为例 例题网址: http://82.157.98.222:8888/p/P10005\",\"最后测试数据部分的文件列表如下图所示\",\"checker.cc,内容为:\",\"#include \\\"testlib.h\\\" #include using namespace std; int main(int argc, char* argv[]) { setName(\\\"Interactor A+B\\\"); registerInteraction(argc, argv); //自动生成两个随机整数 rnd.setSeed(time(NULL)); int a = rnd.next(1000); int b = rnd.next(1000); // 本程序的输出将作为用户程序的输入 cout << a << \\\" \\\" << b << endl; int c; // 用户程序的最后输出将作为本程序的输入 cin >> c; //对比用户结果和预期结果 if (a+b != c) quitf(_wa, \\\"%d + %d expected %d, found %d\\\", a, b, a+b, c); //输出错误的具体信息,便于做题者调试 else quitf(_ok, \\\"answer of %d + %d is %d\\\",a,b,c); } \",\"config.yaml 文件的内容为:\",\"type: interactive interactor: checker.cc cases: - input: /dev/null # no input and no output, dynamic generated output: /dev/null - input: /dev/null # no input and no output, dynamic generated output: /dev/null \",\"AC 代码和类型一中的相同\"]},\"201\":{\"h\":\"五.文件读写测试\",\"t\":[\"例题网址:http://82.157.98.222:8888/p/P10003 有时希望指定输入和输出文件,此时测试文件 1.in 和 1.out 和类型一类似, 但是要提供config.yaml文件,内容类似于下\",\"file: test \",\"则运行时测试环境会自动把每个输入文件复制到test.in中,输出内容和test.out的内容进行对比. ac的代码如下:\",\"#include using namespace std; int main(int argc,char* argv[]){ int a,b; ifstream ifs(\\\"test.in\\\"); ifs>>a>>b; ofstream ofs(\\\"test.out\\\"); ofs <<(a+b); return 0; } \"]},\"202\":{\"h\":\"六,子任务测试.\",\"t\":[\"例题网址: https://hydro.ac/d/system_test/p/7\",\"提供好题目和各个子任务的输入、输出文件 建议文件名格式为 data-<数字> id为子任务编号\",\"config.yaml文件的内容参考如下\",\"time: 100ms memory: 8m subtasks: - score: 20 id: 0 cases: - input: data1-1.in output: data1-1.ans - input: data1-2.in output: data1-2.ans - input: data1-3.in output: data1-3.ans - input: data1-4.in output: data1-4.ans - input: data1-5.in output: data1-5.ans - score: 20 id: 1 cases: - input: data2-1.in output: data2-1.ans - input: data2-2.in output: data2-2.ans - input: data2-3.in output: data2-3.ans - input: data2-4.in output: data2-4.ans - input: data2-5.in output: data2-5.ans - score: 20 id: 2 cases: - input: data3-1.in output: data3-1.ans - input: data3-2.in output: data3-2.ans - input: data3-3.in output: data3-3.ans - input: data3-4.in output: data3-4.ans - input: data3-5.in output: data3-5.ans - score: 20 id: 3 if: [2] cases: - input: data4-1.in output: data4-1.ans - input: data4-2.in output: data4-2.ans - input: data4-3.in output: data4-3.ans - input: data4-4.in output: data4-4.ans - input: data4-5.in output: data4-5.ans - score: 20 id: 4 if: [1, 3] cases: - input: data5-1.in output: data5-1.ans - input: data5-2.in output: data5-2.ans - input: data5-3.in output: data5-3.ans - input: data5-4.in output: data5-4.ans - input: data5-5.in output: data5-5.ans \",\"可以看出if 用来指定前置子任务. 此外,如果某个子任务没有提供cases部分时,测试时会自动寻找类似于 data-x.in 和data-x.out 的文件,id为子任务编号 上面的例子故意设计为子任务编号和用例文件中的编号不同,所有每个子任务都需要手工指定对应的cases.\"]},\"203\":{\"h\":\"七,客观题制做\",\"t\":[\"注意新版的客观题,格式已经更新。\",\"例题网址:http://82.157.98.222:8888/p/P10004 客观题只需要题面和config.yaml文件. 例子如下:\",\"1. 填空题 1+1 = {{ input(1) }} 2. 选择题 {{ select(2) }} - 1+1=2 - 1+1=3 - 1+1=4 3. 多选题 {{ multiselect(3) }} - A - B - C \",\"上传的 config.yaml 内容为\",\"type: objective # 表明该题为客观题 answers: # 列举出每一题的正确选项与对应的得分 '1': ['2', 50] '2': [['A', 'B'], 30] # 填空题支持多答案,满足其一得分 '3': [['A', 'B'], 20] # 多选题答案为数组,有部分分 \",\"题目运行效果如下:\",\"做完之后点提交,效果如下\",\"可见评分结果正确.\"]},\"204\":{\"h\":\"八.小结\",\"t\":[\"对所有编程题目,题面是必须录入的,如果指定了测试程序时,可以不需要录入输出数据. 如果设置测试方式为interactive,输入数据也不需要手工录入. 想指特殊的测试方式时,一般需要上传一个config.yaml文件,并设置对应字段的值. 对编程题,本文档中用到的字段有\",\"type字段一般为default, 对全自动对拍题,设为interactive\",\"checker_type: testlib checker: checker.cc 用来指定自定义的测试程序,即对拍程序\",\"filename: test用来指定对test.in文件和test.out文件进行读写.\",\"cases:\",\"input: 1.in\",\"用来指定测试用例.\",\"更详细的介绍见\\nhttps://hydro.js.org/docs/user/testdata/\"]},\"205\":{\"h\":\"Hydro Problem Format\",\"t\":[\"为了便于系统间进行数据交换,Hydro 定义了一种基于 zip 的标准格式用于题目传输。压缩包内文件结构如下:\",\"喵? tree . ├── 任意文件名的文件夹 │ ├── problem.yaml │ ├── problem_zh.md │ ├── testdata │ │ ├── config.yaml │ │ ├── a1.in │ │ ├── a1.out │ │ ├── a2.in │ │ ├── a2.out │ │ ├── a3.in │ │ └── a3.out │ └── additional_file │ ├── a.png │ └── b.pdf └── ... \",\"其中 problem.yaml 内容如下:\",\"title: 题目名 tag: - 标签1 - 标签2 pid: 题号(字母+数字) \",\"problem_*.md 中为 markdown 格式的题面,语言代号支持完整形式(如 zh_CN),也支持短形式(如 zh)。若同时存在多个语言的题面,Hydro 将会自动识别并提供切换功能。\",\"testdata 文件夹中存放所有测试数据文件,命名规则和配置文件格式请参照【测试数据格式】章节。\",\"additional_file 中存储附加文件,通常用于存放图片,PDF 等文件。这些文件可以在题面中使用 file://文件名 的路径访问。\"]},\"206\":{\"h\":\"题目\"},\"207\":{\"h\":\"创建题目\",\"t\":[\"拥有 PERM_CREATE_PROBLEM 的用户均可以新建题目。 请点击题库页面右下角的 创建题目 按钮。\",\"Tips\",\"题目 ID 不能全为数字。若留空则使用自动分配的数字题号。\",\"详见下方题面编辑部分,以及 laomai 编写的说明\"]},\"208\":{\"h\":\"导入题目\"},\"209\":{\"h\":\"从 Hydro 导入\",\"t\":[\"上传 Hydro 导出的题目压缩包即可。\",\"如果您的压缩包较大无法上传我们也提供cli导入方法:\",\"hydrooj cli problem import # 将 的Hydro格式题目包导入至 域中。 \"]},\"210\":{\"h\":\"从 SYZOJ 导入\",\"t\":[\"Hydro 提供了一个小工具 loj-download,可从基于原版 SYZOJ/SYZOJ-NG 搭建的源站下载到符合Hydro格式的题目压缩包。 工具使用方法请前往使用教程查看,自行摸索并确保在网络通畅的环境下使用。\"]},\"211\":{\"h\":\"从 FPS 文件导入\",\"t\":[\"见插件 fps-importer。\"]},\"212\":{\"h\":\"从 QDUOJ 导入\",\"t\":[\"见插件 import-qduoj。\"]},\"213\":{\"h\":\"编辑\"},\"214\":{\"h\":\"题面\",\"t\":[\"题面使用 Markdown 语法,并进行了部分扩展。\",\"支持对样例数据分组显示:\",\"```input1 1 2 ``` ```output1 3 ```\",\"后接的数字为测试点编号,将自动合并,并左右分栏显示。\",\"支持从附加文件引用资源。(您可以先创建题目,上传相关文件后再编辑该题目)\",\"附加文件下载链接: [file](file://input.in)\",\"从附加文件引用一张图片: ![img](file://foo.jpg)\",\"从附加文件引用 pdf 作为题面:@[pdf](file://foo.pdf) (部分情况下若无法使用,请尝试 @[pdf](file://foo.pdf?noDisposition=1) )\",\"从附加文件引用 word 文档作为题面: @[doc](file://foo.docx) (依赖 onlyoffice 插件)\",\"Tips\",\"如果您在使用外部的存储服务,部分服务商可能会强制发送 Content-Disposition 导致文件直接被下载而非预览。详询对应服务商。\",\"https://cloud.tencent.com/document/product/436/96243\",\"https://help.aliyun.com/zh/oss/user-guide/how-to-ensure-an-object-is-previewed-when-you-access-the-object\",\"题面支持合并表格:\",\"| 1 | 1 | 3 | 4 | 5 | | --- | --- | --- | --- | --- | | 1 | 1 | 2 | 2 | 6 | | 1 | 1 | 2 | 2 | 7 | | 1 | 4 | 3 | 5 | 5 | \",\"将被渲染为:\",\"支持内嵌 HTML:(用来对付部分 Markdown 搞不定的东西)\",\"foo \"]},\"215\":{\"h\":\"标签\",\"t\":[\"可点击右侧分类面板快速添加标签,也可以用英文半角逗号分隔多个标签。\"]},\"216\":{\"h\":\"文件\",\"t\":[\"您可以在题目右侧“文件”面板上传测试数据和附加文件。(支持拖拽文件至相应位置进行上传)测试数据格式。\"]},\"217\":{\"h\":\"客观题\"},\"218\":{\"h\":\"题面\",\"t\":[\"1. 填空题 1+1 = {{ input(1) }} 2. 选择题 {{ select(2) }} - 1+1=2 - 1+1=3 - 1+1=4 3. 多选题 {{ multiselect(3) }} - A - B - C \"]},\"219\":{\"h\":\"测试数据\",\"t\":[\"仅需要配置 config.yaml 即可,不需要上传其他文件。\",\"type: objective # 表明该题为客观题 answers: # 列举出每一题的正确选项与对应的得分 '1': ['2', 50] # 填空题/选择题,单答案 '2': # 填空题/选择题,多答案,不同答案对应不同分数,注意空格缩进 'A': 30 # 也可以使用相同分数,即同时存在多个正确答案 'B': 10 '3': [['A', 'B'], 20] # 多选题答案为数组,有部分分 \"]},\"220\":{\"h\":\"测试数据格式\"},\"221\":{\"h\":\"自动模式\",\"t\":[\"Tips\",\"您可以直接选择文件(支持多选)上传或将文件拖拽至相应位置上传。 若上传文件为 zip 格式,将会自动进行解压操作。\",\"对于一般的题目,您只需提供 .in 和 .out/.ans 文件,以下是一个例子。 请务必确保文件名中含有数字。形如 sample.in 的文件是不会被自动识别的。\",\"喵? tree . ├── a1.in ├── a1.out ├── a2.in ├── a2.out ├── a3.in └── a3.out \",\"测试数据将被自动识别,并使用 1S 256MB 的限制。\"]},\"222\":{\"h\":\"使用配置文件\",\"t\":[\"Tips\",\"推荐您通过 评测设置 在线编辑题目配置,可以拥有更好的编辑体验。\",\"上传 config.yaml 文件即可,文件格式如下(下方所有样例均为可选项,若无说明则预填写的内容即为默认值):\",\"# 题目类型,可以为 default(比对输出,可以含spj), objective(客观题), interactive(交互题) type: default # 全局时空限制(此处的限制优先级低于测试点的限制) time: 1s memory: 128m # 输入输出文件名(例:使用 foo.in 和 foo.out),若使用标准 IO 删除此配置项即可 filename: foo # 此部分设置当题目类型为 default 时生效 # 比较器类型,支持的值有 default(直接比对,忽略行末空格和文件末换行), ccr, cena, hustoj, lemon, qduoj, syzoj, testlib(比较常用) checker_type: default # 比较器文件(当比较器类型不为 default 时填写) # 文件路径(位于压缩包中的路径) # 将通过扩展名识别语言,与编译命令处一致。在默认配置下,C++ 扩展名应为 .cc 而非 .cpp checker: chk.cc # 此部分设置当题目类型为interactive时生效 # 交互器路径(位于压缩包中的路径) interactor: interactor.cc # Extra files 额外文件 # These files will be copied to the working directory 这些文件将被复制到工作目录。 # 提示:您无需手动上传 testlib.h。 user_extra_files: - extra_input.txt judge_extra_files: - extra_file.txt # Test Cases 测试数据列表 # If neither CASES or SUBTASKS are set(or config.yaml doesn't exist), judge will try to locate them automaticly. # 如果 CASES 和 SUBTASKS 都没有设置或 config.yaml 不存在, 系统会自动尝试识别数据点。 # We support these names for auto mode: 自动识别支持以下命名方式: # 1. [name(optional)][number].(in/out/ans) RegExp: /^([a-zA-Z]*)([0-9]+).in$/ # examples: # - c1.in / c1.out # - 1.in / 1.out # - c1.in / c1.ans # 2. input[number].txt / output[number].txt RegExp: /^(input)([0-9]+).txt$/ # - example: input1.txt / input2.txt # # The CASES option has higher priority than the SUBTASKS option! # 在有 CASES 设置项时,不会读取 SUBTASKS 设置项! # # The CASES option has been deprecated in the new version, please use the more personalized SUBTASKS! # CASES 已于新版本中被废弃,请使用个性化程度更高的SUBTASKS! # score: 50 # 单个测试点分数 # time: 1s # 时间限制 # memory: 256m # 内存限制 # cases: # - input: abc.in # output: def.out # - input: ghi.in # output: jkl.out # 或使用Subtask项: subtasks: - score: 30 type: min # 可选 min/max/sum,分别表示取所有测试点最小值、所有测试点最大值、所有测试点之和 time: 1s memory: 64m cases: - time: 0.5s memory: 32m # 可对单个测试点单独设置时间限制和内存限制 input: a.in output: a.out - input: b.in output: b.out - score: 70 time: 0.5s memory: 32m if: [0] # 可选,传入数组,表示仅在subtask0通过时此subtask才计分 cases: - input: c.in output: c.out - input: d.in output: d.out # 提交语言限制 # 列举出所有本题允许使用的语言对应的代码(需要和评测机 lang.yaml 内的语言代码相同) # 使用语言ID而非名称!对于有子类的选项,请详细至子分类! langs: - c - cc - cc.cc11o2 - pas # 时间内存倍率 # 对某语言设置时间或内存倍率(需要和评测机 lang.yaml 内的语言代码相同) # 部分语言默认已存在倍率,请前往控制面板中查看! # 使用语言ID而非名称!对于有子类的选项,请详细至子分类! time_limit_rate: py.py3: 2 memory_limit_rate: java: 1.5 \",\"可以在 此题库 中找到各种类型题目的配置示例。\"]},\"223\":{\"h\":\"System\"}},\"dirtCount\":0,\"index\":[[\"列举出所有本题允许使用的语言对应的代码\",{\"1\":{\"222\":1}}],[\"列举出每一题的正确选项与对应的得分\",{\"1\":{\"203\":1,\"219\":1}}],[\"传入数组\",{\"1\":{\"222\":1}}],[\"^\",{\"1\":{\"222\":2}}],[\"都没有设置或\",{\"1\":{\"222\":1}}],[\"都可以无损升级到最新版本\",{\"1\":{\"16\":1}}],[\"额外文件\",{\"1\":{\"222\":1}}],[\"交互器路径\",{\"1\":{\"222\":1}}],[\"交互题\",{\"1\":{\"80\":1,\"81\":1,\"222\":1}}],[\"位于压缩包中的路径\",{\"1\":{\"222\":2}}],[\"位置\",{\"1\":{\"77\":1}}],[\"忽略行末空格和文件末换行\",{\"1\":{\"222\":1}}],[\"形如\",{\"1\":{\"221\":1}}],[\"面板上传测试数据和附加文件\",{\"1\":{\"216\":1}}],[\"搞不定的东西\",{\"1\":{\"214\":1}}],[\"依赖\",{\"1\":{\"214\":1}}],[\"见插件\",{\"1\":{\"211\":1,\"212\":1}}],[\"工具使用方法请前往使用教程查看\",{\"1\":{\"210\":1}}],[\"搭建的源站下载到符合hydro格式的题目压缩包\",{\"1\":{\"210\":1}}],[\"搭建过程中如果遇到问题欢迎\",{\"1\":{\"133\":1}}],[\"解压后的文件夹\",{\"1\":{\"209\":1}}],[\"解锁\",{\"1\":{\"172\":1}}],[\"压缩文件\",{\"1\":{\"209\":1}}],[\"压缩包内文件结构如下\",{\"1\":{\"205\":1}}],[\"标签\",{\"0\":{\"215\":1}}],[\"标签2\",{\"1\":{\"205\":1}}],[\"标签1\",{\"1\":{\"205\":1}}],[\"标题\",{\"1\":{\"179\":1,\"190\":1}}],[\"└──\",{\"1\":{\"205\":4,\"221\":1}}],[\"│\",{\"1\":{\"205\":20}}],[\"任意文件名的文件夹\",{\"1\":{\"205\":1}}],[\"任何操作前请做好离线备份\",{\"1\":{\"21\":1}}],[\"任何人均能够在遵守协议的情况下使用这套框架\",{\"1\":{\"1\":1}}],[\"├──\",{\"1\":{\"205\":11,\"221\":5}}],[\"喵\",{\"1\":{\"205\":1,\"221\":1}}],[\"想指特殊的测试方式时\",{\"1\":{\"204\":1}}],[\"八\",{\"0\":{\"204\":1}}],[\"效果如下\",{\"1\":{\"203\":1}}],[\"满足其一得分\",{\"1\":{\"203\":1}}],[\"仍以求和为例\",{\"1\":{\"200\":1}}],[\"仍以两数求和为例\",{\"1\":{\"200\":1}}],[\"便于做题者调试\",{\"1\":{\"200\":3}}],[\"便于批量操作与管理\",{\"1\":{\"194\":1}}],[\"读取输出流的下一个整数\",{\"1\":{\"200\":1}}],[\"读取输入流的下一个整数\",{\"1\":{\"200\":1}}],[\"读取输入流的第一个整数\",{\"1\":{\"200\":1}}],[\"半对拍\",{\"0\":{\"200\":1}}],[\"半自动对拍的oj题\",{\"1\":{\"196\":1}}],[\"出题者应该在题目要求里写明这个函数的原型以及把tools\",{\"1\":{\"199\":1}}],[\"出现csrftokenerror\",{\"0\":{\"13\":1}}],[\"留待做题者实现\",{\"1\":{\"199\":1}}],[\"空格分开\",{\"1\":{\"198\":1}}],[\"空闲内存要求\",{\"1\":{\"47\":1}}],[\"点创建文件\",{\"1\":{\"198\":1}}],[\"点击右上角\",{\"1\":{\"188\":1}}],[\"点击右侧栏底部的\",{\"1\":{\"182\":1}}],[\"点击运行\",{\"1\":{\"90\":1,\"128\":1}}],[\"点击\",{\"1\":{\"10\":1,\"83\":1,\"180\":1,\"182\":1}}],[\"输出文件\",{\"1\":{\"202\":1}}],[\"输出内容和test\",{\"1\":{\"201\":1}}],[\"输出的效果如下\",{\"1\":{\"200\":1}}],[\"输出错误的具体信息\",{\"1\":{\"200\":2}}],[\"输出他们的和\",{\"1\":{\"197\":1}}],[\"输入输出文件名\",{\"1\":{\"222\":1}}],[\"输入数据也不需要手工录入\",{\"1\":{\"204\":1}}],[\"输入题号和标题\",{\"1\":{\"198\":1}}],[\"输入两个整数\",{\"1\":{\"197\":1}}],[\"要求\",{\"1\":{\"197\":1}}],[\"要花多少钱\",{\"0\":{\"31\":1}}],[\"文档作为题面\",{\"1\":{\"214\":1}}],[\"文档中可以用下面的格式为这些文件提供下载链接\",{\"1\":{\"197\":1}}],[\"文件路径\",{\"1\":{\"222\":1}}],[\"文件格式如下\",{\"1\":{\"222\":1}}],[\"文件格式参照\",{\"1\":{\"107\":1}}],[\"文件即可\",{\"1\":{\"222\":1}}],[\"文件名\",{\"1\":{\"205\":1}}],[\"文件名为\",{\"1\":{\"198\":1}}],[\"文件读写测试\",{\"0\":{\"201\":1}}],[\"文件的内容为\",{\"1\":{\"200\":1}}],[\"文件一致\",{\"1\":{\"198\":1}}],[\"文件后缀\",{\"1\":{\"146\":1}}],[\"文件后使用\",{\"1\":{\"80\":1}}],[\"文件默认存储于本地的\",{\"1\":{\"140\":1}}],[\"文件之后\",{\"1\":{\"137\":1}}],[\"文件需要为\",{\"1\":{\"92\":1}}],[\"文件消耗大量内存\",{\"1\":{\"92\":1}}],[\"文件\",{\"0\":{\"216\":1},\"1\":{\"92\":3,\"137\":1,\"173\":1,\"197\":1,\"198\":1,\"216\":1,\"221\":1}}],[\"文件导入\",{\"0\":{\"211\":1},\"1\":{\"92\":1}}],[\"文件导入题目\",{\"0\":{\"92\":1}}],[\"文件io\",{\"1\":{\"80\":1}}],[\"文件夹中存放所有测试数据文件\",{\"1\":{\"205\":1}}],[\"文件夹备份即可\",{\"1\":{\"158\":1}}],[\"文件夹的位置\",{\"1\":{\"115\":1,\"116\":1}}],[\"文件夹路径即为\",{\"1\":{\"86\":1}}],[\"文件夹格式相同\",{\"1\":{\"79\":1}}],[\"文件夹下后进行修改即可\",{\"1\":{\"162\":1}}],[\"文件夹下\",{\"1\":{\"78\":1}}],[\"文件夹\",{\"1\":{\"49\":1,\"137\":2}}],[\"文件夹再重试\",{\"1\":{\"15\":1}}],[\"图片\",{\"1\":{\"197\":1}}],[\"里面至少有一个config\",{\"1\":{\"197\":1}}],[\"子任务测试\",{\"0\":{\"202\":1}}],[\"子目录\",{\"1\":{\"197\":1}}],[\"子文件夹下\",{\"1\":{\"50\":1}}],[\"比较器文件\",{\"1\":{\"222\":1}}],[\"比较器类型\",{\"1\":{\"222\":1}}],[\"比较常用\",{\"1\":{\"222\":1}}],[\"比对输出\",{\"1\":{\"222\":1}}],[\"比如头文件\",{\"1\":{\"197\":1}}],[\"比如标题和标签等\",{\"1\":{\"197\":1}}],[\"比赛内题目导致无法打开\",{\"1\":{\"189\":1}}],[\"比赛过程中\",{\"1\":{\"178\":1}}],[\"比赛的成绩等等\",{\"1\":{\"55\":1}}],[\"比赛\",{\"1\":{\"54\":1,\"70\":2,\"81\":1,\"189\":1,\"193\":1}}],[\"比赛等数据\",{\"1\":{\"28\":1}}],[\"比赛开始的时刻\",{\"1\":{\"20\":1}}],[\"比赛作业里面的时间是什么含义\",{\"0\":{\"20\":1}}],[\"比赛作业结束后让题目成为训练题库的一部分\",{\"1\":{\"17\":1}}],[\"客观题只需要题面和config\",{\"1\":{\"203\":1}}],[\"客观题制做\",{\"0\":{\"203\":1}}],[\"客观题\",{\"0\":{\"217\":1},\"1\":{\"196\":1,\"222\":1}}],[\"七\",{\"0\":{\"203\":1},\"1\":{\"196\":1}}],[\"多答案\",{\"1\":{\"219\":1}}],[\"多选题答案为数组\",{\"1\":{\"203\":1,\"219\":1}}],[\"多选题\",{\"1\":{\"203\":1,\"218\":1}}],[\"多个子任务\",{\"1\":{\"196\":1}}],[\"多评测机\",{\"1\":{\"81\":1}}],[\"六\",{\"0\":{\"202\":1},\"1\":{\"196\":1}}],[\"五\",{\"0\":{\"201\":1},\"1\":{\"196\":1}}],[\"完全对拍题\",{\"1\":{\"196\":1}}],[\"完成后将配置的用户名及密码写入评测机配置文件\",{\"1\":{\"152\":1}}],[\"完成登录逻辑后应该跳转到哪一页\",{\"1\":{\"73\":1}}],[\"四\",{\"1\":{\"196\":1}}],[\"三\",{\"0\":{\"200\":1},\"1\":{\"196\":1}}],[\"三个字段外\",{\"1\":{\"45\":1}}],[\"制做最简单的oj题目\",{\"0\":{\"198\":1}}],[\"制做最简单的oj题\",{\"1\":{\"196\":1}}],[\"零\",{\"0\":{\"197\":1},\"1\":{\"196\":1}}],[\"希望对大家有帮助\",{\"1\":{\"196\":1}}],[\"日期\",{\"1\":{\"196\":1}}],[\"日前安装\",{\"1\":{\"23\":1}}],[\"网址\",{\"1\":{\"196\":1}}],[\"网易\",{\"1\":{\"142\":1}}],[\"考虑到系统中的用户可能非常多\",{\"1\":{\"194\":1}}],[\"拥有\",{\"1\":{\"207\":1}}],[\"拥有所有权限\",{\"1\":{\"194\":1}}],[\"拥有极高的评测效率\",{\"1\":{\"80\":1}}],[\"角色是针对域内权限\",{\"1\":{\"194\":1}}],[\"角色\",{\"0\":{\"194\":1},\"1\":{\"194\":1}}],[\"被禁用\",{\"1\":{\"193\":1}}],[\"被封禁\",{\"1\":{\"192\":1}}],[\"控制一个账号是否能够作为普通账号登录\",{\"1\":{\"192\":1}}],[\"控制面板>导入用户\",{\"1\":{\"148\":1}}],[\"控制面板>manage\",{\"1\":{\"141\":1}}],[\"控制面板>脚本管理\",{\"1\":{\"115\":1,\"118\":1}}],[\"控制面板>系统设置>存储桶设置\",{\"1\":{\"141\":1}}],[\"控制面板>系统设置\",{\"1\":{\"85\":1,\"107\":2}}],[\"控制面板\",{\"1\":{\"90\":1,\"126\":1,\"128\":1}}],[\"源代码\",{\"1\":{\"191\":1}}],[\"精通\",{\"1\":{\"190\":1}}],[\"入门\",{\"1\":{\"190\":1}}],[\"二\",{\"0\":{\"199\":1},\"1\":{\"196\":1}}],[\"二后才能进行\",{\"1\":{\"190\":1}}],[\"二无前置条件\",{\"1\":{\"190\":1}}],[\"举例\",{\"1\":{\"190\":1}}],[\"计划\",{\"1\":{\"190\":1}}],[\"说明\",{\"1\":{\"190\":1}}],[\"说明安装独立模块\",{\"1\":{\"173\":1}}],[\"右侧选择权限组\",{\"1\":{\"188\":1}}],[\"右侧系统设置\",{\"1\":{\"135\":1}}],[\"页内\",{\"1\":{\"188\":1}}],[\"初始化讨论节点\",{\"0\":{\"187\":1},\"1\":{\"187\":1}}],[\"初始化项目\",{\"0\":{\"75\":1}}],[\"界面内显示\",{\"1\":{\"186\":1}}],[\"公告\",{\"1\":{\"186\":1}}],[\"名称\",{\"1\":{\"186\":1}}],[\"简介\",{\"0\":{\"185\":1},\"1\":{\"190\":1}}],[\"简单\",{\"1\":{\"47\":2}}],[\"认领作业\",{\"0\":{\"180\":1},\"1\":{\"180\":1}}],[\"置顶讨论\",{\"1\":{\"179\":1}}],[\"成绩表\",{\"1\":{\"178\":2,\"180\":2}}],[\"成功率高\",{\"1\":{\"134\":1}}],[\"越早递交评测的用户代码的评测结果对题目难度影响越大\",{\"1\":{\"177\":1}}],[\"难度才会变得较为准确\",{\"1\":{\"177\":1}}],[\"难度的数值越大\",{\"1\":{\"177\":1}}],[\"滚榜设置\",{\"1\":{\"175\":1}}],[\"测试时会自动寻找类似于\",{\"1\":{\"202\":1}}],[\"测试时会把用户的输出和样本程序的输出进行对比\",{\"1\":{\"200\":1}}],[\"测试服务器负载情况\",{\"1\":{\"174\":1}}],[\"测试数据列表\",{\"1\":{\"222\":1}}],[\"测试数据将被自动识别\",{\"1\":{\"221\":1}}],[\"测试数据\",{\"0\":{\"219\":1}}],[\"测试数据部分只需要提供1\",{\"1\":{\"200\":1}}],[\"测试数据格式\",{\"0\":{\"108\":1,\"220\":1},\"1\":{\"108\":1,\"205\":1,\"216\":1}}],[\"测试数据同步\",{\"1\":{\"81\":1}}],[\"测试数据存储\",{\"1\":{\"81\":1}}],[\"测试数据下载\",{\"0\":{\"44\":1}}],[\"测试数据的\",{\"1\":{\"43\":1}}],[\"测试数据等文件存储于\",{\"1\":{\"21\":1}}],[\"引导选手大量提交\",{\"1\":{\"174\":1}}],[\"热身赛通常使用至少一道可以反复提交爆破的题目\",{\"1\":{\"174\":1}}],[\"热身赛\",{\"0\":{\"174\":1}}],[\"热重载\",{\"1\":{\"47\":1}}],[\"操作流程\",{\"0\":{\"182\":1}}],[\"操作前请确认列表中不含管理员账号和管理员所使用的机器\",{\"1\":{\"173\":1}}],[\"操作触发了频率限制\",{\"0\":{\"37\":1}}],[\"志愿者拿到小票后根据其上内容分发气球\",{\"1\":{\"173\":1}}],[\"气球颜色\",{\"1\":{\"173\":1}}],[\"气球通常由小票机进行打印\",{\"1\":{\"173\":1}}],[\"座位号\",{\"1\":{\"173\":1}}],[\"打印功能在\",{\"1\":{\"173\":1}}],[\"打开\",{\"1\":{\"137\":1}}],[\"打开插件文件夹\",{\"1\":{\"76\":1}}],[\"打开用户注册\",{\"0\":{\"25\":1}}],[\"打开已配置完成的测试环境\",{\"1\":{\"0\":1}}],[\"批量修改选手机为强密码\",{\"1\":{\"173\":1}}],[\"队伍名称和座位号会在纸张顶部\",{\"1\":{\"173\":1}}],[\"队伍\",{\"1\":{\"173\":1}}],[\"填空题支持多答案\",{\"1\":{\"203\":1}}],[\"填空题\",{\"1\":{\"203\":1,\"218\":1,\"219\":2}}],[\"填写以下信息\",{\"1\":{\"190\":1}}],[\"填入以下信息\",{\"1\":{\"186\":1}}],[\"填入\",{\"1\":{\"173\":1}}],[\"填入座位号\",{\"1\":{\"173\":1}}],[\"填错会导致邮件无法发送\",{\"1\":{\"142\":1}}],[\"截取屏幕和摄像头流供\",{\"1\":{\"172\":1}}],[\"截图\",{\"0\":{\"82\":1}}],[\"镜像修改而来\",{\"1\":{\"172\":1}}],[\"镜像\",{\"1\":{\"172\":1}}],[\"拦截其他流量\",{\"1\":{\"172\":1}}],[\"现场赛指南\",{\"0\":{\"171\":1}}],[\"现在可以做本题了\",{\"1\":{\"198\":1}}],[\"现在开始\",{\"0\":{\"83\":1}}],[\"现在你所使用的评测系统也仅仅是一个程序\",{\"1\":{\"10\":1}}],[\"清除缓存\",{\"0\":{\"170\":1}}],[\"清空所有进程之后重新运行安装脚本\",{\"1\":{\"167\":1}}],[\"原有数据不会丢失\",{\"1\":{\"167\":1}}],[\"容器或是精简版系统\",{\"1\":{\"167\":1}}],[\"容器技术\",{\"1\":{\"80\":1}}],[\"尖括号同样需要替换\",{\"1\":{\"166\":1}}],[\"维护\",{\"0\":{\"164\":1}}],[\"学号为\",{\"1\":{\"163\":1}}],[\"学校为\",{\"1\":{\"163\":1}}],[\"学生阅读题目\",{\"1\":{\"10\":1}}],[\"逗号分隔\",{\"1\":{\"163\":1}}],[\"目前支持\",{\"1\":{\"163\":1}}],[\"目录名为题目编号比如1\",{\"1\":{\"197\":1}}],[\"目录文件\",{\"1\":{\"159\":1}}],[\"目录下\",{\"1\":{\"140\":1}}],[\"目录\",{\"1\":{\"27\":2}}],[\"特别地\",{\"1\":{\"192\":1}}],[\"特别的\",{\"1\":{\"162\":1}}],[\"特点\",{\"1\":{\"0\":1}}],[\"值即为页面名\",{\"1\":{\"162\":1}}],[\"值为\",{\"1\":{\"77\":1,\"146\":1,\"154\":1}}],[\"确定\",{\"1\":{\"182\":1,\"188\":1}}],[\"确保备份成功\",{\"1\":{\"158\":1}}],[\"确认您安装了支持彩色输出的编译器\",{\"1\":{\"110\":1}}],[\"恢复之前备份的数据\",{\"1\":{\"157\":1}}],[\"恢复备份时出现\",{\"0\":{\"15\":1}}],[\"快捷备份数据\",{\"1\":{\"157\":1}}],[\"快速备份与恢复\",{\"0\":{\"157\":1}}],[\"快速在\",{\"1\":{\"75\":1}}],[\"快速安装\",{\"1\":{\"48\":1}}],[\"快速起步\",{\"1\":{\"47\":1}}],[\"根本不会想到是你这次改数据库导致的\",{\"1\":{\"156\":1}}],[\"根据递交数\",{\"1\":{\"177\":1}}],[\"根据开启的方法关闭即可\",{\"1\":{\"102\":1}}],[\"根据用户id进行鉴权\",{\"1\":{\"77\":1}}],[\"根据具体情况替换尖括号中的部分\",{\"1\":{\"33\":1}}],[\"过段时间发现了一些异常\",{\"1\":{\"156\":1}}],[\"改完觉得好像没什么问题\",{\"1\":{\"156\":1}}],[\"改为\",{\"1\":{\"27\":1}}],[\"非常不推荐直接操作数据库\",{\"1\":{\"156\":1}}],[\"非常不建议自建开发环境\",{\"1\":{\"47\":1}}],[\"调用\",{\"1\":{\"154\":1}}],[\"调整沙箱空间大小\",{\"0\":{\"109\":1}}],[\"命令打开数据库\",{\"1\":{\"156\":1}}],[\"命令列表\",{\"0\":{\"154\":1}}],[\"命名空间和\",{\"1\":{\"80\":1}}],[\"命名规则和配置文件格式请参照\",{\"1\":{\"205\":1}}],[\"命名规则\",{\"0\":{\"69\":1}}],[\"移出黑名单\",{\"1\":{\"153\":1}}],[\"拉入黑名单\",{\"1\":{\"153\":1}}],[\"禁止\",{\"1\":{\"153\":1}}],[\"禁用内存地址空间随机化\",{\"1\":{\"112\":1}}],[\"禁用\",{\"1\":{\"112\":1}}],[\"禁用功能\",{\"1\":{\"9\":1}}],[\"封禁\",{\"1\":{\"153\":1}}],[\"封榜\",{\"1\":{\"81\":1}}],[\"黑名单相关\",{\"0\":{\"153\":1}}],[\"很少使用\",{\"1\":{\"148\":1}}],[\"很多程序高手都跟你一样\",{\"1\":{\"10\":1}}],[\"括号也应替换\",{\"1\":{\"147\":1}}],[\"括起来的参数可以给出\",{\"1\":{\"147\":1}}],[\"括起来的参数必须给出\",{\"1\":{\"147\":1}}],[\"该账号将无法登录\",{\"1\":{\"192\":1}}],[\"该训练的具体题目及计划信息\",{\"1\":{\"190\":1}}],[\"该训练的详细信息\",{\"1\":{\"190\":1}}],[\"该训练的简介\",{\"1\":{\"190\":1}}],[\"该训练的标题\",{\"1\":{\"190\":1}}],[\"该讨论是否置顶\",{\"1\":{\"179\":1}}],[\"该贴的左边将有醒目的红色线条\",{\"1\":{\"179\":1}}],[\"该题目越难\",{\"1\":{\"177\":1}}],[\"该队伍当前的所有气球颜色等信息\",{\"1\":{\"173\":1}}],[\"该用户将会被分配至当前域的\",{\"1\":{\"163\":1}}],[\"该用户的邮箱\",{\"1\":{\"148\":1}}],[\"该设置是为了能够让系统正确获取到用户的ip地址\",{\"1\":{\"146\":1}}],[\"该方法可以帮助您在任意服务器上部署评测机\",{\"1\":{\"98\":1}}],[\"头部取值\",{\"1\":{\"146\":1}}],[\"头部参数\",{\"1\":{\"146\":1}}],[\"遵循源站\",{\"1\":{\"146\":1}}],[\"缓存仍然存在\",{\"1\":{\"156\":1}}],[\"缓存一天\",{\"1\":{\"146\":1}}],[\"缓存行为\",{\"1\":{\"146\":1}}],[\"缓存设置可以参考以下设置\",{\"1\":{\"146\":1}}],[\"全局时空限制\",{\"1\":{\"222\":1}}],[\"全部文件\",{\"1\":{\"146\":2}}],[\"全站\",{\"0\":{\"146\":1},\"1\":{\"146\":1}}],[\"全量同步\",{\"1\":{\"81\":3}}],[\"资源\",{\"0\":{\"145\":1}}],[\"新建题目之后编辑题目内容\",{\"1\":{\"198\":1}}],[\"新建训练计划\",{\"1\":{\"190\":1}}],[\"新题目的难度可能不准确\",{\"1\":{\"177\":1}}],[\"新浪邮箱\",{\"1\":{\"142\":1}}],[\"新版本\",{\"1\":{\"141\":1}}],[\"飞书域名邮箱\",{\"1\":{\"142\":1}}],[\"腾讯企业邮\",{\"1\":{\"142\":1}}],[\"腾讯云cos\",{\"1\":{\"141\":1}}],[\"腾讯云\",{\"1\":{\"12\":1,\"135\":1}}],[\"邮箱域名封禁\",{\"1\":{\"153\":1}}],[\"邮箱和用户名均不重复\",{\"1\":{\"148\":1}}],[\"邮箱\",{\"1\":{\"142\":2,\"163\":4}}],[\"邮箱为例\",{\"1\":{\"142\":1}}],[\"连接\",{\"1\":{\"142\":1}}],[\"连接建立后\",{\"1\":{\"41\":1}}],[\"连接建立流程\",{\"0\":{\"41\":1}}],[\"代替读取\",{\"1\":{\"141\":1}}],[\"代码和类型一中的相同\",{\"1\":{\"200\":1}}],[\"代码为\",{\"1\":{\"198\":1}}],[\"代码\",{\"1\":{\"46\":1}}],[\"由志愿者打开所有选手机桌面上的\",{\"1\":{\"173\":1}}],[\"由\",{\"1\":{\"141\":1}}],[\"由于虚拟机本身的数据保存机制\",{\"1\":{\"134\":1}}],[\"由于universaloj脚本会将原站所有数据迁移\",{\"1\":{\"117\":1}}],[\"由于其升级过程较为麻烦\",{\"1\":{\"117\":1}}],[\"由于syzoj脚本会将原站所有数据迁移\",{\"1\":{\"116\":1}}],[\"由于用附加组件安装的评测机与\",{\"1\":{\"97\":1}}],[\"由于防止解析\",{\"1\":{\"92\":1}}],[\"由于形式的错误造成系统不能理解\",{\"1\":{\"10\":1}}],[\"旧版本\",{\"1\":{\"141\":1}}],[\"占用较大\",{\"1\":{\"141\":1}}],[\"选择题\",{\"1\":{\"203\":1,\"218\":1,\"219\":2}}],[\"选手机均连接到内网\",{\"1\":{\"172\":1}}],[\"选手机预装了\",{\"1\":{\"172\":1}}],[\"选项卡中\",{\"1\":{\"189\":1}}],[\"选项卡中点击\",{\"1\":{\"187\":1}}],[\"选项卡中找到\",{\"1\":{\"186\":1}}],[\"选项\",{\"1\":{\"141\":1,\"156\":1}}],[\"选中值为\",{\"1\":{\"77\":1}}],[\"替代进程\",{\"1\":{\"166\":1}}],[\"替代此处的进程名称\",{\"1\":{\"166\":1}}],[\"替代\",{\"1\":{\"139\":1}}],[\"替换为编译出的\",{\"1\":{\"137\":1}}],[\"小结\",{\"0\":{\"204\":1}}],[\"小票机同理\",{\"1\":{\"175\":1}}],[\"小票内含队伍名\",{\"1\":{\"173\":1}}],[\"小组内\",{\"1\":{\"163\":1}}],[\"小写\",{\"1\":{\"139\":1}}],[\"小时以前的提交记录\",{\"1\":{\"68\":1}}],[\"构建过程中的缓存文件可以使用\",{\"1\":{\"137\":1}}],[\"构建后会产生一个\",{\"1\":{\"137\":1}}],[\"记得给打印机补纸\",{\"1\":{\"175\":1}}],[\"记得清理浏览器缓存\",{\"1\":{\"27\":1}}],[\"记住该文件夹所在的路径\",{\"1\":{\"137\":1}}],[\"复制\",{\"1\":{\"182\":1}}],[\"复制题目可以帮助用户将任何有权提交的题目复制到有权创建题目的域中以在比赛\",{\"1\":{\"181\":1}}],[\"复制题目\",{\"0\":{\"181\":1}}],[\"复制到\",{\"1\":{\"162\":1}}],[\"复制即可\",{\"1\":{\"159\":1}}],[\"复制以上文件\",{\"1\":{\"137\":1}}],[\"复杂\",{\"1\":{\"47\":2}}],[\"查找数据库\",{\"1\":{\"156\":1}}],[\"查找方式同上文\",{\"1\":{\"137\":1}}],[\"查看域等等\",{\"1\":{\"192\":1}}],[\"查看该进程的后\",{\"1\":{\"167\":1}}],[\"查看进程列表\",{\"1\":{\"167\":1}}],[\"查看已安装版本\",{\"0\":{\"169\":1}}],[\"查看已安装的列表\",{\"1\":{\"136\":1}}],[\"查看已注册的插件列表\",{\"0\":{\"87\":1}}],[\"查看具体使用指南\",{\"1\":{\"131\":1}}],[\"查看\",{\"1\":{\"94\":1,\"166\":1}}],[\"查看此域\",{\"1\":{\"18\":1}}],[\"库\",{\"1\":{\"136\":1}}],[\"已知旧版本的内核在高负载的情况下可能出现锁死的问题\",{\"1\":{\"172\":1}}],[\"已知能够完整兼容的服务商有\",{\"1\":{\"142\":1}}],[\"已移动至\",{\"1\":{\"143\":1}}],[\"已有文件请自行复制\",{\"1\":{\"141\":2}}],[\"已预装\",{\"1\":{\"136\":2}}],[\"已于新版本中被废弃\",{\"1\":{\"222\":1}}],[\"已于\",{\"1\":{\"134\":1}}],[\"生效\",{\"1\":{\"136\":2}}],[\"生产模式\",{\"1\":{\"47\":1}}],[\"另\",{\"1\":{\"135\":1}}],[\"免费专区进行下载\",{\"1\":{\"135\":1}}],[\"样例\",{\"1\":{\"135\":1,\"197\":1}}],[\"务必正确填写\",{\"1\":{\"135\":1}}],[\"结尾\",{\"1\":{\"135\":1,\"145\":1}}],[\"结果确定\",{\"1\":{\"45\":1}}],[\"结果你没有空\",{\"1\":{\"10\":1}}],[\"验证管理员密码后按需修改配置\",{\"1\":{\"135\":1}}],[\"验证码\",{\"1\":{\"85\":1}}],[\"放行80端口\",{\"1\":{\"135\":1}}],[\"放置于\",{\"1\":{\"78\":1}}],[\"华为云等等用户安装后如果不能访问\",{\"1\":{\"135\":1}}],[\"宝塔面板已知出现多次高危漏洞\",{\"1\":{\"135\":1}}],[\"突然断电很容易导致数据库损坏无法读取\",{\"1\":{\"134\":1}}],[\"虚拟机由于非独占\",{\"1\":{\"134\":1}}],[\"虚拟机用户请注意\",{\"1\":{\"134\":1}}],[\"运维经验\",{\"1\":{\"134\":1}}],[\"运行该指令后您会从命令行窗口中看到该用户\",{\"1\":{\"148\":1}}],[\"运行下面的脚本\",{\"1\":{\"135\":1}}],[\"运行以下命令更新\",{\"1\":{\"113\":1}}],[\"运行的网址\",{\"1\":{\"98\":1}}],[\"它会消耗较多的内存\",{\"1\":{\"134\":1}}],[\"及其各种变种\",{\"1\":{\"134\":1}}],[\"上传或将文件拖拽至相应位置上传\",{\"1\":{\"221\":1}}],[\"上传相关文件后再编辑该题目\",{\"1\":{\"214\":1}}],[\"上传\",{\"1\":{\"209\":1,\"222\":1}}],[\"上传的\",{\"1\":{\"203\":1}}],[\"上传文件的位置\",{\"1\":{\"115\":1}}],[\"上面的例子故意设计为子任务编号和用例文件中的编号不同\",{\"1\":{\"202\":1}}],[\"上方包是评测所需要的\",{\"1\":{\"137\":1}}],[\"上运行\",{\"1\":{\"134\":1}}],[\"上手简单\",{\"1\":{\"134\":1}}],[\"发布\",{\"1\":{\"193\":1}}],[\"发布讨论\",{\"0\":{\"179\":1}}],[\"发送签名\",{\"1\":{\"142\":1}}],[\"发送至服务端\",{\"1\":{\"37\":1}}],[\"发行版\",{\"1\":{\"134\":1}}],[\"兼容大部分\",{\"1\":{\"134\":1}}],[\"兼容性\",{\"1\":{\"47\":1}}],[\"停止支持\",{\"1\":{\"134\":1}}],[\"人使用\",{\"1\":{\"134\":1}}],[\"约可允许\",{\"1\":{\"134\":1}}],[\"最后测试数据部分的文件列表如下图所示\",{\"1\":{\"200\":1}}],[\"最终的测试文件列表如下所示\",{\"1\":{\"200\":1}}],[\"最多五列\",{\"1\":{\"163\":1}}],[\"最低服务器配置\",{\"1\":{\"134\":1}}],[\"最新版本后\",{\"1\":{\"130\":1}}],[\"主进程同样支持多进程启动\",{\"1\":{\"167\":1}}],[\"主进程\",{\"1\":{\"166\":1,\"167\":1}}],[\"主频不同\",{\"1\":{\"134\":1}}],[\"主交互通道\",{\"1\":{\"40\":1}}],[\"表明该题为客观题\",{\"1\":{\"203\":1,\"219\":1}}],[\"表\",{\"1\":{\"173\":1}}],[\"表现为修改不生效\",{\"1\":{\"156\":1}}],[\"表中插入如下条目\",{\"1\":{\"132\":1}}],[\"表示仅在subtask0通过时此subtask才计分\",{\"1\":{\"222\":1}}],[\"表示仅捕获\",{\"1\":{\"68\":1}}],[\"表示用例\",{\"1\":{\"198\":1}}],[\"表示该用户的\",{\"1\":{\"152\":1}}],[\"表示在主逻辑完成后运行\",{\"1\":{\"68\":1}}],[\"表示路由事件\",{\"1\":{\"68\":1}}],[\"访问控制\",{\"0\":{\"188\":1}}],[\"访问\",{\"1\":{\"153\":1,\"154\":1}}],[\"访问网页端\",{\"1\":{\"135\":1}}],[\"访问来源有一定限制\",{\"1\":{\"131\":1}}],[\"访问次数\",{\"1\":{\"131\":1}}],[\"访问改路由需要priv\",{\"1\":{\"77\":1}}],[\"那么按照以下内容配置\",{\"1\":{\"126\":1}}],[\"那么自行输出这些文字将导致你的程序输出与老师事先告诉系统的输出不能做到\",{\"1\":{\"10\":1}}],[\"栏下的\",{\"1\":{\"119\":1}}],[\"第\",{\"1\":{\"119\":1}}],[\"密码为\",{\"1\":{\"148\":1,\"154\":1,\"163\":3}}],[\"密码\",{\"1\":{\"142\":1,\"163\":1}}],[\"密码是什么\",{\"0\":{\"26\":1}}],[\"密钥的\",{\"1\":{\"141\":2}}],[\"密钥\",{\"1\":{\"119\":1}}],[\"手动载入进程列表\",{\"1\":{\"167\":1}}],[\"手动恢复备份\",{\"0\":{\"159\":1}}],[\"手动备份\",{\"0\":{\"158\":1}}],[\"手动迁移请在开发群中提问\",{\"1\":{\"117\":1}}],[\"手动搭建\",{\"1\":{\"81\":1}}],[\"常见需求\",{\"1\":{\"192\":1}}],[\"常见于\",{\"1\":{\"167\":1}}],[\"常见问题\",{\"0\":{\"143\":1}}],[\"常见问题集合\",{\"0\":{\"5\":1}}],[\"常用教程\",{\"1\":{\"131\":1}}],[\"常称作uoj社区版\",{\"1\":{\"117\":1}}],[\"视情况而定\",{\"1\":{\"115\":1}}],[\"迁入的域\",{\"1\":{\"115\":1,\"116\":1}}],[\"迁移脚本应运行名为\",{\"1\":{\"116\":1,\"117\":1}}],[\"迁移方法类似\",{\"1\":{\"116\":1}}],[\"迁移后\",{\"1\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"迁移会删除当前\",{\"1\":{\"115\":1,\"118\":1}}],[\"迁移数据\",{\"0\":{\"14\":1}}],[\"账号密码\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"所以将一个用户的权限设为\",{\"1\":{\"188\":1}}],[\"所以将登陆用户设为\",{\"1\":{\"188\":1}}],[\"所以运行耗时较长\",{\"1\":{\"116\":1,\"117\":1}}],[\"所在的数据库不应和源\",{\"1\":{\"115\":1,\"118\":1}}],[\"所有测试点之和\",{\"1\":{\"222\":1}}],[\"所有测试点最大值\",{\"1\":{\"222\":1}}],[\"所有每个子任务都需要手工指定对应的cases\",{\"1\":{\"202\":1}}],[\"所有于\",{\"1\":{\"154\":1}}],[\"所有权限节点均可自由设置\",{\"1\":{\"80\":1}}],[\"所有官方插件均随源码仓库下载到安装文件夹的\",{\"1\":{\"50\":1}}],[\"所有提交给系统的答案必须包含并且只有一个main函数\",{\"1\":{\"10\":1}}],[\"而非\",{\"1\":{\"222\":1}}],[\"而是在每次测试时自动动态生成的话\",{\"1\":{\"200\":1}}],[\"而是推荐用\",{\"1\":{\"21\":1}}],[\"而在\",{\"1\":{\"113\":1}}],[\"设为interactive\",{\"1\":{\"204\":1}}],[\"设备默认使用\",{\"1\":{\"113\":1}}],[\"设置完后可点击\",{\"1\":{\"189\":1}}],[\"设置完之后\",{\"1\":{\"98\":1}}],[\"设置中填入\",{\"1\":{\"173\":1}}],[\"设置中填写真实\",{\"1\":{\"141\":1}}],[\"设置用户权限\",{\"0\":{\"150\":1}}],[\"设置全站管理员\",{\"0\":{\"149\":1}}],[\"设置末尾\",{\"1\":{\"132\":1}}],[\"设置项时\",{\"1\":{\"222\":1}}],[\"设置项修改为\",{\"1\":{\"145\":1}}],[\"设置项配置错误会导致无法记录用户ip\",{\"1\":{\"139\":1}}],[\"设置项配置错误会导致用户无法登录等问题\",{\"1\":{\"139\":1}}],[\"设置项需要填写正确\",{\"1\":{\"139\":1}}],[\"设置项\",{\"1\":{\"27\":1,\"222\":1}}],[\"意味着当前系统的内存消耗计量存在误差\",{\"1\":{\"113\":1}}],[\"警告时\",{\"1\":{\"113\":1}}],[\"频率波动\",{\"1\":{\"112\":1}}],[\"频率缩放与\",{\"1\":{\"112\":1}}],[\"防止\",{\"1\":{\"112\":1}}],[\"睿频加速技术\",{\"1\":{\"112\":1}}],[\"彩色编译错误信息\",{\"0\":{\"110\":1}}],[\"保存\",{\"1\":{\"173\":1}}],[\"保存对\",{\"1\":{\"167\":1}}],[\"保存为\",{\"1\":{\"137\":1}}],[\"保存后重启\",{\"1\":{\"109\":1,\"141\":2}}],[\"保证供电稳定\",{\"1\":{\"134\":1}}],[\"保证用户可以进行平滑升级\",{\"1\":{\"3\":1}}],[\"行日志\",{\"1\":{\"167\":1}}],[\"行的\",{\"1\":{\"109\":1}}],[\"行和第\",{\"1\":{\"109\":1}}],[\"单个测试点分数\",{\"1\":{\"222\":1}}],[\"单答案\",{\"1\":{\"219\":1}}],[\"单评测机评测进程数量\",{\"1\":{\"106\":1}}],[\"单题最大总测试时长\",{\"1\":{\"106\":1}}],[\"单题最多测试点数量\",{\"1\":{\"106\":1}}],[\"~100m\",{\"1\":{\"134\":1}}],[\"~\",{\"1\":{\"98\":1,\"106\":1,\"107\":1,\"137\":1,\"156\":1,\"161\":1,\"162\":1}}],[\"具体内容见后面的例子\",{\"1\":{\"197\":1}}],[\"具体的定义与数值可以查看\",{\"1\":{\"191\":1}}],[\"具体可根据实际情况自行安排\",{\"1\":{\"171\":1}}],[\"具体方法参照\",{\"1\":{\"98\":1}}],[\"具体流程如下\",{\"1\":{\"77\":1}}],[\"首页例外\",{\"1\":{\"162\":1}}],[\"首先需要创建一个有\",{\"1\":{\"98\":1}}],[\"首次启动会要求您填写数据库连接信息\",{\"1\":{\"51\":1}}],[\"必须在同一台服务器上\",{\"1\":{\"97\":1}}],[\"架构的\",{\"1\":{\"95\":1}}],[\"了编译器\",{\"1\":{\"95\":1}}],[\"重新构建\",{\"1\":{\"137\":1}}],[\"重新安装\",{\"1\":{\"95\":1}}],[\"重要\",{\"1\":{\"135\":1}}],[\"重建题目索引\",{\"0\":{\"128\":1}}],[\"重启进程\",{\"1\":{\"167\":1}}],[\"重启沙箱\",{\"1\":{\"136\":1}}],[\"重启\",{\"0\":{\"127\":1},\"1\":{\"27\":1,\"97\":1,\"119\":1,\"126\":1,\"172\":1}}],[\"重启后\",{\"1\":{\"16\":1}}],[\"重启服务\",{\"1\":{\"16\":1}}],[\"准备完成后\",{\"1\":{\"173\":1}}],[\"准备工作\",{\"0\":{\"172\":1,\"173\":1}}],[\"准备\",{\"0\":{\"95\":1}}],[\"准备编写组件\",{\"0\":{\"77\":1}}],[\"搜索功能应当可以正常使用\",{\"1\":{\"90\":1,\"128\":1}}],[\"至此\",{\"1\":{\"90\":1,\"128\":1,\"135\":1}}],[\"卸载\",{\"0\":{\"89\":1,\"103\":1}}],[\"绝对路径\",{\"1\":{\"86\":1}}],[\"先\",{\"1\":{\"152\":1}}],[\"先全局安装所需模块\",{\"1\":{\"86\":1}}],[\"先执行\",{\"1\":{\"77\":1}}],[\"导致文件直接被下载而非预览\",{\"1\":{\"214\":1}}],[\"导出的题目压缩包即可\",{\"1\":{\"209\":1}}],[\"导出的题库\",{\"1\":{\"85\":2}}],[\"导出一些基本信息和部分编译器所需的\",{\"1\":{\"137\":1}}],[\"导出系统状态至\",{\"1\":{\"85\":1}}],[\"导入题目\",{\"0\":{\"208\":1}}],[\"导入用户数据\",{\"1\":{\"163\":1}}],[\"导入用户\",{\"0\":{\"163\":1}}],[\"导入备份的数据库文件\",{\"1\":{\"159\":1}}],[\"导入\",{\"0\":{\"209\":1,\"210\":1,\"212\":1},\"1\":{\"85\":3}}],[\"导入所需的比赛用户\",{\"1\":{\"173\":1}}],[\"导入所需的5\",{\"1\":{\"17\":1}}],[\"导入所有数据至\",{\"1\":{\"80\":1}}],[\"博客功能\",{\"1\":{\"85\":1}}],[\"描述这类的框不知道写啥就随便填\",{\"1\":{\"189\":1}}],[\"描述\",{\"1\":{\"85\":1}}],[\"官方目前提供了以下附加组件\",{\"1\":{\"85\":1}}],[\"详询对应服务商\",{\"1\":{\"214\":1}}],[\"详见下方题面编辑部分\",{\"1\":{\"207\":1}}],[\"详情见后\",{\"1\":{\"197\":1}}],[\"详情\",{\"1\":{\"172\":1}}],[\"详情请前往\",{\"1\":{\"94\":1}}],[\"详情请前往左侧插件详情查看\",{\"1\":{\"85\":1}}],[\"详细说明\",{\"1\":{\"13\":1}}],[\"斜体标注\",{\"1\":{\"85\":1}}],[\"附加文件下载链接\",{\"1\":{\"214\":1}}],[\"附加组件列表\",{\"0\":{\"85\":1}}],[\"附加条款\",{\"0\":{\"3\":1}}],[\"域头像\",{\"1\":{\"186\":1}}],[\"域主页上显示的公告\",{\"1\":{\"186\":1}}],[\"域的名字\",{\"1\":{\"186\":1}}],[\"域间数据完全独立\",{\"1\":{\"185\":1}}],[\"域功能类似团队\",{\"1\":{\"185\":1}}],[\"域\",{\"0\":{\"184\":1}}],[\"域中的所有题目包导出\",{\"1\":{\"154\":1}}],[\"域中\",{\"1\":{\"154\":1,\"209\":1}}],[\"域名\",{\"1\":{\"145\":1}}],[\"域之间仅共享账号数据\",{\"1\":{\"83\":1}}],[\"域设置>编辑域资料\",{\"1\":{\"183\":1}}],[\"域设置\",{\"1\":{\"35\":1}}],[\"阿里oss\",{\"1\":{\"83\":1}}],[\"阿里云oss\",{\"1\":{\"141\":1}}],[\"阿里云\",{\"1\":{\"12\":1,\"135\":1}}],[\"指令中使用\",{\"1\":{\"147\":1}}],[\"指令集\",{\"1\":{\"134\":1}}],[\"指令集以提高运行性能\",{\"1\":{\"134\":1}}],[\"指所有兼容\",{\"1\":{\"83\":1}}],[\"指定输入文件和输出文件\",{\"1\":{\"196\":1}}],[\"指定模板则渲染\",{\"1\":{\"77\":1}}],[\"指定启动端口\",{\"1\":{\"51\":1}}],[\"↩︎\",{\"1\":{\"83\":9}}],[\"曾用名\",{\"1\":{\"83\":1}}],[\"吧\",{\"1\":{\"83\":1}}],[\"团队\",{\"1\":{\"81\":1}}],[\"题号\",{\"1\":{\"205\":1}}],[\"题面支持合并表格\",{\"1\":{\"214\":1}}],[\"题面使用\",{\"1\":{\"214\":1}}],[\"题面\",{\"0\":{\"214\":1,\"218\":1}}],[\"题面是必须录入的\",{\"1\":{\"204\":1}}],[\"题面里可以用如下格式为用户提供下载链接\",{\"1\":{\"199\":1}}],[\"题单\",{\"1\":{\"81\":1}}],[\"题目类型\",{\"1\":{\"222\":1}}],[\"题目名\",{\"1\":{\"205\":1}}],[\"题目运行效果如下\",{\"1\":{\"203\":1}}],[\"题目内容和类型一类似\",{\"1\":{\"200\":1}}],[\"题目内容的录入以及测试数据的录入和类型一样\",{\"1\":{\"199\":1}}],[\"题目网址\",{\"1\":{\"198\":1,\"199\":1}}],[\"题目一栏支持根据题目id或是题目名自动筛选\",{\"1\":{\"189\":1}}],[\"题目难度\",{\"0\":{\"177\":1}}],[\"题目导入\",{\"1\":{\"81\":1}}],[\"题目详情为值的对象\",{\"1\":{\"70\":1}}],[\"题目的难度由算法计算得出\",{\"1\":{\"177\":1}}],[\"题目的提交状态\",{\"1\":{\"70\":1}}],[\"题目的限时和内存限制的精度是怎样的\",{\"0\":{\"22\":1}}],[\"题目\",{\"0\":{\"206\":1},\"1\":{\"28\":1,\"35\":1,\"70\":1,\"207\":1}}],[\"题目限时允许设定的字面精度是\",{\"1\":{\"22\":1}}],[\"题目可以按通过的比例进行记分\",{\"1\":{\"20\":1}}],[\"题目列表右侧有相应入口\",{\"1\":{\"17\":1}}],[\"添加用户\",{\"1\":{\"188\":1}}],[\"添加了状态上报\",{\"1\":{\"172\":1}}],[\"添加新语言支持\",{\"0\":{\"107\":1}}],[\"添加语言需要修改源代码\",{\"1\":{\"83\":1}}],[\"添加语言\",{\"1\":{\"81\":1,\"161\":1}}],[\"添加公告\",{\"1\":{\"68\":1}}],[\"乐多\",{\"1\":{\"81\":1}}],[\"未登录用户将默认使用\",{\"1\":{\"188\":1}}],[\"未知\",{\"1\":{\"81\":1}}],[\"未选中则为空\",{\"1\":{\"77\":1}}],[\"只需要专心实现给定的函数即可\",{\"1\":{\"199\":1}}],[\"只需要在停止\",{\"1\":{\"159\":1}}],[\"只监听8888端口\",{\"1\":{\"135\":1}}],[\"只进行在不修改源代码情况下的对比\",{\"1\":{\"81\":1}}],[\"只读文件系统\",{\"1\":{\"80\":1}}],[\"直接比对\",{\"1\":{\"222\":1}}],[\"直接访问训练计划编辑页并修正配置文件\",{\"1\":{\"190\":1}}],[\"直接访问编辑页并修正\",{\"1\":{\"189\":1}}],[\"直接选择第二项启动选项即可一键安装\",{\"1\":{\"172\":1}}],[\"直接操作数据库的权限过大\",{\"1\":{\"156\":1}}],[\"直接修改数据库后\",{\"1\":{\"156\":1}}],[\"直接导入\",{\"1\":{\"80\":1}}],[\"直到用户名可用\",{\"1\":{\"73\":1}}],[\"正式赛\",{\"0\":{\"175\":1}}],[\"正在管理的所有进程\",{\"1\":{\"166\":1}}],[\"正在持续维护中\",{\"1\":{\"80\":1}}],[\"正确的方式是每次训练\",{\"1\":{\"17\":1}}],[\"社区\",{\"1\":{\"80\":1}}],[\"易上手\",{\"1\":{\"80\":1}}],[\"易于部署\",{\"1\":{\"0\":1}}],[\"独立评测机\",{\"1\":{\"80\":1}}],[\"配合\",{\"1\":{\"80\":1}}],[\"配置选手机网络\",{\"1\":{\"172\":1}}],[\"配置过程不同\",{\"1\":{\"146\":1}}],[\"配置方法不同\",{\"1\":{\"146\":1}}],[\"配置资源\",{\"1\":{\"146\":1}}],[\"配置较为繁琐\",{\"1\":{\"146\":1}}],[\"配置示例\",{\"1\":{\"124\":1}}],[\"配置项即可\",{\"1\":{\"107\":1}}],[\"配置文件格式如下\",{\"1\":{\"98\":1}}],[\"配置文件位于\",{\"1\":{\"21\":1}}],[\"配置\",{\"0\":{\"125\":1,\"138\":1},\"1\":{\"20\":1,\"108\":1,\"126\":1,\"141\":2,\"173\":1}}],[\"强大\",{\"1\":{\"80\":1}}],[\"杜绝卡评测\",{\"1\":{\"80\":1}}],[\"安全\",{\"1\":{\"80\":1}}],[\"安装对应的打印机驱动\",{\"1\":{\"173\":1}}],[\"安装时执行命令的位置\",{\"1\":{\"147\":1}}],[\"安装新编译器\",{\"1\":{\"136\":1}}],[\"安装编译器后使用\",{\"1\":{\"136\":1}}],[\"安装完成后\",{\"1\":{\"135\":1}}],[\"安装完插件后需要重启\",{\"1\":{\"86\":1}}],[\"安装脚本支持一些可选的高级选项\",{\"1\":{\"135\":1}}],[\"安装脚本已提供自动升级服务\",{\"1\":{\"117\":1}}],[\"安装和安装后的所有操作均需要在\",{\"1\":{\"135\":1}}],[\"安装后题目搜索不正常\",{\"0\":{\"130\":1}}],[\"安装插件后创建名为\",{\"1\":{\"132\":1}}],[\"安装插件后\",{\"1\":{\"115\":1,\"118\":1}}],[\"安装配置繁琐\",{\"1\":{\"83\":1}}],[\"安装相关开发组件\",{\"1\":{\"76\":1}}],[\"安装\",{\"0\":{\"49\":1,\"86\":1,\"96\":1,\"121\":1,\"123\":1},\"1\":{\"48\":2,\"81\":1,\"86\":1,\"90\":1,\"141\":1,\"173\":2}}],[\"安装依赖包\",{\"1\":{\"49\":1}}],[\"安装依赖\",{\"0\":{\"48\":1}}],[\"介绍\",{\"0\":{\"80\":1}}],[\"格式已经更新\",{\"1\":{\"203\":1}}],[\"格式创建一个新文件\",{\"1\":{\"161\":1}}],[\"格式为\",{\"1\":{\"153\":1}}],[\"格式的题面\",{\"1\":{\"205\":1}}],[\"格式的题目\",{\"1\":{\"85\":1}}],[\"格式的\",{\"1\":{\"92\":2}}],[\"格式题目\",{\"1\":{\"85\":1}}],[\"格式\",{\"1\":{\"83\":1,\"163\":3,\"221\":1}}],[\"格式后使用\",{\"1\":{\"80\":1}}],[\"格式与前面的三排类似\",{\"1\":{\"106\":1}}],[\"格式与\",{\"1\":{\"79\":1}}],[\"格式在页脚注明\",{\"1\":{\"3\":1}}],[\"存入\",{\"1\":{\"78\":1}}],[\"存储\",{\"0\":{\"140\":1}}],[\"存储临时信息\",{\"1\":{\"65\":1}}],[\"存储系统日志\",{\"1\":{\"58\":1}}],[\"存储用户的提交记录\",{\"1\":{\"56\":1}}],[\"存储用户在对应文档下留下的信息\",{\"1\":{\"55\":1}}],[\"存储所有文档\",{\"1\":{\"54\":1}}],[\"会与标题同时显示在列表页面中\",{\"1\":{\"190\":1}}],[\"会根据比赛规则显示排名\",{\"1\":{\"178\":1}}],[\"会打印一张小票\",{\"1\":{\"173\":1}}],[\"会自动抓取打印任务自动打印\",{\"1\":{\"173\":1}}],[\"会自动完成之后的升级操作\",{\"1\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"会降低性能且成倍提高内存占用\",{\"1\":{\"167\":1}}],[\"会导致评测时间计量精度降低\",{\"1\":{\"134\":1}}],[\"会发布不定期更新\",{\"1\":{\"99\":1}}],[\"会在请求结束时根据\",{\"1\":{\"78\":1}}],[\"会是格式错误\",{\"1\":{\"10\":1}}],[\"语言代号支持完整形式\",{\"1\":{\"205\":1}}],[\"语言介绍\",{\"1\":{\"137\":1}}],[\"语言配置下发\",{\"0\":{\"42\":1}}],[\"语法\",{\"1\":{\"78\":1,\"214\":1}}],[\"模式运行\",{\"1\":{\"173\":1}}],[\"模式\",{\"1\":{\"141\":1}}],[\"模块使用\",{\"1\":{\"172\":1}}],[\"模块\",{\"1\":{\"80\":1}}],[\"模块名\",{\"1\":{\"77\":1}}],[\"模板采用\",{\"1\":{\"78\":1}}],[\"路由匹配基于\",{\"1\":{\"77\":1}}],[\"路由以创建新文档\",{\"1\":{\"77\":1}}],[\"匹配\",{\"1\":{\"77\":1}}],[\"仅需要配置\",{\"1\":{\"219\":1}}],[\"仅需要修改\",{\"1\":{\"137\":1}}],[\"仅用户信息相通\",{\"1\":{\"185\":1}}],[\"仅用于发送系统消息\",{\"1\":{\"26\":1}}],[\"仅作为独立评测机安装\",{\"1\":{\"135\":1}}],[\"仅作为说明\",{\"1\":{\"77\":1}}],[\"仅作留存使用\",{\"1\":{\"131\":1}}],[\"仅保留其数据库开启\",{\"1\":{\"115\":1,\"118\":1}}],[\"仅能修改部分编译参数\",{\"1\":{\"83\":1}}],[\"方法用于将用户重定向至前一个地址\",{\"1\":{\"77\":1}}],[\"方案三\",{\"1\":{\"37\":1}}],[\"方案二\",{\"1\":{\"37\":1}}],[\"方案一\",{\"1\":{\"37\":1}}],[\"相应的\",{\"1\":{\"77\":1}}],[\"相关教程\",{\"1\":{\"135\":1}}],[\"相关操作参照其文档\",{\"1\":{\"77\":1}}],[\"相关文档若说明的不够详细\",{\"1\":{\"0\":1}}],[\"从附加文件引用\",{\"1\":{\"214\":2}}],[\"从附加文件引用一张图片\",{\"1\":{\"214\":1}}],[\"从\",{\"0\":{\"92\":1,\"115\":1,\"116\":1,\"117\":1,\"118\":1,\"209\":1,\"210\":1,\"211\":1,\"212\":1},\"1\":{\"85\":1,\"92\":1,\"135\":1,\"136\":1}}],[\"从用户提交的表单中取出content和private字段\",{\"1\":{\"77\":1}}],[\"从系统设置中获取基础设置\",{\"1\":{\"73\":1}}],[\"使得\",{\"1\":{\"77\":1}}],[\"使用语言id而非名称\",{\"1\":{\"222\":2}}],[\"使用配置文件\",{\"0\":{\"222\":1}}],[\"使用一键安装脚本安装的\",{\"1\":{\"165\":1}}],[\"使用一键安装脚本部署的\",{\"1\":{\"140\":1}}],[\"使用外部工具连接请确保使用了正确的\",{\"1\":{\"156\":1}}],[\"使用内容分发网络\",{\"0\":{\"144\":1}}],[\"使用安装脚本安装\",{\"1\":{\"173\":1}}],[\"使用安装脚本需要设置\",{\"1\":{\"134\":1}}],[\"使用安装脚本后忘记\",{\"0\":{\"24\":1}}],[\"使用的数据库依赖于\",{\"1\":{\"134\":1}}],[\"使用下面的指令即可开始运行\",{\"1\":{\"98\":1}}],[\"使用了沙箱复用技术\",{\"1\":{\"80\":1}}],[\"使用pastecreatehandler处理\",{\"1\":{\"77\":1}}],[\"使用从\",{\"1\":{\"73\":1}}],[\"使用代理\",{\"1\":{\"47\":1}}],[\"使用开发环境默认您有良好的国际互联网连接\",{\"1\":{\"47\":1}}],[\"使用自动脚本安装也可以基于插件系统完成大部分的定制需求\",{\"1\":{\"47\":1}}],[\"使用形如\",{\"1\":{\"37\":1}}],[\"使用\",{\"0\":{\"6\":1,\"31\":1,\"67\":1,\"74\":1,\"141\":1},\"1\":{\"23\":1,\"25\":1,\"27\":1,\"37\":1,\"47\":1,\"51\":1,\"54\":1,\"67\":1,\"73\":2,\"75\":2,\"76\":3,\"77\":2,\"80\":1,\"90\":1,\"122\":1,\"123\":1,\"136\":2,\"137\":1,\"142\":1,\"159\":1,\"165\":1,\"222\":1}}],[\"暴露这些接口\",{\"1\":{\"77\":1}}],[\"声明数据表类型\",{\"1\":{\"77\":1}}],[\"函数交互型题目\",{\"0\":{\"199\":1}}],[\"函数将在初始化阶段被调用\",{\"1\":{\"77\":1}}],[\"函数\",{\"1\":{\"77\":2}}],[\"函数名使用驼峰命名\",{\"1\":{\"77\":1}}],[\"函数命名规则\",{\"0\":{\"71\":1}}],[\"含已封禁用户\",{\"1\":{\"194\":1}}],[\"含选手机\",{\"1\":{\"172\":1}}],[\"含用户账户信息\",{\"1\":{\"115\":1,\"118\":1}}],[\"含有自定义头文件的oj题\",{\"1\":{\"196\":1}}],[\"含有\",{\"1\":{\"77\":1}}],[\"含义请查看\",{\"1\":{\"45\":1}}],[\"执行命令\",{\"1\":{\"127\":1}}],[\"执行如下命令\",{\"1\":{\"124\":1}}],[\"执行\",{\"1\":{\"77\":4}}],[\"执行下面的操作即可\",{\"1\":{\"33\":1}}],[\"允许在一套系统中创建多个环境\",{\"1\":{\"185\":1}}],[\"允许用户使用\",{\"1\":{\"85\":2}}],[\"允许用户创建域并在域内拥有管理员权限\",{\"1\":{\"83\":1}}],[\"允许将文档设置为私密以防止他人查看\",{\"1\":{\"77\":1}}],[\"允许的语言\",{\"1\":{\"35\":2}}],[\"来检验注册者是否是人类\",{\"1\":{\"119\":1}}],[\"来检测并进行更新\",{\"1\":{\"99\":1}}],[\"来查看已创建的文档\",{\"1\":{\"77\":1}}],[\"来源署名\",{\"1\":{\"3\":1}}],[\"检查输入\",{\"1\":{\"77\":1}}],[\"检查用户是否登录\",{\"1\":{\"77\":1}}],[\"检查请求类型\",{\"1\":{\"77\":1}}],[\"检查登陆状态是否有效\",{\"1\":{\"40\":1}}],[\"检索相应文档\",{\"1\":{\"77\":1}}],[\"剪贴板组件需要以下功能\",{\"1\":{\"77\":1}}],[\"有部分分\",{\"1\":{\"203\":1,\"219\":1}}],[\"有时希望指定输入和输出文件\",{\"1\":{\"201\":1}}],[\"有时我们希望使用本机的\",{\"1\":{\"76\":1}}],[\"有可能出现不准确的结果\",{\"1\":{\"177\":1}}],[\"有条件请购买\",{\"1\":{\"134\":1}}],[\"有条件找虚拟机实测还原是否成功\",{\"1\":{\"21\":1}}],[\"q\",{\"1\":{\"136\":1}}],[\"quitf\",{\"1\":{\"200\":4}}],[\"quiet\",{\"1\":{\"113\":2}}],[\"query\",{\"1\":{\"124\":3}}],[\"querystring\",{\"1\":{\"77\":1}}],[\"question\",{\"1\":{\"75\":8}}],[\"qduoj\",{\"0\":{\"212\":1},\"1\":{\"80\":3,\"81\":4,\"85\":2,\"212\":1,\"222\":1}}],[\"qq\",{\"1\":{\"26\":1,\"142\":4,\"186\":1,\"196\":1}}],[\"$out\",{\"1\":{\"137\":1}}],[\"$\",{\"1\":{\"73\":2,\"75\":1,\"110\":1}}],[\"$set\",{\"1\":{\"33\":1,\"132\":1}}],[\"```output1\",{\"1\":{\"197\":1,\"214\":1}}],[\"```\",{\"1\":{\"197\":2,\"214\":2}}],[\"```input1\",{\"1\":{\"197\":1,\"214\":1}}],[\"`yarn\",{\"1\":{\"169\":1}}],[\"`cgroup\",{\"1\":{\"113\":1}}],[\"`github\",{\"1\":{\"73\":1}}],[\"`\",{\"1\":{\"73\":2}}],[\"`token\",{\"1\":{\"73\":1}}],[\"`$\",{\"1\":{\"73\":5}}],[\"`https\",{\"1\":{\"73\":1}}],[\"再点击\",{\"1\":{\"188\":1}}],[\"再重启沙箱即可生效\",{\"1\":{\"137\":1}}],[\"再运行重建题目索引\",{\"1\":{\"130\":1}}],[\"再向\",{\"1\":{\"86\":1}}],[\"再执行\",{\"1\":{\"77\":1}}],[\"再调用\",{\"1\":{\"73\":1}}],[\"再将老师事先提供的输入数据\",{\"1\":{\"10\":1}}],[\"换取\",{\"1\":{\"73\":1}}],[\"登录用户将默认使用\",{\"1\":{\"188\":1}}],[\"登录账号后\",{\"1\":{\"186\":1}}],[\"登录\",{\"1\":{\"73\":2,\"85\":2,\"173\":1}}],[\"登录为例\",{\"1\":{\"73\":1}}],[\"登记成绩表等操作\",{\"1\":{\"45\":1}}],[\"接入第三方账号系统\",{\"0\":{\"72\":1}}],[\"类型\",{\"1\":{\"146\":1}}],[\"类型请选择\",{\"1\":{\"119\":1}}],[\"类对象\",{\"1\":{\"71\":1}}],[\"类似办法创建一个\",{\"1\":{\"198\":1}}],[\"类似\",{\"1\":{\"26\":1}}],[\"返回此页面\",{\"1\":{\"77\":1}}],[\"返回插入的文档id\",{\"1\":{\"77\":1}}],[\"返回\",{\"1\":{\"71\":1}}],[\"返回对应值或\",{\"1\":{\"71\":1}}],[\"获取黑名单中有关\",{\"1\":{\"153\":1}}],[\"获取用户信息\",{\"1\":{\"73\":1}}],[\"获取系统设置和之前的状态\",{\"1\":{\"73\":1}}],[\"获取数据库查询的指针\",{\"1\":{\"71\":1}}],[\"获取内容\",{\"1\":{\"71\":2}}],[\"获取公告\",{\"1\":{\"68\":1}}],[\"键为题目\",{\"1\":{\"70\":1}}],[\"包含\",{\"1\":{\"86\":1}}],[\"包含若干题目的数组\",{\"1\":{\"70\":1}}],[\"包括如下内容\",{\"1\":{\"196\":1}}],[\"包括未加入域的用户\",{\"1\":{\"194\":1}}],[\"包括起来的部分\",{\"1\":{\"147\":1}}],[\"包括腾讯cos\",{\"1\":{\"83\":1}}],[\"包括\",{\"1\":{\"77\":1}}],[\"包括题目\",{\"1\":{\"54\":1}}],[\"包括但不限于使用\",{\"1\":{\"3\":1}}],[\"站内信息\",{\"1\":{\"70\":1}}],[\"讨论的二级回复\",{\"1\":{\"70\":1}}],[\"讨论的回复\",{\"1\":{\"70\":1}}],[\"讨论\",{\"1\":{\"70\":1}}],[\"训练此章节之前需要完成的章节数字编号\",{\"1\":{\"190\":1}}],[\"训练计划中使用这些题目\",{\"1\":{\"181\":1}}],[\"训练计划\",{\"1\":{\"81\":1}}],[\"训练\",{\"1\":{\"70\":1,\"190\":1}}],[\"训练等等\",{\"1\":{\"54\":1}}],[\"变更到另一权限组\",{\"1\":{\"195\":1}}],[\"变更后\",{\"1\":{\"25\":1}}],[\"变为\",{\"1\":{\"113\":1}}],[\"变量命名规则\",{\"0\":{\"70\":1}}],[\"系列钩子的一参数为对应的\",{\"1\":{\"68\":1}}],[\"系统会自动尝试识别数据点\",{\"1\":{\"222\":1}}],[\"系统会不定期发布更新\",{\"1\":{\"168\":1}}],[\"系统会根据返回的用户信息自动查找已有用户或是创建新用户\",{\"1\":{\"73\":1}}],[\"系统放在同一台机器上\",{\"1\":{\"158\":1}}],[\"系统安装后需要题库\",{\"1\":{\"135\":1}}],[\"系统启动后仅占用\",{\"1\":{\"134\":1}}],[\"系统设置>hydrojudge\",{\"1\":{\"101\":1,\"105\":1}}],[\"系统设置中预留了大量可自行修改的内容\",{\"1\":{\"80\":1}}],[\"系统默认拒绝导入超过\",{\"1\":{\"92\":1}}],[\"系统的功能\",{\"1\":{\"81\":1}}],[\"系统\",{\"1\":{\"48\":1,\"172\":2}}],[\"系统要求\",{\"1\":{\"48\":1}}],[\"系统为了能用统一的方式运行所有同学的答案\",{\"1\":{\"10\":1}}],[\"系统编译并运行学生的程序\",{\"1\":{\"10\":1}}],[\"系统运行过程如下\",{\"1\":{\"10\":1}}],[\"系统中的用户只有编辑\",{\"1\":{\"9\":1}}],[\"示例\",{\"0\":{\"68\":1}}],[\"参与比赛\",{\"0\":{\"178\":1},\"1\":{\"178\":1}}],[\"参数启动容器\",{\"1\":{\"134\":1}}],[\"参数\",{\"1\":{\"116\":1}}],[\"参数留空即可\",{\"1\":{\"90\":1,\"128\":1}}],[\"参考所使用服务商cdn文档来设置用户来源ip\",{\"1\":{\"146\":1}}],[\"参考\",{\"1\":{\"66\":1}}],[\"参照下文进行插件开发工作\",{\"1\":{\"76\":1}}],[\"参照步骤\",{\"1\":{\"76\":1}}],[\"参照\",{\"1\":{\"68\":1,\"108\":1,\"141\":2,\"173\":1}}],[\"参照左侧\",{\"1\":{\"47\":1}}],[\"参照本文\",{\"1\":{\"9\":1}}],[\"前加上\",{\"1\":{\"162\":1}}],[\"前安装的用户\",{\"1\":{\"109\":1}}],[\"前往\",{\"1\":{\"95\":1,\"119\":1}}],[\"前置条件\",{\"1\":{\"74\":1}}],[\"前端修改\",{\"0\":{\"66\":1,\"160\":1},\"1\":{\"66\":1}}],[\"前请先完成\",{\"1\":{\"48\":1}}],[\"作者\",{\"1\":{\"196\":1}}],[\"作为题面\",{\"1\":{\"214\":1}}],[\"作为安装镜像\",{\"1\":{\"172\":1}}],[\"作为存储后端\",{\"0\":{\"141\":1}}],[\"作为独立进程\",{\"0\":{\"98\":1,\"102\":1,\"106\":1}}],[\"作为附加组件\",{\"0\":{\"97\":1,\"101\":1,\"105\":1}}],[\"作为函数返回\",{\"1\":{\"73\":1}}],[\"作频率限制用\",{\"1\":{\"64\":1}}],[\"作业功能\",{\"1\":{\"81\":1}}],[\"作业的提交状态\",{\"1\":{\"70\":1}}],[\"作业\",{\"0\":{\"189\":1},\"1\":{\"17\":1,\"70\":1,\"181\":1,\"189\":2}}],[\"定义了一种基于\",{\"1\":{\"205\":1}}],[\"定时任务相关\",{\"1\":{\"63\":1}}],[\"定制自动备份计划\",{\"1\":{\"14\":1}}],[\"基本指令\",{\"0\":{\"167\":1}}],[\"基础组件\",{\"1\":{\"136\":2}}],[\"基础功能安装已全部完成\",{\"1\":{\"135\":1}}],[\"基础列\",{\"1\":{\"54\":1,\"55\":1,\"56\":1,\"57\":1}}],[\"基于\",{\"1\":{\"3\":1,\"30\":1,\"85\":2,\"107\":1}}],[\"数万甚至数十万\",{\"1\":{\"194\":1}}],[\"数据既可以用文本编辑器创建\",{\"1\":{\"163\":1}}],[\"数据库备份和恢复\",{\"0\":{\"155\":1}}],[\"数据库名\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"数据库端口\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"数据库地址\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"数据库相同\",{\"1\":{\"115\":1,\"118\":1}}],[\"数据库\",{\"1\":{\"81\":2,\"166\":1}}],[\"数据库结构\",{\"0\":{\"53\":1}}],[\"数计量\",{\"1\":{\"45\":1}}],[\"部署提供技术支持\",{\"1\":{\"134\":1}}],[\"部署hydro\",{\"1\":{\"94\":1}}],[\"部署\",{\"0\":{\"133\":1,\"135\":1},\"1\":{\"83\":1}}],[\"部署难度\",{\"1\":{\"47\":1}}],[\"部分语言默认已存在倍率\",{\"1\":{\"222\":1}}],[\"部分服务商可能会强制发送\",{\"1\":{\"214\":1}}],[\"部分情况下若无法使用\",{\"1\":{\"214\":1}}],[\"部分题目可能不允许复制\",{\"1\":{\"183\":1}}],[\"部分反代工具会使用\",{\"1\":{\"139\":1}}],[\"部分\",{\"1\":{\"113\":1}}],[\"部分插件若安装后没有正确配置可能会影响系统正常使用\",{\"1\":{\"85\":1}}],[\"部分插件\",{\"1\":{\"85\":1}}],[\"部分二次开发版本有此功能\",{\"1\":{\"83\":1}}],[\"部分支持的远程站点对提交数量\",{\"1\":{\"131\":1}}],[\"部分支持\",{\"1\":{\"81\":1}}],[\"部分模块修改后可能仍需重启才能生效\",{\"1\":{\"51\":1}}],[\"启用后\",{\"1\":{\"173\":1}}],[\"启用上传的插件\",{\"1\":{\"76\":1}}],[\"启用热重载\",{\"1\":{\"51\":1}}],[\"启用开发模式\",{\"1\":{\"51\":1}}],[\"启动进程\",{\"1\":{\"167\":1}}],[\"启动时显示的\",{\"1\":{\"141\":1}}],[\"启动完成后\",{\"1\":{\"51\":1}}],[\"启动\",{\"0\":{\"51\":1,\"124\":1},\"1\":{\"37\":1,\"51\":1}}],[\"版\",{\"1\":{\"119\":1}}],[\"版本前的内核的\",{\"1\":{\"113\":1}}],[\"版本为\",{\"1\":{\"95\":1}}],[\"版本\",{\"1\":{\"48\":1}}],[\"版权申诉相关问题请联系对应网站管理者\",{\"1\":{\"1\":1}}],[\"环境变量为\",{\"1\":{\"134\":1}}],[\"环境\",{\"1\":{\"47\":1}}],[\"切换存储后端时需要手动复制或移动原有文件\",{\"1\":{\"140\":1}}],[\"切换到新的环境\",{\"1\":{\"137\":1}}],[\"切换网络环境\",{\"1\":{\"47\":1}}],[\"切记\",{\"1\":{\"17\":1}}],[\"以方便做题者\",{\"1\":{\"199\":1}}],[\"以及\",{\"1\":{\"207\":1}}],[\"以及给领导展示\",{\"1\":{\"173\":1}}],[\"以及它们的变种\",{\"1\":{\"70\":1}}],[\"以上所有更改均会在重启\",{\"1\":{\"162\":1}}],[\"以上图片将在页面左上角\",{\"1\":{\"27\":1}}],[\"以上图片将在浏览器标签页图片上显示\",{\"1\":{\"27\":1}}],[\"以月为单位的整数\",{\"1\":{\"153\":1}}],[\"以此方式调用\",{\"1\":{\"135\":1}}],[\"以下日期排期仅供参考\",{\"1\":{\"171\":1}}],[\"以下仅为参考配置且配置补全\",{\"1\":{\"146\":1}}],[\"以下为样例\",{\"1\":{\"139\":1}}],[\"以下是一个例子\",{\"1\":{\"221\":1}}],[\"以下是常用编译器的示例\",{\"1\":{\"136\":1}}],[\"以下是\",{\"1\":{\"136\":1}}],[\"以下教程仅为示例\",{\"1\":{\"131\":1}}],[\"以下报错信息均为网络问题导致\",{\"1\":{\"47\":1}}],[\"以使得存在内存寻址错误的代码能够得到更多可重复的结果\",{\"1\":{\"112\":1}}],[\"以使插件生效\",{\"1\":{\"86\":1}}],[\"以\",{\"1\":{\"73\":1,\"113\":1,\"135\":1,\"142\":1,\"145\":1,\"167\":1,\"173\":1}}],[\"以启用位置在\",{\"1\":{\"50\":1}}],[\"以启用\",{\"1\":{\"50\":1}}],[\"需安装\",{\"1\":{\"85\":2}}],[\"需配合第三方软件使用\",{\"1\":{\"85\":1}}],[\"需重写代码\",{\"1\":{\"47\":1}}],[\"需要和评测机\",{\"1\":{\"222\":2}}],[\"需要用户有\",{\"1\":{\"185\":1}}],[\"需要填入下面的指令中\",{\"1\":{\"152\":1}}],[\"需要配置的内容较多\",{\"1\":{\"146\":1}}],[\"需要手动处理\",{\"1\":{\"115\":1,\"116\":1}}],[\"需要手动在服务器间同步数据\",{\"1\":{\"83\":1}}],[\"需要在\",{\"1\":{\"107\":1}}],[\"需要在后台运行并监听\",{\"1\":{\"95\":1}}],[\"需要在软件名或版本号中采用可识别的方式进行注明\",{\"1\":{\"3\":1}}],[\"需要ip库支持\",{\"1\":{\"85\":1}}],[\"需要登录\",{\"1\":{\"81\":1}}],[\"需要进行转换\",{\"1\":{\"77\":1}}],[\"需要使用以下端口\",{\"1\":{\"135\":1}}],[\"需要使用\",{\"1\":{\"73\":1,\"134\":1}}],[\"需要重定向到\",{\"1\":{\"73\":1}}],[\"需要更新的时候进入对应仓库文件夹执行\",{\"1\":{\"52\":1}}],[\"需要\",{\"1\":{\"48\":1,\"179\":2}}],[\"需要保留底部的\",{\"1\":{\"3\":1}}],[\"需要遵守以下额外条款\",{\"1\":{\"3\":1}}],[\"高亮讨论\",{\"1\":{\"179\":1}}],[\"高效\",{\"1\":{\"80\":1}}],[\"高\",{\"1\":{\"47\":1}}],[\"低\",{\"1\":{\"47\":1}}],[\"技能要求\",{\"1\":{\"47\":1}}],[\"技术支持\",{\"1\":{\"47\":1}}],[\"升级而来\",{\"1\":{\"118\":1}}],[\"升级\",{\"0\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1},\"1\":{\"47\":1,\"85\":1,\"95\":1}}],[\"性能优化\",{\"1\":{\"47\":1}}],[\"底层代码修改\",{\"1\":{\"47\":1}}],[\"❌\",{\"1\":{\"47\":6}}],[\"✅\",{\"1\":{\"47\":8}}],[\"功能代替\",{\"1\":{\"148\":1}}],[\"功能\",{\"1\":{\"81\":1}}],[\"功能对比\",{\"0\":{\"81\":1},\"1\":{\"47\":1}}],[\"功能强大且易于扩展\",{\"1\":{\"0\":1}}],[\"中存储附加文件\",{\"1\":{\"205\":1}}],[\"中为\",{\"1\":{\"205\":1}}],[\"中括号内的内容可以自己写\",{\"1\":{\"199\":1}}],[\"中体现\",{\"1\":{\"186\":1}}],[\"中题目的难度\",{\"1\":{\"177\":1}}],[\"中没有必要使用多进程启动\",{\"1\":{\"167\":1}}],[\"中搜索你需要的编译器\",{\"1\":{\"136\":1}}],[\"中数据库名为\",{\"1\":{\"118\":1}}],[\"中移除了精确计量内存消耗的接口\",{\"1\":{\"113\":1}}],[\"中添加下面这行并运行\",{\"1\":{\"112\":1}}],[\"中配置\",{\"1\":{\"107\":1,\"173\":1}}],[\"中修改\",{\"1\":{\"107\":2}}],[\"中有一栏\",{\"1\":{\"101\":1}}],[\"中查看并免费下载使用样例\",{\"1\":{\"81\":1}}],[\"中\",{\"1\":{\"78\":1,\"92\":1,\"111\":1,\"115\":2,\"116\":1,\"119\":1,\"162\":1}}],[\"中返回的\",{\"1\":{\"73\":1}}],[\"中找到各种类型题目的配置示例\",{\"1\":{\"222\":1}}],[\"中找到对应文件\",{\"1\":{\"162\":1}}],[\"中找到名为\",{\"1\":{\"115\":1,\"118\":1}}],[\"中找到\",{\"1\":{\"70\":1,\"85\":1}}],[\"中关于此部分的内容\",{\"1\":{\"46\":1}}],[\"中的管理员设定\",{\"1\":{\"183\":1}}],[\"中的内容\",{\"1\":{\"77\":1}}],[\"中的全部参数\",{\"1\":{\"77\":1}}],[\"中的大部分变量有固定命名规则\",{\"1\":{\"70\":1}}],[\"中的一个方法\",{\"1\":{\"68\":1}}],[\"中的\",{\"1\":{\"26\":1}}],[\"||\",{\"1\":{\"73\":1}}],[\"||t\",{\"1\":{\"30\":1}}],[\"|\",{\"1\":{\"46\":1,\"109\":1,\"214\":30}}],[\"应当新建一个用户组\",{\"1\":{\"194\":1}}],[\"应当提供\",{\"1\":{\"77\":1}}],[\"应用\",{\"1\":{\"112\":1}}],[\"应设置为\",{\"1\":{\"46\":1}}],[\"应该填英文逗号分隔的语言id\",{\"1\":{\"35\":1}}],[\"例子如下\",{\"1\":{\"203\":1}}],[\"例题网址\",{\"1\":{\"200\":2,\"201\":1,\"202\":1,\"203\":1}}],[\"例如\",{\"1\":{\"194\":1}}],[\"例\",{\"1\":{\"46\":1,\"86\":1,\"110\":1,\"222\":1}}],[\"其格式如下\",{\"1\":{\"190\":1}}],[\"其所在行而非整个文件\",{\"1\":{\"161\":1}}],[\"其他工具请在使用工具前先配置好系统设置\",{\"1\":{\"139\":1}}],[\"其他字段均为可选\",{\"1\":{\"45\":1}}],[\"其参数格式如下\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"其中章节一\",{\"1\":{\"190\":1}}],[\"其中\",{\"1\":{\"190\":1,\"205\":1}}],[\"其中包含了一个或多个\",{\"1\":{\"92\":1}}],[\"其中的\",{\"1\":{\"3\":1}}],[\"除一键安装脚本在安装\",{\"1\":{\"139\":1}}],[\"除用户\",{\"1\":{\"83\":1}}],[\"除\",{\"1\":{\"45\":1}}],[\"除非得到许可\",{\"1\":{\"3\":1}}],[\"kotlin\",{\"1\":{\"132\":2}}],[\"kv\",{\"1\":{\"124\":4}}],[\"kb\",{\"1\":{\"45\":1}}],[\"keep\",{\"1\":{\"139\":1}}],[\"kernel\",{\"1\":{\"41\":1,\"112\":1,\"113\":1}}],[\"key\",{\"1\":{\"41\":2,\"45\":3,\"119\":1,\"153\":1}}],[\"或使用subtask项\",{\"1\":{\"222\":1}}],[\"或者实现头文件里指定的函数\",{\"1\":{\"199\":1}}],[\"或者使用的为非\",{\"1\":{\"95\":1}}],[\"或者\",{\"1\":{\"86\":1,\"115\":1}}],[\"或是不同功能\",{\"1\":{\"185\":1}}],[\"或是\",{\"1\":{\"141\":1,\"147\":1,\"153\":1}}],[\"或是部分更新操作\",{\"1\":{\"77\":1}}],[\"或是修改时间的时间戳\",{\"1\":{\"43\":1}}],[\"或\",{\"1\":{\"48\":1,\"80\":1,\"118\":1,\"163\":1,\"186\":3,\"189\":2}}],[\"或联系开发组说明\",{\"1\":{\"0\":1}}],[\"用来对付部分\",{\"1\":{\"214\":1}}],[\"用来指定测试用例\",{\"1\":{\"204\":1}}],[\"用来指定自定义的测试程序\",{\"1\":{\"204\":1}}],[\"用来指定前置子任务\",{\"1\":{\"202\":1}}],[\"用来说明测试的类型\",{\"1\":{\"197\":1}}],[\"用来识别本地缓存的文件是否与云端一致\",{\"1\":{\"43\":1}}],[\"用\",{\"1\":{\"147\":1,\"163\":2,\"166\":1}}],[\"用于监测服务器运行状态\",{\"1\":{\"173\":1}}],[\"用于统一监测服务器状态\",{\"1\":{\"172\":1}}],[\"用于提供多国翻译\",{\"1\":{\"79\":1}}],[\"用于提交队列等\",{\"1\":{\"61\":1}}],[\"用于记录用户的访问情况\",{\"1\":{\"64\":1}}],[\"用于处理\",{\"1\":{\"62\":1}}],[\"用户程序的最后输出将作为本程序的输入\",{\"1\":{\"200\":1}}],[\"用户通过某种方式自助将自己的权限组由\",{\"1\":{\"195\":1}}],[\"用户可以创建多个域\",{\"1\":{\"185\":1}}],[\"用户文档\",{\"0\":{\"176\":1}}],[\"用户不可重新登录\",{\"1\":{\"173\":1}}],[\"用户创建后无法删除\",{\"1\":{\"163\":1}}],[\"用户信息\",{\"1\":{\"163\":1}}],[\"用户封禁\",{\"1\":{\"153\":1}}],[\"用户名\",{\"1\":{\"163\":1}}],[\"用户名和密码\",{\"1\":{\"148\":1}}],[\"用户名为\",{\"0\":{\"26\":1},\"1\":{\"26\":1,\"148\":1,\"154\":1}}],[\"用户执行\",{\"1\":{\"147\":1}}],[\"用户执行如下命令\",{\"1\":{\"122\":1,\"123\":1}}],[\"用户大部分可直接切换至\",{\"1\":{\"141\":1}}],[\"用户请根据自己的情况替换掉用\",{\"1\":{\"147\":1}}],[\"用户请注意\",{\"1\":{\"134\":1}}],[\"用户请在此处填写\",{\"1\":{\"98\":1}}],[\"用户\",{\"1\":{\"25\":1}}],[\"用户注册由\",{\"1\":{\"25\":1}}],[\"用户qq群\",{\"0\":{\"8\":1}}],[\"用户群\",{\"1\":{\"1\":1}}],[\"字母+数字\",{\"1\":{\"205\":1}}],[\"字段使用下划线\",{\"1\":{\"77\":1}}],[\"字段\",{\"1\":{\"77\":1}}],[\"字段区分文档类型\",{\"1\":{\"54\":1}}],[\"字段包含且仅包含一个字符\",{\"1\":{\"43\":1}}],[\"字段的提交使用相同的缓存目录\",{\"1\":{\"43\":1}}],[\"字段为缓存\",{\"1\":{\"43\":1}}],[\"字段值作为程序输入\",{\"1\":{\"43\":1}}],[\"字样需指向\",{\"1\":{\"3\":1}}],[\"字样\",{\"1\":{\"3\":1}}],[\"自动识别支持以下命名方式\",{\"1\":{\"222\":1}}],[\"自动模式\",{\"0\":{\"221\":1}}],[\"自动生成两个随机整数\",{\"1\":{\"200\":1}}],[\"自行摸索并确保在网络通畅的环境下使用\",{\"1\":{\"210\":1}}],[\"自行创建等\",{\"1\":{\"86\":1}}],[\"自己指定评测程序并修改测试输出格式\",{\"0\":{\"200\":1}}],[\"自己看不懂解法的题目\",{\"1\":{\"17\":1}}],[\"自带的\",{\"1\":{\"158\":1,\"159\":1}}],[\"自定\",{\"1\":{\"80\":1}}],[\"自测提交使用\",{\"1\":{\"43\":1}}],[\"向评测端推送评测任务\",{\"1\":{\"43\":1}}],[\"分隔\",{\"1\":{\"163\":2}}],[\"分别表示取所有测试点最小值\",{\"1\":{\"222\":1}}],[\"分别表示选择对应的语言后的高亮设置\",{\"1\":{\"107\":1}}],[\"分别为\",{\"1\":{\"163\":1,\"191\":1,\"199\":1}}],[\"分别对应反向代理所添加的标头名\",{\"1\":{\"139\":1}}],[\"分析\",{\"1\":{\"77\":1}}],[\"分发服务端的语言设置\",{\"1\":{\"42\":1}}],[\"分辨率应尽可能对应\",{\"1\":{\"27\":1}}],[\"端新建一个打印机\",{\"1\":{\"173\":1}}],[\"端点将不可用\",{\"1\":{\"141\":1}}],[\"端可进行\",{\"1\":{\"45\":1}}],[\"端会通过\",{\"1\":{\"43\":1}}],[\"端会向\",{\"1\":{\"42\":1,\"44\":1}}],[\"端口映射\",{\"1\":{\"135\":1}}],[\"端口访问到\",{\"1\":{\"51\":1}}],[\"端口\",{\"1\":{\"12\":1,\"139\":1}}],[\"建议文件名格式为\",{\"1\":{\"202\":1}}],[\"建议通过\",{\"1\":{\"148\":1}}],[\"建议复制防止敲错\",{\"1\":{\"135\":1}}],[\"建议重装为其他操作系统\",{\"1\":{\"134\":1}}],[\"建议使用\",{\"1\":{\"43\":1,\"134\":1}}],[\"建议您停止使用本项目\",{\"1\":{\"3\":1}}],[\"建立连接后每隔\",{\"1\":{\"41\":1}}],[\"汇报当前节点状态\",{\"1\":{\"41\":1}}],[\"当比较器类型不为\",{\"1\":{\"222\":1}}],[\"当程序有错误时\",{\"1\":{\"200\":1}}],[\"当然\",{\"1\":{\"199\":1}}],[\"当你改动一个字段的时候\",{\"1\":{\"156\":1}}],[\"当脚本运行完成后\",{\"1\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"当您的评测使用文件\",{\"1\":{\"109\":1}}],[\"当前所用系统\",{\"1\":{\"83\":1}}],[\"当前版本\",{\"1\":{\"39\":1}}],[\"当提交表单并存在\",{\"1\":{\"77\":1}}],[\"当用户在三方系统中完成授权\",{\"1\":{\"73\":1}}],[\"当用户点击\",{\"1\":{\"73\":1}}],[\"当\",{\"1\":{\"45\":1}}],[\"当重分发经修改后的本软件时\",{\"1\":{\"3\":1}}],[\"推荐您通过\",{\"1\":{\"222\":1}}],[\"推荐您使用\",{\"1\":{\"139\":1}}],[\"推荐七天\",{\"1\":{\"172\":1}}],[\"推荐启用\",{\"1\":{\"113\":1}}],[\"推荐使用\",{\"1\":{\"48\":1,\"134\":1,\"172\":1}}],[\"推荐\",{\"1\":{\"37\":1}}],[\"推荐直接使用在线服务\",{\"1\":{\"9\":1}}],[\"通过算法计算得出\",{\"1\":{\"177\":1}}],[\"通过率以及每个递交的递交时间和评测结果\",{\"1\":{\"177\":1}}],[\"通过域功能\",{\"1\":{\"83\":1}}],[\"通过在内网架设代理服务器\",{\"1\":{\"37\":1}}],[\"通常情况下\",{\"1\":{\"194\":1}}],[\"通常情况下您仅需设置资源\",{\"1\":{\"144\":1}}],[\"通常我们需要给特定的一组用户分配相同的权限\",{\"1\":{\"194\":1}}],[\"通常比赛的前一小时气球组会非常忙\",{\"1\":{\"175\":1}}],[\"通常的\",{\"1\":{\"162\":1}}],[\"通常为\",{\"1\":{\"139\":1,\"159\":1}}],[\"通常为其\",{\"1\":{\"1\":1}}],[\"通常用于存放图片\",{\"1\":{\"205\":1}}],[\"通常用于\",{\"1\":{\"77\":1}}],[\"通常每六小时执行一次\",{\"1\":{\"40\":1}}],[\"大师\",{\"1\":{\"190\":1}}],[\"大部分虚拟机软件默认没有启用\",{\"1\":{\"134\":1}}],[\"大部分插件的配置均可在安装后于\",{\"1\":{\"85\":1}}],[\"大量用户同\",{\"0\":{\"37\":1}}],[\"大系统备份应该有上百兆\",{\"1\":{\"21\":1}}],[\"编写的说明\",{\"1\":{\"207\":1}}],[\"编写一个样本程序\",{\"1\":{\"200\":1}}],[\"编写插件上传到服务器\",{\"1\":{\"76\":1}}],[\"编写插件\",{\"0\":{\"67\":1,\"74\":1},\"1\":{\"47\":1,\"67\":1}}],[\"编码\",{\"1\":{\"92\":1,\"163\":1}}],[\"编辑系统设置\",{\"1\":{\"192\":1}}],[\"编辑\",{\"0\":{\"213\":1},\"1\":{\"109\":1,\"113\":1,\"198\":1}}],[\"编辑器语法规则设置\",{\"1\":{\"107\":1}}],[\"编辑器提供的代码补全可以很大程度简化开发流程\",{\"1\":{\"76\":1}}],[\"编辑域资料\",{\"1\":{\"35\":1}}],[\"编译命令后加上\",{\"1\":{\"110\":1}}],[\"编译前端\",{\"1\":{\"49\":1}}],[\"编译器名\",{\"1\":{\"136\":2}}],[\"编译器\",{\"0\":{\"136\":1},\"1\":{\"23\":1,\"32\":1,\"95\":1}}],[\"编译错误\",{\"1\":{\"10\":1}}],[\"编译错误发生时\",{\"1\":{\"10\":1}}],[\"脚本默认使用的为清华大学镜像\",{\"1\":{\"135\":1}}],[\"脚本安装默认只装了一小部分编译器\",{\"1\":{\"32\":1}}],[\"脚本把\",{\"0\":{\"21\":1}}],[\"给我发个红包\",{\"1\":{\"31\":1}}],[\"给学生的程序\",{\"1\":{\"10\":1}}],[\"我的域\",{\"1\":{\"186\":2}}],[\"我的\",{\"1\":{\"186\":1}}],[\"我们假定题目内容均为下面的markdown文档\",{\"1\":{\"197\":1}}],[\"我们不建议使用\",{\"1\":{\"141\":1}}],[\"我们建议使用编写单独的\",{\"1\":{\"137\":1}}],[\"我们采用\",{\"1\":{\"119\":1}}],[\"我们仍不建议您导入过大的题目包\",{\"1\":{\"92\":1}}],[\"我们也推荐这么做\",{\"1\":{\"76\":1}}],[\"我们是\",{\"1\":{\"31\":1}}],[\"我是机房用户\",{\"0\":{\"37\":1}}],[\"我想让\",{\"0\":{\"23\":1}}],[\"4等等\",{\"1\":{\"197\":1}}],[\"465\",{\"1\":{\"142\":1}}],[\"49\",{\"1\":{\"132\":3}}],[\"41\",{\"1\":{\"132\":2}}],[\"40\",{\"1\":{\"132\":2}}],[\"48\",{\"1\":{\"132\":2}}],[\"436\",{\"1\":{\"214\":1}}],[\"43\",{\"1\":{\"132\":2}}],[\"4\",{\"1\":{\"75\":1,\"81\":1,\"124\":1,\"132\":7,\"202\":11,\"214\":2}}],[\"45\",{\"1\":{\"30\":1}}],[\"443\",{\"1\":{\"12\":1,\"135\":1,\"139\":1}}],[\"96243\",{\"1\":{\"214\":1}}],[\"96x96\",{\"1\":{\"27\":1}}],[\"98\",{\"1\":{\"196\":1,\"198\":1,\"199\":1,\"200\":2,\"201\":1,\"203\":1}}],[\"9000\",{\"1\":{\"141\":1}}],[\"900\",{\"1\":{\"124\":1}}],[\"9\",{\"1\":{\"81\":1,\"132\":4,\"222\":2}}],[\"999\",{\"1\":{\"37\":1}}],[\"99\",{\"1\":{\"30\":1}}],[\"za\",{\"1\":{\"222\":1}}],[\"zoho\",{\"1\":{\"142\":1}}],[\"zeptomail\",{\"1\":{\"142\":1}}],[\"zh\",{\"1\":{\"73\":1,\"161\":3,\"197\":1,\"205\":3,\"214\":1}}],[\"z+\",{\"1\":{\"30\":1}}],[\"zindex\",{\"1\":{\"30\":1}}],[\"zip\",{\"1\":{\"14\":1,\"80\":1,\"92\":1,\"137\":1,\"205\":1,\"221\":1}}],[\"z\",{\"1\":{\"30\":2,\"222\":1}}],[\"29985091\",{\"1\":{\"196\":1}}],[\"27\",{\"0\":{\"139\":1}}],[\"27017\",{\"1\":{\"118\":1,\"135\":1}}],[\"28\",{\"1\":{\"132\":2}}],[\"256m\",{\"1\":{\"222\":1}}],[\"256mb\",{\"1\":{\"221\":1}}],[\"250000\",{\"1\":{\"124\":1}}],[\"25189552128\",{\"1\":{\"41\":1}}],[\"241\",{\"1\":{\"132\":1}}],[\"24\",{\"1\":{\"68\":1}}],[\"24529293328\",{\"1\":{\"41\":1}}],[\"2g\",{\"1\":{\"47\":1,\"134\":1}}],[\"222\",{\"1\":{\"196\":1,\"198\":1,\"199\":1,\"200\":2,\"201\":1,\"203\":1}}],[\"22\",{\"1\":{\"41\":1,\"75\":1,\"134\":2}}],[\"262144\",{\"1\":{\"41\":1}}],[\"23636676608\",{\"1\":{\"41\":1}}],[\"2e4\",{\"1\":{\"30\":1}}],[\"2d\",{\"1\":{\"30\":1}}],[\"2+m\",{\"1\":{\"30\":1}}],[\"2\",{\"0\":{\"36\":1,\"175\":1},\"1\":{\"30\":2,\"41\":3,\"81\":1,\"106\":1,\"113\":2,\"124\":1,\"132\":8,\"135\":1,\"148\":3,\"149\":2,\"190\":4,\"197\":1,\"198\":1,\"202\":12,\"203\":4,\"214\":5,\"218\":2,\"219\":2,\"222\":2}}],[\"2019\",{\"1\":{\"135\":1}}],[\"2017\",{\"1\":{\"132\":1}}],[\"2048\",{\"1\":{\"124\":1}}],[\"20\",{\"1\":{\"124\":1,\"132\":3,\"202\":5,\"203\":1,\"219\":1}}],[\"2021\",{\"1\":{\"134\":1}}],[\"2023\",{\"1\":{\"43\":1}}],[\"2022\",{\"0\":{\"139\":1},\"1\":{\"23\":1,\"109\":2,\"111\":1,\"136\":1,\"196\":1}}],[\"20分钟\",{\"1\":{\"20\":1}}],[\"5s\",{\"1\":{\"222\":2}}],[\"587\",{\"1\":{\"142\":1}}],[\"55\",{\"1\":{\"132\":2}}],[\"51\",{\"1\":{\"132\":2}}],[\"59\",{\"1\":{\"132\":2}}],[\"54\",{\"1\":{\"132\":2}}],[\"500\",{\"1\":{\"197\":1}}],[\"50\",{\"1\":{\"132\":2,\"203\":1,\"219\":1,\"222\":1}}],[\"5050\",{\"1\":{\"95\":1,\"135\":1}}],[\"52\",{\"1\":{\"132\":2}}],[\"535z\",{\"1\":{\"43\":1}}],[\"57\",{\"1\":{\"43\":1}}],[\"5\",{\"1\":{\"30\":3,\"41\":2,\"68\":1,\"81\":1,\"113\":2,\"124\":1,\"132\":2,\"198\":1,\"202\":10,\"214\":3,\"222\":1}}],[\"x+y\",{\"1\":{\"199\":1}}],[\"x+=e\",{\"1\":{\"30\":1}}],[\"xcpc\",{\"1\":{\"173\":4}}],[\"xhost\",{\"1\":{\"139\":2}}],[\"xff\",{\"1\":{\"139\":2,\"146\":1}}],[\"xml\",{\"1\":{\"92\":3}}],[\"x64\",{\"1\":{\"41\":1}}],[\"xeon®\",{\"1\":{\"41\":1}}],[\"x=null\",{\"1\":{\"30\":1}}],[\"x=e\",{\"1\":{\"30\":1}}],[\"x=\",{\"1\":{\"30\":1}}],[\"x\",{\"0\":{\"36\":1},\"1\":{\"30\":10,\"137\":1,\"139\":4,\"146\":2,\"199\":2,\"202\":2}}],[\"x<0\",{\"1\":{\"30\":1}}],[\"x>l||e\",{\"1\":{\"30\":1}}],[\"xa\",{\"1\":{\"30\":3}}],[\"xx云\",{\"1\":{\"135\":1}}],[\"xx\",{\"1\":{\"19\":1,\"73\":1}}],[\"xxx\",{\"1\":{\"3\":1,\"14\":1,\"73\":1,\"86\":1,\"153\":6,\"162\":1,\"197\":1}}],[\"vlc\",{\"1\":{\"172\":1}}],[\"v8\",{\"1\":{\"132\":1}}],[\"v3\",{\"1\":{\"119\":1}}],[\"v3+json\",{\"1\":{\"73\":1}}],[\"v2\",{\"1\":{\"113\":1,\"132\":1}}],[\"vj2\",{\"1\":{\"118\":1}}],[\"vj4\",{\"1\":{\"98\":2,\"118\":9}}],[\"vjudge\",{\"0\":{\"131\":1},\"1\":{\"85\":1,\"131\":1,\"132\":1}}],[\"view\",{\"1\":{\"162\":2,\"193\":1}}],[\"viewer\",{\"1\":{\"92\":1}}],[\"visual\",{\"1\":{\"132\":1}}],[\"vijos4\",{\"1\":{\"85\":1}}],[\"vijos\",{\"0\":{\"118\":1},\"1\":{\"4\":1,\"80\":1,\"81\":1}}],[\"vscode\",{\"1\":{\"76\":1}}],[\"version\",{\"1\":{\"75\":1,\"222\":1}}],[\"verified\",{\"1\":{\"73\":1}}],[\"vendor\",{\"1\":{\"41\":1}}],[\"vnd\",{\"1\":{\"73\":1}}],[\"va\",{\"1\":{\"112\":1}}],[\"valeriansaliou\",{\"1\":{\"124\":1}}],[\"value=\",{\"1\":{\"77\":1}}],[\"validationerror\",{\"1\":{\"73\":2}}],[\"var\",{\"1\":{\"30\":4}}],[\"vme\",{\"1\":{\"41\":1}}],[\"v1\",{\"1\":{\"39\":1,\"75\":1,\"113\":2}}],[\"v\",{\"1\":{\"30\":1}}],[\"v=2\",{\"1\":{\"30\":1}}],[\"when\",{\"1\":{\"214\":1}}],[\"we\",{\"1\":{\"222\":1}}],[\"welcome\",{\"1\":{\"141\":1}}],[\"web\",{\"1\":{\"41\":1,\"42\":1,\"43\":1,\"44\":1,\"45\":1,\"115\":1,\"154\":1}}],[\"websocket\",{\"0\":{\"41\":1},\"1\":{\"40\":1,\"41\":1,\"43\":1,\"139\":1}}],[\"webkitrequestanimationframe||window\",{\"1\":{\"30\":1}}],[\"write\",{\"1\":{\"124\":2}}],[\"working\",{\"1\":{\"222\":1}}],[\"workspace\",{\"1\":{\"75\":1}}],[\"words\",{\"1\":{\"124\":1}}],[\"word\",{\"1\":{\"124\":1,\"214\":1}}],[\"www\",{\"1\":{\"119\":1}}],[\"wa\",{\"1\":{\"200\":2}}],[\"wall\",{\"1\":{\"110\":1}}],[\"watch\",{\"1\":{\"51\":2}}],[\"warning\",{\"1\":{\"28\":1,\"84\":1,\"109\":1,\"115\":1,\"118\":2,\"131\":1,\"134\":1,\"139\":1,\"141\":1,\"146\":1,\"156\":1,\"163\":1}}],[\"wsl2\",{\"1\":{\"48\":1}}],[\"will\",{\"1\":{\"222\":2}}],[\"without\",{\"1\":{\"113\":1}}],[\"with\",{\"1\":{\"72\":2,\"73\":9,\"85\":2,\"137\":1}}],[\"withhandlerclass\",{\"1\":{\"68\":1}}],[\"windows\",{\"1\":{\"48\":1}}],[\"window\",{\"1\":{\"30\":4}}],[\"width=window\",{\"1\":{\"30\":1}}],[\"w=window\",{\"1\":{\"30\":1}}],[\"w\",{\"1\":{\"30\":1}}],[\"\",{\"1\":{\"30\":1}}],[\"<数字>\",{\"1\":{\"202\":1}}],[\"\",{\"1\":{\"201\":1}}],[\"\",{\"1\":{\"167\":1}}],[\"\",{\"1\":{\"166\":1}}],[\"\",{\"1\":{\"137\":1}}],[\"\",{\"1\":{\"157\":1}}],[\"\",{\"1\":{\"154\":2}}],[\"\",{\"1\":{\"154\":4,\"209\":2}}],[\"\",{\"1\":{\"153\":6,\"154\":2}}],[\"\",{\"1\":{\"150\":1,\"154\":2}}],[\"\",{\"1\":{\"148\":1,\"151\":1,\"154\":4}}],[\"\",{\"1\":{\"154\":1}}],[\"\",{\"1\":{\"154\":3}}],[\"\",{\"1\":{\"148\":1,\"149\":1,\"150\":1,\"151\":1,\"152\":1,\"153\":1,\"154\":10}}],[\"\",{\"1\":{\"148\":1}}],[\"\",{\"1\":{\"148\":1,\"154\":4}}],[\"<>\",{\"1\":{\"147\":2}}],[\"<存储桶>\",{\"1\":{\"141\":2}}],[\"<存储桶名称>\",{\"1\":{\"141\":1}}],[\"<存储桶地域>\",{\"1\":{\"141\":3}}],[\"<=2gib\",{\"1\":{\"134\":1}}],[\"\",{\"1\":{\"198\":1,\"200\":2}}],[\"\",{\"1\":{\"166\":1,\"167\":5,\"189\":2,\"190\":1}}],[\" \",{\"1\":{\"33\":1}}],[\"<用户\",{\"1\":{\"33\":1}}],[\"<\",{\"1\":{\"30\":1,\"48\":1,\"68\":1,\"98\":1,\"135\":2}}],[\"\",{\"1\":{\"30\":1,\"68\":2,\"73\":1}}],[\"=\",{\"1\":{\"20\":1,\"30\":2,\"47\":2,\"68\":3,\"73\":7,\"77\":12,\"81\":7,\"112\":1,\"124\":25,\"137\":6,\"200\":8,\"203\":1,\"218\":1}}],[\"惩罚时间\",{\"1\":{\"20\":2}}],[\"+x\",{\"1\":{\"30\":4}}],[\"+\",{\"1\":{\"20\":1,\"30\":2,\"81\":25,\"200\":4,\"222\":2}}],[\"花费\",{\"1\":{\"20\":2}}],[\"号<\",{\"1\":{\"19\":1}}],[\"备份完成后会在当前目录生成备份压缩包文件\",{\"1\":{\"157\":1}}],[\"备份文件一定要解压查看内部是否包含全部数据\",{\"1\":{\"21\":1}}],[\"备\",{\"1\":{\"19\":1}}],[\"权限在系统内部使用位运算表示\",{\"1\":{\"191\":1}}],[\"权限后并不会显示在\",{\"1\":{\"188\":1}}],[\"权限为\",{\"1\":{\"154\":1}}],[\"权限下进行\",{\"1\":{\"135\":1}}],[\"权限的账户\",{\"1\":{\"98\":1}}],[\"权限运行\",{\"1\":{\"95\":1}}],[\"权限系统\",{\"0\":{\"191\":1},\"1\":{\"81\":1}}],[\"权限结构\",{\"1\":{\"46\":1}}],[\"权限\",{\"1\":{\"46\":1,\"179\":2,\"185\":1,\"188\":2,\"192\":1}}],[\"权限节点\",{\"0\":{\"46\":1}}],[\"权限控制\",{\"1\":{\"25\":1}}],[\"权限禁用\",{\"1\":{\"18\":1}}],[\"权限组的\",{\"1\":{\"18\":1}}],[\"将通过扩展名识别语言\",{\"1\":{\"222\":1}}],[\"将被渲染为\",{\"1\":{\"214\":1}}],[\"将自动合并\",{\"1\":{\"214\":1}}],[\"将会自动进行解压操作\",{\"1\":{\"221\":1}}],[\"将会自动识别并提供切换功能\",{\"1\":{\"205\":1}}],[\"将会在\",{\"1\":{\"186\":1}}],[\"将会在域\",{\"1\":{\"186\":1}}],[\"将角色移出域和将用户的角色设置为\",{\"1\":{\"194\":1}}],[\"将停止更新\",{\"1\":{\"178\":1,\"180\":1}}],[\"将文件的全部内容\",{\"1\":{\"162\":1}}],[\"将其中\",{\"1\":{\"137\":1}}],[\"将首个注册用户设置为超级管理员\",{\"1\":{\"135\":1}}],[\"将如下配置添加至\",{\"1\":{\"132\":1}}],[\"将数据库映射至其他本机端口\",{\"1\":{\"118\":1}}],[\"将它勾上\",{\"1\":{\"101\":1}}],[\"将用户重定向到创建完成的url\",{\"1\":{\"77\":1}}],[\"将用户重定向至第三方平台请求授权\",{\"1\":{\"73\":1}}],[\"将本地的文件夹上传至服务器\",{\"1\":{\"76\":1}}],[\"将内网\",{\"1\":{\"37\":1}}],[\"将您的站点图标放置于该文件夹下\",{\"1\":{\"27\":1}}],[\"将\",{\"1\":{\"18\":1,\"28\":1,\"109\":1,\"110\":1,\"132\":1,\"153\":2,\"154\":7,\"209\":1}}],[\"管理用户\",{\"1\":{\"188\":1}}],[\"管理环境\",{\"1\":{\"136\":1}}],[\"管理\",{\"1\":{\"98\":1}}],[\"管理员可以修改导入文件大小限制\",{\"1\":{\"92\":1}}],[\"管理员二元化权限之外的\",{\"1\":{\"83\":1}}],[\"管理逻辑简洁\",{\"1\":{\"80\":1}}],[\"管理权限\",{\"1\":{\"18\":1}}],[\"管理域\",{\"1\":{\"18\":1,\"187\":1}}],[\">foo<\",{\"1\":{\"214\":1}}],[\">>\",{\"1\":{\"200\":1}}],[\">$out\",{\"1\":{\"137\":2}}],[\">=18\",{\"1\":{\"48\":1}}],[\">xx\",{\"1\":{\"19\":1}}],[\">\",{\"1\":{\"18\":1,\"33\":2,\"35\":4,\"77\":5,\"162\":1,\"209\":1}}],[\"慎用\",{\"1\":{\"17\":1}}],[\"少用\",{\"1\":{\"17\":1}}],[\"怎么解决\",{\"0\":{\"37\":1}}],[\"怎么自定义用户标签\",{\"0\":{\"33\":1}}],[\"怎么办\",{\"0\":{\"23\":1}}],[\"怎么添加页脚备案号\",{\"0\":{\"19\":1}}],[\"怎么导入题目\",{\"0\":{\"17\":1}}],[\"怎么备份\",{\"0\":{\"14\":1}}],[\"随时加官方群咨询群主\",{\"1\":{\"16\":1}}],[\"没有的自行建立\",{\"1\":{\"124\":1}}],[\"没有看到报错并看到了\",{\"1\":{\"16\":1}}],[\"没有删除功能\",{\"1\":{\"9\":1}}],[\"然后点确定\",{\"1\":{\"198\":1}}],[\"然后点创建按钮\",{\"1\":{\"198\":1}}],[\"然后批量上传的话\",{\"1\":{\"197\":1}}],[\"然后给予该账号评测权限\",{\"1\":{\"152\":1}}],[\"然后修改第\",{\"1\":{\"109\":1}}],[\"然后重启\",{\"1\":{\"101\":1,\"105\":1}}],[\"然后重新启动\",{\"1\":{\"113\":1}}],[\"然后重新\",{\"1\":{\"52\":1}}],[\"然后在运行评测机的服务器上安装\",{\"1\":{\"98\":1}}],[\"然后在脚本管理中找到重建题目索引\",{\"1\":{\"90\":1}}],[\"然后\",{\"1\":{\"16\":1}}],[\"然后按空格选中除\",{\"1\":{\"16\":1}}],[\"回车确认\",{\"1\":{\"16\":1}}],[\"ghi\",{\"1\":{\"222\":1}}],[\"ghc\",{\"1\":{\"132\":1,\"136\":1}}],[\"gif\",{\"1\":{\"146\":1}}],[\"git\",{\"1\":{\"49\":2,\"52\":1,\"75\":1}}],[\"gitpod\",{\"1\":{\"0\":1}}],[\"github\",{\"1\":{\"0\":1,\"4\":1,\"30\":1,\"49\":1,\"72\":1,\"73\":18,\"75\":1,\"85\":2,\"124\":1,\"173\":1,\"186\":1}}],[\"gmail\",{\"1\":{\"142\":1}}],[\"guide\",{\"1\":{\"137\":1,\"214\":1}}],[\"guest\",{\"1\":{\"18\":1,\"25\":1,\"188\":1,\"194\":1,\"195\":1}}],[\"garbage\",{\"1\":{\"137\":1,\"170\":1}}],[\"g++17\",{\"1\":{\"132\":2}}],[\"g++14\",{\"1\":{\"132\":1}}],[\"gnu\",{\"1\":{\"132\":4}}],[\"gravatar\",{\"1\":{\"186\":1}}],[\"grafana\",{\"1\":{\"173\":1}}],[\"graph\",{\"1\":{\"124\":1}}],[\"group\",{\"1\":{\"163\":1}}],[\"grub\",{\"1\":{\"113\":6}}],[\"grep\",{\"1\":{\"109\":1}}],[\"gcc\",{\"1\":{\"110\":1,\"132\":1,\"136\":1,\"137\":1}}],[\"golang\",{\"1\":{\"136\":1}}],[\"go\",{\"1\":{\"95\":3,\"132\":2,\"136\":1}}],[\"google\",{\"1\":{\"72\":1,\"85\":2,\"119\":1}}],[\"gov\",{\"1\":{\"19\":1}}],[\"generated\",{\"1\":{\"200\":2}}],[\"generic\",{\"1\":{\"41\":1}}],[\"geolite2\",{\"1\":{\"93\":1}}],[\"geoip\",{\"0\":{\"93\":1},\"1\":{\"85\":1,\"86\":3,\"89\":2}}],[\"get请求时触发该函数\",{\"1\":{\"77\":1}}],[\"getmany\",{\"1\":{\"73\":1}}],[\"getmulti\",{\"1\":{\"71\":1}}],[\"getlist\",{\"1\":{\"71\":1}}],[\"getannounce\",{\"1\":{\"68\":3}}],[\"getattribute\",{\"1\":{\"30\":1}}],[\"gettimestamp\",{\"1\":{\"68\":1}}],[\"get\",{\"1\":{\"40\":1,\"68\":3,\"71\":1,\"73\":5,\"77\":8,\"153\":1}}],[\"getelementsbyclassname\",{\"1\":{\"30\":1}}],[\"getelementsbytagname\",{\"1\":{\"30\":1}}],[\"getcontext\",{\"1\":{\"30\":1}}],[\"g\",{\"1\":{\"30\":1,\"48\":1}}],[\"g=m\",{\"1\":{\"30\":1}}],[\"global\",{\"0\":{\"36\":1},\"1\":{\"16\":1,\"21\":1,\"77\":2,\"86\":1,\"88\":1,\"89\":1,\"97\":1,\"99\":1,\"103\":1,\"123\":1,\"168\":1,\"169\":1}}],[\"后接的数字为测试点编号\",{\"1\":{\"214\":1}}],[\"后将自动跳转到复制后的题目连接\",{\"1\":{\"182\":1}}],[\"后台所见座位号应当同步刷新\",{\"1\":{\"173\":1}}],[\"后文的指令中将用\",{\"1\":{\"166\":1}}],[\"后生效\",{\"1\":{\"162\":1}}],[\"后进入\",{\"1\":{\"141\":1}}],[\"后会自动配置设置项\",{\"1\":{\"139\":1}}],[\"后续若需更改环境配置\",{\"1\":{\"137\":1}}],[\"后续不会为安全漏洞发布补丁\",{\"1\":{\"134\":1}}],[\"后使用脚本安装的实例已自动配置\",{\"0\":{\"139\":1}}],[\"后使用\",{\"1\":{\"136\":1}}],[\"后重启沙箱\",{\"1\":{\"136\":1}}],[\"后端地址\",{\"1\":{\"126\":1}}],[\"后端地址配置\",{\"0\":{\"126\":1}}],[\"后端热重载可能存在\",{\"1\":{\"51\":1}}],[\"后安装的实例默认已开启无限栈空间\",{\"1\":{\"111\":1}}],[\"后安装的用户\",{\"1\":{\"109\":1}}],[\"后安装\",{\"1\":{\"90\":1}}],[\"后\",{\"1\":{\"23\":1,\"97\":1,\"113\":1,\"119\":1}}],[\"后手动删除\",{\"1\":{\"15\":1}}],[\"后再试\",{\"1\":{\"11\":1}}],[\"smtp\",{\"0\":{\"142\":1},\"1\":{\"142\":8}}],[\"ssl\",{\"0\":{\"138\":1}}],[\"sonic\",{\"0\":{\"120\":1,\"123\":1},\"1\":{\"85\":3,\"122\":1,\"123\":2,\"124\":7,\"126\":1}}],[\"source\",{\"1\":{\"43\":5,\"162\":2}}],[\"s3\",{\"0\":{\"141\":1},\"1\":{\"81\":1,\"83\":2,\"141\":2}}],[\"sys\",{\"1\":{\"113\":1}}],[\"sysctl\",{\"1\":{\"112\":2}}],[\"systemd\",{\"1\":{\"95\":1,\"113\":2}}],[\"systemkeys\",{\"1\":{\"73\":1}}],[\"systemmodel\",{\"1\":{\"73\":3}}],[\"system\",{\"0\":{\"60\":1,\"223\":1},\"1\":{\"37\":1,\"46\":1,\"81\":1,\"115\":2,\"116\":2,\"137\":3,\"154\":1,\"202\":1}}],[\"syzoj无需\",{\"1\":{\"116\":1}}],[\"syzoj\",{\"0\":{\"116\":1,\"210\":1},\"1\":{\"80\":1,\"81\":3,\"83\":3,\"85\":1,\"116\":5,\"210\":2,\"222\":1}}],[\"span>\",{\"1\":{\"214\":1}}],[\"space\",{\"1\":{\"112\":1}}],[\"splash\",{\"1\":{\"113\":2}}],[\"spoj\",{\"1\":{\"81\":1,\"85\":1}}],[\"specialjudge\",{\"1\":{\"81\":1}}],[\"speed\",{\"1\":{\"41\":1}}],[\"spj\",{\"1\":{\"80\":1,\"83\":1}}],[\"sample\",{\"1\":{\"221\":1}}],[\"save\",{\"1\":{\"124\":1,\"167\":1}}],[\"saved\",{\"1\":{\"75\":1}}],[\"sandbox\",{\"1\":{\"23\":1,\"109\":4,\"111\":5,\"136\":3,\"166\":1}}],[\"src\",{\"1\":{\"54\":1,\"70\":1,\"115\":1}}],[\"shell\",{\"1\":{\"156\":1}}],[\"show\",{\"1\":{\"77\":5}}],[\"sh\",{\"1\":{\"48\":1,\"98\":1,\"135\":2}}],[\"school\",{\"1\":{\"163\":3}}],[\"schema\",{\"1\":{\"124\":1}}],[\"schedule\",{\"0\":{\"63\":1}}],[\"scala\",{\"1\":{\"132\":2}}],[\"scope=read\",{\"1\":{\"73\":1}}],[\"score\",{\"1\":{\"45\":4,\"56\":1,\"202\":5,\"222\":3}}],[\"script>\",{\"1\":{\"30\":1}}],[\"script\",{\"1\":{\"30\":1}}],[\"size\",{\"1\":{\"43\":2,\"109\":2,\"124\":1,\"139\":1}}],[\"sid=cookie\",{\"1\":{\"44\":1}}],[\"sid\",{\"1\":{\"41\":1,\"44\":1}}],[\"swapaccount=1\",{\"1\":{\"113\":2}}],[\"swapfree\",{\"1\":{\"41\":1}}],[\"swapused\",{\"1\":{\"41\":1}}],[\"swaptotal\",{\"1\":{\"41\":1}}],[\"slab\",{\"1\":{\"41\":1}}],[\"sum\",{\"1\":{\"222\":1}}],[\"support\",{\"1\":{\"222\":1}}],[\"superagent\",{\"1\":{\"73\":3}}],[\"su\",{\"1\":{\"135\":1}}],[\"suggest\",{\"1\":{\"124\":2}}],[\"success\",{\"1\":{\"75\":1}}],[\"such\",{\"0\":{\"32\":1}}],[\"subtasks\",{\"1\":{\"202\":1,\"222\":6}}],[\"subtask\",{\"1\":{\"45\":1,\"81\":1}}],[\"subtaskid\",{\"1\":{\"45\":1}}],[\"submission\",{\"1\":{\"43\":1}}],[\"submitted\",{\"1\":{\"43\":1}}],[\"submitter\",{\"1\":{\"43\":1}}],[\"sudo\",{\"1\":{\"14\":1,\"112\":1,\"135\":1}}],[\"s=\",{\"1\":{\"30\":1}}],[\"s\",{\"1\":{\"30\":2,\"73\":3,\"111\":2}}],[\"select\",{\"1\":{\"203\":1,\"218\":1}}],[\"seat\",{\"1\":{\"173\":1}}],[\"search\",{\"0\":{\"90\":1},\"1\":{\"85\":1,\"90\":1,\"124\":2,\"136\":1}}],[\"secure\",{\"1\":{\"142\":1}}],[\"secretid\",{\"1\":{\"141\":1}}],[\"secretkey\",{\"1\":{\"141\":3}}],[\"secretpassword\",{\"1\":{\"124\":1,\"126\":1}}],[\"secret\",{\"1\":{\"73\":5,\"119\":1}}],[\"send\",{\"1\":{\"73\":1}}],[\"setseed\",{\"1\":{\"200\":1}}],[\"setsuperadmin\",{\"1\":{\"135\":1,\"149\":2,\"154\":1}}],[\"setname\",{\"1\":{\"200\":1}}],[\"setemail\",{\"1\":{\"154\":1}}],[\"setuname\",{\"1\":{\"154\":1}}],[\"setup\",{\"1\":{\"98\":1,\"135\":2}}],[\"setjudge\",{\"1\":{\"152\":1}}],[\"setpassword\",{\"1\":{\"151\":2,\"154\":1}}],[\"setpriv\",{\"1\":{\"25\":2,\"150\":1,\"153\":1,\"154\":1}}],[\"setting\",{\"1\":{\"115\":1,\"118\":1}}],[\"settimeout\",{\"1\":{\"30\":2}}],[\"set\",{\"1\":{\"37\":1,\"46\":1,\"73\":4,\"154\":1,\"222\":1}}],[\"server\",{\"1\":{\"16\":1,\"73\":1,\"98\":1,\"122\":1,\"124\":1,\"135\":1,\"139\":5,\"145\":1,\"146\":1,\"173\":1}}],[\"std\",{\"1\":{\"198\":1,\"199\":1,\"200\":2,\"201\":1}}],[\"std=c99\",{\"1\":{\"110\":1}}],[\"studentid\",{\"1\":{\"163\":1}}],[\"store\",{\"1\":{\"124\":9}}],[\"stop\",{\"1\":{\"15\":1,\"167\":2}}],[\"step5\",{\"0\":{\"79\":1}}],[\"step4\",{\"0\":{\"78\":1}}],[\"step2\",{\"0\":{\"77\":1}}],[\"step1\",{\"0\":{\"75\":1}}],[\"stepping\",{\"1\":{\"41\":1}}],[\"static\",{\"1\":{\"139\":3}}],[\"state=$\",{\"1\":{\"73\":1}}],[\"state\",{\"1\":{\"73\":6}}],[\"status\",{\"0\":{\"55\":1},\"1\":{\"41\":1,\"45\":6,\"56\":1}}],[\"starttls\",{\"1\":{\"142\":1}}],[\"start\",{\"1\":{\"37\":1,\"111\":1,\"124\":1,\"167\":2}}],[\"started\",{\"1\":{\"16\":1}}],[\"star\",{\"1\":{\"0\":1}}],[\"style\",{\"1\":{\"30\":1}}],[\"string\",{\"1\":{\"68\":1,\"73\":3,\"77\":13,\"156\":1}}],[\"stroke\",{\"1\":{\"30\":1}}],[\"strokestyle=\",{\"1\":{\"30\":1}}],[\"stream\",{\"0\":{\"11\":1}}],[\"百度学习\",{\"1\":{\"14\":1}}],[\"还原备份\",{\"0\":{\"14\":1}}],[\"反向代理\",{\"0\":{\"138\":1,\"139\":1},\"1\":{\"166\":1}}],[\"反向代理时请确保设置了正确的\",{\"1\":{\"13\":1}}],[\"反之亦然\",{\"1\":{\"10\":1}}],[\"nr\",{\"1\":{\"109\":1}}],[\"ng\",{\"1\":{\"83\":1,\"210\":1}}],[\"nginx\",{\"0\":{\"13\":1},\"1\":{\"139\":1}}],[\"npm\",{\"1\":{\"48\":1}}],[\"nixos\",{\"1\":{\"136\":1}}],[\"nixpkgs\",{\"1\":{\"48\":1,\"122\":1,\"136\":20}}],[\"nix\",{\"1\":{\"48\":3,\"122\":1,\"136\":20,\"137\":11,\"170\":1}}],[\"neither\",{\"1\":{\"222\":1}}],[\"netdata\",{\"1\":{\"173\":1}}],[\"net\",{\"1\":{\"132\":2}}],[\"new\",{\"1\":{\"68\":1,\"73\":3,\"77\":2,\"222\":1}}],[\"next\",{\"1\":{\"45\":1,\"200\":2}}],[\"nest\",{\"1\":{\"30\":1}}],[\"names\",{\"1\":{\"222\":1}}],[\"namespace\",{\"1\":{\"198\":1,\"199\":1,\"200\":2,\"201\":1}}],[\"name>\",{\"1\":{\"167\":1}}],[\"name=\",{\"1\":{\"77\":1}}],[\"name\",{\"1\":{\"43\":2,\"73\":1,\"75\":1,\"110\":1,\"111\":1,\"115\":2,\"116\":2,\"118\":2,\"137\":1,\"186\":1,\"222\":1}}],[\"nav\",{\"1\":{\"27\":3}}],[\"nodisposition=1\",{\"1\":{\"214\":1}}],[\"node\",{\"1\":{\"132\":1}}],[\"nodesource\",{\"1\":{\"48\":1}}],[\"nodejs>=18\",{\"1\":{\"74\":1}}],[\"nodejs\",{\"1\":{\"48\":3,\"76\":1,\"136\":2}}],[\"none\",{\"1\":{\"132\":1}}],[\"noerrors\",{\"1\":{\"77\":1}}],[\"now\",{\"1\":{\"68\":1}}],[\"no\",{\"0\":{\"32\":1},\"1\":{\"135\":1,\"200\":4}}],[\"notfounderror\",{\"1\":{\"77\":2}}],[\"not\",{\"0\":{\"15\":1}}],[\"n>h\",{\"1\":{\"30\":1}}],[\"nunjucks\",{\"1\":{\"78\":1}}],[\"null\",{\"1\":{\"30\":4,\"71\":1,\"199\":1,\"200\":6}}],[\"numpy\",{\"0\":{\"23\":1},\"1\":{\"23\":1,\"136\":3}}],[\"number\",{\"1\":{\"10\":1,\"77\":2,\"222\":3}}],[\"n\",{\"1\":{\"30\":7,\"167\":1}}],[\"等文件\",{\"1\":{\"205\":1}}],[\"等其他角色\",{\"1\":{\"194\":1}}],[\"等软件来辅助创建\",{\"1\":{\"163\":1}}],[\"等工具进行反向代理\",{\"1\":{\"139\":1}}],[\"等工具进行拆分\",{\"1\":{\"92\":1}}],[\"等待几分钟即可\",{\"1\":{\"135\":1}}],[\"等\",{\"1\":{\"83\":1}}],[\"等多种特性\",{\"1\":{\"80\":1}}],[\"等等\",{\"1\":{\"185\":1}}],[\"等等库\",{\"0\":{\"23\":1}}],[\"等等自定义需求\",{\"1\":{\"9\":1}}],[\"等服务商\",{\"1\":{\"12\":1}}],[\"和data\",{\"1\":{\"202\":1}}],[\"和类型一类似\",{\"1\":{\"201\":1}}],[\"和将用户移出该域是等价的\",{\"1\":{\"188\":1}}],[\"和\",{\"1\":{\"11\":1,\"12\":1,\"21\":1,\"73\":1,\"76\":1,\"83\":1,\"105\":1,\"107\":2,\"109\":1,\"119\":1,\"136\":1,\"137\":1,\"139\":3,\"141\":1,\"159\":1,\"173\":1,\"191\":1,\"195\":1,\"198\":1,\"199\":1,\"201\":1,\"221\":1,\"222\":2}}],[\"和功能建议请在\",{\"1\":{\"0\":1}}],[\"you\",{\"1\":{\"73\":1,\"113\":1,\"214\":1}}],[\"y=null\",{\"1\":{\"30\":1}}],[\"y=e\",{\"1\":{\"30\":1}}],[\"y=\",{\"1\":{\"30\":1}}],[\"y\",{\"1\":{\"30\":14,\"199\":2}}],[\"y<0\",{\"1\":{\"30\":1}}],[\"y>u||e\",{\"1\":{\"30\":1}}],[\"yaml文件的内容参考如下\",{\"1\":{\"202\":1}}],[\"yaml文件的内容如下\",{\"1\":{\"200\":1}}],[\"yaml文件的内容为\",{\"1\":{\"199\":1}}],[\"yaml文件\",{\"1\":{\"197\":1,\"201\":1,\"203\":1,\"204\":1}}],[\"yaml\",{\"1\":{\"98\":1,\"106\":1,\"107\":1,\"109\":2,\"137\":1,\"161\":3,\"197\":1,\"199\":1,\"200\":1,\"203\":1,\"205\":3,\"219\":1,\"222\":5}}],[\"ya\",{\"1\":{\"30\":3}}],[\"yarn\",{\"0\":{\"36\":2},\"1\":{\"11\":1,\"16\":1,\"21\":1,\"48\":4,\"49\":2,\"50\":2,\"51\":2,\"52\":2,\"75\":4,\"76\":3,\"86\":1,\"88\":1,\"89\":1,\"97\":1,\"99\":1,\"103\":1,\"123\":1,\"168\":1,\"169\":1,\"170\":1}}],[\"yarnrc\",{\"1\":{\"11\":1}}],[\"y+=e\",{\"1\":{\"30\":1}}],[\"yml\",{\"1\":{\"11\":1,\"118\":1}}],[\"错误\",{\"0\":{\"11\":1}}],[\"的限制\",{\"1\":{\"221\":1}}],[\"的路径访问\",{\"1\":{\"205\":1}}],[\"的路由\",{\"1\":{\"77\":1}}],[\"的标准格式用于题目传输\",{\"1\":{\"205\":1}}],[\"的内容为\",{\"1\":{\"199\":1}}],[\"的内容为两个整数比如\",{\"1\":{\"198\":1}}],[\"的内部事件通讯\",{\"1\":{\"62\":1}}],[\"的输入\",{\"1\":{\"198\":1}}],[\"的过程\",{\"1\":{\"195\":1}}],[\"的权限系统使用双层结构\",{\"1\":{\"191\":1}}],[\"的权限使用位运算处理\",{\"1\":{\"46\":1}}],[\"的包含以下部分\",{\"1\":{\"190\":1}}],[\"的格式添加\",{\"1\":{\"186\":1}}],[\"的hydro格式题目包导入至\",{\"1\":{\"154\":1,\"209\":1}}],[\"的信息\",{\"1\":{\"153\":1}}],[\"的邮箱注册\",{\"1\":{\"153\":1}}],[\"的正整数且未被占用\",{\"1\":{\"148\":1}}],[\"的访问质量\",{\"1\":{\"144\":1}}],[\"的服务商无需勾选\",{\"1\":{\"142\":1}}],[\"的服务器上运行\",{\"1\":{\"98\":1}}],[\"的简要操作说明\",{\"1\":{\"136\":1}}],[\"的域设置中\",{\"1\":{\"132\":1}}],[\"的域\",{\"1\":{\"132\":1}}],[\"的管理员账号登录实例\",{\"1\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"的脚本外\",{\"1\":{\"116\":1}}],[\"的脚本\",{\"1\":{\"115\":1,\"117\":1,\"118\":1}}],[\"的部署并完成对文件服务的配置\",{\"1\":{\"115\":1,\"118\":1}}],[\"的数据\",{\"1\":{\"115\":1,\"118\":1}}],[\"的所有数据\",{\"1\":{\"115\":1,\"118\":1}}],[\"的所有历史版本\",{\"1\":{\"16\":1}}],[\"的配置文件\",{\"0\":{\"139\":1}}],[\"的配置\",{\"1\":{\"113\":1}}],[\"的启动参数为\",{\"1\":{\"111\":1}}],[\"的大小至您想要的大小\",{\"1\":{\"109\":1}}],[\"的运行目录下\",{\"1\":{\"109\":1}}],[\"的运行目录\",{\"1\":{\"109\":1}}],[\"的设置均可添加到此处\",{\"1\":{\"106\":1}}],[\"的末尾添加下列内容\",{\"1\":{\"106\":1}}],[\"的机器上运行下面的指令安装\",{\"1\":{\"97\":1}}],[\"的发行版\",{\"1\":{\"95\":1}}],[\"的文件是不会被自动识别的\",{\"1\":{\"221\":1}}],[\"的文件\",{\"1\":{\"92\":1,\"202\":1}}],[\"的文件夹\",{\"1\":{\"86\":1}}],[\"的文字链接可以得到详细解释\",{\"1\":{\"10\":1}}],[\"的默认引导器\",{\"1\":{\"113\":1}}],[\"的默认用户界面\",{\"1\":{\"85\":1}}],[\"的默认位置可以运行\",{\"1\":{\"21\":1}}],[\"的更细粒度的权限划分\",{\"1\":{\"83\":1}}],[\"的题目搜索增强\",{\"1\":{\"85\":2}}],[\"的题目\",{\"1\":{\"83\":1,\"190\":1}}],[\"的值进行渲染\",{\"1\":{\"78\":1}}],[\"的值选择模板\",{\"1\":{\"78\":1}}],[\"的样例\",{\"1\":{\"75\":1}}],[\"的一参数传入\",{\"1\":{\"73\":1}}],[\"的定义可参照\",{\"1\":{\"54\":1}}],[\"的命令设置新的频率限制\",{\"1\":{\"37\":1}}],[\"的\",{\"1\":{\"25\":1,\"31\":1,\"47\":1,\"79\":1,\"93\":1,\"131\":1,\"134\":1,\"194\":1}}],[\"的账号密码怎么办\",{\"0\":{\"24\":1}}],[\"的时间进行排名\",{\"1\":{\"20\":1}}],[\"的时间\",{\"1\":{\"20\":1}}],[\"的用法后\",{\"1\":{\"14\":1}}],[\"的用户均可以新建题目\",{\"1\":{\"207\":1}}],[\"的用户是附加在特定数据库中的\",{\"1\":{\"156\":1}}],[\"的用户是干什么的\",{\"0\":{\"26\":1}}],[\"的用户设为全站管理员\",{\"1\":{\"154\":1}}],[\"的用户的邮箱设置为\",{\"1\":{\"154\":1}}],[\"的用户的密码设置为\",{\"1\":{\"154\":1}}],[\"的用户的密码改为\",{\"1\":{\"151\":1}}],[\"的用户的权限设为\",{\"1\":{\"154\":1}}],[\"的用户的用户名设置为\",{\"1\":{\"154\":1}}],[\"的用户为管理员\",{\"1\":{\"149\":1}}],[\"的用户\",{\"1\":{\"1\":1,\"26\":1,\"148\":1,\"154\":1,\"194\":1}}],[\"对某语言设置时间或内存倍率\",{\"1\":{\"222\":1}}],[\"对全自动对拍题\",{\"1\":{\"204\":1}}],[\"对编程题\",{\"1\":{\"204\":1}}],[\"对所有编程题目\",{\"1\":{\"204\":1}}],[\"对所有未指定角色的用户生效\",{\"1\":{\"194\":1}}],[\"对比用户结果和预期结果\",{\"1\":{\"200\":1}}],[\"对未登录用户生效\",{\"1\":{\"194\":1}}],[\"对进程进行管理\",{\"1\":{\"165\":1}}],[\"对应网站里的测试数据部分里的文件\",{\"1\":{\"197\":1}}],[\"对应\",{\"1\":{\"77\":1}}],[\"对接其他平台\",{\"0\":{\"73\":1}}],[\"对于有子类的选项\",{\"1\":{\"222\":2}}],[\"对于一般的题目\",{\"1\":{\"221\":1}}],[\"对于不在列表中的用户\",{\"1\":{\"188\":1}}],[\"对于数据库\",{\"1\":{\"158\":1}}],[\"对于\",{\"1\":{\"109\":2,\"136\":1}}],[\"对于没有安装内置评测机的用户\",{\"1\":{\"107\":1}}],[\"对于已安装内置评测机的用户\",{\"1\":{\"107\":1}}],[\"对于非官方插件\",{\"1\":{\"50\":1}}],[\"对于虚拟机和脚本语言\",{\"1\":{\"22\":1}}],[\"对于本地native的编译型语言c\",{\"1\":{\"22\":1}}],[\"对于正在运行中的生产服务器\",{\"1\":{\"21\":1}}],[\"对于学习c\",{\"1\":{\"10\":1}}],[\"对此项目做如下声明\",{\"1\":{\"3\":1}}],[\"一\",{\"0\":{\"198\":1},\"1\":{\"196\":1}}],[\"一键锁屏\",{\"1\":{\"172\":1}}],[\"一键安装脚本默认会创建下面几个进程\",{\"1\":{\"166\":1}}],[\"一键脚本\",{\"1\":{\"81\":2}}],[\"一般需要上传一个config\",{\"1\":{\"204\":1}}],[\"一般地\",{\"1\":{\"177\":1}}],[\"一般已自动完成存储配置\",{\"1\":{\"140\":1}}],[\"一般为\",{\"1\":{\"115\":1,\"116\":1}}],[\"一项需要填写访问网站用的完整的\",{\"1\":{\"135\":1}}],[\"一栏中选择\",{\"1\":{\"92\":1}}],[\"一同挂载到\",{\"1\":{\"77\":1}}],[\"一节并已完成了插件的创建\",{\"1\":{\"67\":1}}],[\"一丝不苟的进行编程的\",{\"1\":{\"10\":1}}],[\"一字不差\",{\"1\":{\"10\":2}}],[\"是一个markdown格式的文档\",{\"1\":{\"197\":1}}],[\"是一个高效的信息学在线测评系统\",{\"1\":{\"0\":1}}],[\"是没有意义的\",{\"1\":{\"195\":1}}],[\"是等价的\",{\"1\":{\"194\":1}}],[\"是用户在单个域内拥有的权限\",{\"1\":{\"193\":1}}],[\"是用户在整套系统内拥有的权限\",{\"1\":{\"192\":1}}],[\"是否高亮\",{\"1\":{\"179\":1}}],[\"是否使用加密\",{\"1\":{\"142\":1}}],[\"是否存在来验证是否当前系统是否启用了\",{\"1\":{\"113\":1}}],[\"是在低配置服务器上运行的更优方案\",{\"1\":{\"134\":1}}],[\"是由\",{\"1\":{\"118\":1}}],[\"是两套不同的系统\",{\"1\":{\"83\":1}}],[\"是\",{\"1\":{\"47\":1}}],[\"是从对这个系统吐槽开始学习如何认真仔细的\",{\"1\":{\"10\":1}}],[\"养成良好的代码习惯\",{\"1\":{\"10\":1}}],[\"这些文件将被复制到工作目录\",{\"1\":{\"222\":1}}],[\"这些文件可以在题面中使用\",{\"1\":{\"205\":1}}],[\"这些命令需要以在终端以\",{\"1\":{\"147\":1}}],[\"这个头文件里实现了一个主函数\",{\"1\":{\"199\":1}}],[\"这个是题目的配置信息\",{\"1\":{\"197\":1}}],[\"这个文件是就是题目的内容\",{\"1\":{\"197\":1}}],[\"这个main函数必须返回int类型\",{\"1\":{\"10\":1}}],[\"这也表示所有用户默认不会出现在管理列表中\",{\"1\":{\"188\":1}}],[\"这遵循\",{\"1\":{\"183\":1}}],[\"这时请使用\",{\"1\":{\"167\":1}}],[\"这时所有返回的参数作为\",{\"1\":{\"73\":1}}],[\"这将创建三个用户\",{\"1\":{\"163\":1}}],[\"这样第一个用例的输入和预期输出就录入完毕\",{\"1\":{\"198\":1}}],[\"这样数据丢失的风险仍然较高\",{\"1\":{\"158\":1}}],[\"这样能保证题库中题号靠前的题目难度依次上升\",{\"1\":{\"17\":1}}],[\"这可能会导致评测时间计量不准确\",{\"1\":{\"134\":1}}],[\"这可以极大降低开发难度\",{\"1\":{\"47\":1}}],[\"这里并没有列出所有可以运行的指令\",{\"1\":{\"154\":1}}],[\"这里提供了几套方案帮助您建立自己的站点\",{\"1\":{\"133\":1}}],[\"这里存储着上传的图片和文件等信息\",{\"1\":{\"115\":1}}],[\"这里存储着题目数据等关键信息\",{\"1\":{\"115\":1,\"116\":1}}],[\"这意味着使用\",{\"1\":{\"83\":1}}],[\"这在不同系统中可能设计不同\",{\"1\":{\"73\":1}}],[\"这两个地方\",{\"1\":{\"35\":1}}],[\"这会自动创建\",{\"1\":{\"27\":1}}],[\"这点东西都不能自动识别\",{\"1\":{\"10\":1}}],[\"这系统太烂了\",{\"1\":{\"10\":1}}],[\"这是为了从根源上防止出现\",{\"1\":{\"9\":1}}],[\"这是对开发者的鼓励\",{\"1\":{\"0\":1}}],[\"哦\",{\"1\":{\"10\":1}}],[\"因此在入域申请链接的权限组中选择\",{\"1\":{\"195\":1}}],[\"因此很多地方需要你来迁就它\",{\"1\":{\"10\":1}}],[\"因各服务商全站\",{\"1\":{\"146\":1}}],[\"因为其中很多功能我们更推荐通过\",{\"1\":{\"154\":1}}],[\"因为底部注册路由时已声明所需权限\",{\"1\":{\"77\":1}}],[\"因为操作系统对非零的返回值认为是运行出错\",{\"1\":{\"10\":1}}],[\"因而将导致系统报答案错误\",{\"1\":{\"10\":1}}],[\"之前\",{\"1\":{\"147\":1}}],[\"之后点击\",{\"1\":{\"179\":2}}],[\"之后又不会修\",{\"1\":{\"156\":1}}],[\"之后保存并重启沙箱\",{\"1\":{\"137\":1}}],[\"之后刷新页面\",{\"1\":{\"135\":1}}],[\"之后在终端中使用\",{\"1\":{\"135\":1}}],[\"之后再重启\",{\"1\":{\"132\":1}}],[\"之后前往系统设置\",{\"1\":{\"27\":1}}],[\"之后无法登录\",{\"0\":{\"13\":1}}],[\"之外的所有包更新\",{\"1\":{\"16\":1}}],[\"之类的提示信息\",{\"1\":{\"10\":1}}],[\"之一的链接\",{\"1\":{\"3\":1}}],[\"txt$\",{\"1\":{\"222\":1}}],[\"txt\",{\"1\":{\"173\":1,\"197\":1,\"222\":6}}],[\"tag\",{\"1\":{\"205\":1}}],[\"tab\",{\"1\":{\"163\":1}}],[\"task\",{\"0\":{\"61\":1},\"1\":{\"43\":1}}],[\"tls\",{\"1\":{\"142\":1}}],[\"tk\",{\"1\":{\"135\":1}}],[\"tree\",{\"1\":{\"205\":1,\"221\":1}}],[\"training\",{\"1\":{\"162\":1,\"190\":1}}],[\"try\",{\"1\":{\"124\":1,\"139\":1,\"222\":1}}],[\"true\",{\"1\":{\"40\":1,\"98\":2,\"124\":2,\"137\":1,\"141\":1}}],[\"tcp\",{\"1\":{\"124\":1}}],[\"tyvj\",{\"1\":{\"118\":1}}],[\"type字段一般为default\",{\"1\":{\"204\":1}}],[\"typeof\",{\"1\":{\"77\":1}}],[\"types\",{\"1\":{\"77\":6}}],[\"typescript\",{\"0\":{\"67\":1,\"74\":1},\"1\":{\"47\":3,\"67\":1}}],[\"type=\",{\"1\":{\"77\":1}}],[\"type\",{\"1\":{\"43\":1,\"73\":3,\"98\":1,\"132\":1,\"141\":2,\"199\":1,\"200\":2,\"203\":1,\"204\":1,\"219\":1,\"222\":3}}],[\"tencent\",{\"1\":{\"214\":1}}],[\"tencentos\",{\"1\":{\"134\":1}}],[\"teacher\",{\"1\":{\"194\":1}}],[\"temp\",{\"1\":{\"163\":2}}],[\"templates\",{\"1\":{\"78\":1,\"160\":1,\"162\":2}}],[\"template\",{\"0\":{\"78\":1},\"1\":{\"77\":3,\"78\":2}}],[\"test用来指定对test\",{\"1\":{\"204\":1}}],[\"testlib\",{\"1\":{\"200\":3,\"204\":1,\"222\":2}}],[\"testdata\",{\"1\":{\"197\":1,\"204\":1,\"205\":2}}],[\"testcases\",{\"1\":{\"106\":1}}],[\"test\",{\"1\":{\"81\":1,\"163\":4,\"201\":3,\"202\":1,\"222\":1}}],[\"text\",{\"1\":{\"73\":1}}],[\"telegram\",{\"1\":{\"1\":1}}],[\"tdoc\",{\"1\":{\"70\":1}}],[\"tsdoc\",{\"1\":{\"70\":1}}],[\"ts\",{\"1\":{\"54\":1,\"70\":1,\"75\":1,\"77\":1}}],[\"tsc\",{\"1\":{\"41\":1}}],[\"title\",{\"1\":{\"54\":1,\"55\":1,\"190\":4,\"205\":1}}],[\"tips\",{\"1\":{\"47\":1,\"85\":1,\"90\":1,\"94\":1,\"97\":1,\"98\":1,\"118\":1,\"119\":1,\"134\":1,\"135\":2,\"140\":1,\"141\":1,\"147\":1,\"148\":1,\"189\":1,\"190\":1,\"207\":1,\"214\":1,\"221\":1,\"222\":1}}],[\"timestamp\",{\"1\":{\"137\":1}}],[\"timeout\",{\"1\":{\"47\":1,\"124\":1}}],[\"time\",{\"1\":{\"29\":1,\"45\":2,\"68\":2,\"106\":1,\"200\":1,\"202\":1,\"222\":6}}],[\"than\",{\"1\":{\"222\":1}}],[\"throw\",{\"1\":{\"73\":3,\"77\":2}}],[\"this\",{\"1\":{\"73\":3,\"77\":11,\"113\":1}}],[\"third\",{\"0\":{\"36\":1}}],[\"them\",{\"1\":{\"222\":1}}],[\"these\",{\"1\":{\"132\":1,\"222\":2}}],[\"the\",{\"0\":{\"36\":1},\"1\":{\"214\":1,\"222\":6}}],[\"t=\",{\"1\":{\"30\":1}}],[\"t===y\",{\"1\":{\"30\":1}}],[\"t=d\",{\"1\":{\"30\":1}}],[\"t\",{\"1\":{\"30\":11,\"73\":3,\"222\":1}}],[\"tools\",{\"1\":{\"173\":5,\"199\":6}}],[\"toolkit\",{\"1\":{\"173\":2}}],[\"todo\",{\"1\":{\"141\":1,\"173\":1,\"175\":1}}],[\"token`\",{\"1\":{\"73\":1}}],[\"tokenmodel\",{\"1\":{\"73\":7}}],[\"token\",{\"0\":{\"65\":1},\"1\":{\"73\":4,\"173\":2}}],[\"to\",{\"1\":{\"47\":1,\"77\":1,\"132\":1,\"214\":1,\"222\":2}}],[\"top\",{\"1\":{\"30\":1}}],[\"total\",{\"1\":{\"29\":1,\"41\":1,\"106\":1}}],[\"touch\",{\"1\":{\"27\":1}}],[\"two\",{\"1\":{\"10\":1}}],[\"则运行时测试环境会自动把每个输入文件复制到test\",{\"1\":{\"201\":1}}],[\"则每个用例至少要提供一个in文件和一个输出文件\",{\"1\":{\"197\":1}}],[\"则该用户无法查看此域\",{\"1\":{\"193\":1}}],[\"则格式如下\",{\"1\":{\"190\":1}}],[\"则用户信息列不可用\",{\"1\":{\"163\":1}}],[\"则永久封禁\",{\"1\":{\"153\":1}}],[\"则需要进行备案后才能使用\",{\"1\":{\"139\":1}}],[\"则跳过渲染步骤\",{\"1\":{\"78\":1}}],[\"则表示此提交为自测提交\",{\"1\":{\"43\":1}}],[\"则进行登录操作\",{\"1\":{\"40\":1}}],[\"则包含了虚拟机本身或解释器本身的内存消耗\",{\"1\":{\"22\":1}}],[\"则一切正常\",{\"1\":{\"16\":1}}],[\"则中断程序的运行\",{\"1\":{\"10\":1}}],[\"则认为学生的程序是正确的\",{\"1\":{\"10\":1}}],[\"喂\",{\"1\":{\"10\":1}}],[\"并左右分栏显示\",{\"1\":{\"214\":1}}],[\"并进行了部分扩展\",{\"1\":{\"214\":1}}],[\"并设置对应字段的值\",{\"1\":{\"204\":1}}],[\"并提供一个对拍程序\",{\"1\":{\"200\":1}}],[\"并点击\",{\"1\":{\"186\":1}}],[\"并可以访问内网中任何设备\",{\"1\":{\"172\":1}}],[\"并有对应的开发环境\",{\"1\":{\"172\":1}}],[\"并还原\",{\"1\":{\"159\":1}}],[\"并将选定用户加入该用户组\",{\"1\":{\"194\":1}}],[\"并将\",{\"1\":{\"158\":1,\"161\":1}}],[\"并忽略本章节\",{\"1\":{\"136\":1}}],[\"并移入\",{\"1\":{\"115\":1,\"118\":1}}],[\"并非轻量化软件\",{\"1\":{\"90\":1}}],[\"并与定义的\",{\"1\":{\"77\":1}}],[\"并使用外部工具进行连接\",{\"1\":{\"156\":1}}],[\"并使用\",{\"1\":{\"76\":1,\"78\":1,\"221\":1}}],[\"并按照提示填写相关信息\",{\"1\":{\"75\":1}}],[\"并储存状态信息\",{\"1\":{\"73\":1}}],[\"并且声明了需要做题者实现的函数add\",{\"1\":{\"199\":1}}],[\"并且有以下内置模块可用\",{\"1\":{\"72\":1}}],[\"并且最好返回0\",{\"1\":{\"10\":1}}],[\"并在后台运行\",{\"1\":{\"51\":1}}],[\"并尝试给网站设置\",{\"1\":{\"34\":1}}],[\"并认为答案不正确\",{\"1\":{\"10\":1}}],[\"并根据自己的理解提交程序\",{\"1\":{\"10\":1}}],[\"并严格定义题目提供输入数据的格式和要求的输出数据格式\",{\"1\":{\"10\":1}}],[\"并没有人工智能\",{\"1\":{\"10\":1}}],[\"教程多\",{\"1\":{\"134\":1}}],[\"教师根据题目定义的格式向系统中添加若干组测试数据\",{\"1\":{\"10\":1}}],[\"教师在系统中添加题目\",{\"1\":{\"10\":1}}],[\"教学事故\",{\"1\":{\"9\":1}}],[\"也支持短形式\",{\"1\":{\"205\":1}}],[\"也可以使用相同分数\",{\"1\":{\"219\":1}}],[\"也可以用英文半角逗号分隔多个标签\",{\"1\":{\"215\":1}}],[\"也可以用\",{\"1\":{\"163\":1}}],[\"也可以从\",{\"1\":{\"156\":1}}],[\"也可以换成其他的你喜欢的路径\",{\"1\":{\"124\":1}}],[\"也可使用域内小组进行权限控制\",{\"1\":{\"83\":1}}],[\"也可在管理面板中开通高级功能自助操作\",{\"1\":{\"9\":1}}],[\"也能够正常调用这些函数\",{\"1\":{\"77\":1}}],[\"也许你会觉得\",{\"1\":{\"10\":1}}],[\"也会导致错误\",{\"1\":{\"10\":1}}],[\"你的答案即使本质上是正确的\",{\"1\":{\"10\":1}}],[\"什么是\",{\"0\":{\"10\":1}}],[\"lxc\",{\"1\":{\"167\":1}}],[\"ls\",{\"1\":{\"166\":2,\"167\":1}}],[\"lm\",{\"1\":{\"110\":1}}],[\"lyrio\",{\"1\":{\"83\":2}}],[\"luogu\",{\"1\":{\"81\":1,\"85\":1}}],[\"laomai\",{\"1\":{\"196\":1,\"207\":1}}],[\"lastmodified\",{\"1\":{\"43\":1}}],[\"lang=zh\",{\"1\":{\"135\":1}}],[\"languages\",{\"1\":{\"132\":1}}],[\"language\",{\"1\":{\"107\":2}}],[\"langs\",{\"1\":{\"107\":2,\"132\":1,\"222\":1}}],[\"lang\",{\"1\":{\"43\":1,\"56\":1,\"222\":2}}],[\"latest\",{\"1\":{\"16\":1,\"88\":1,\"99\":1,\"168\":1}}],[\"later\",{\"1\":{\"3\":1}}],[\"lts\",{\"1\":{\"41\":1}}],[\"locate\",{\"1\":{\"222\":1}}],[\"local\",{\"1\":{\"148\":2}}],[\"localhost\",{\"1\":{\"98\":2,\"115\":1,\"116\":1,\"118\":1}}],[\"locales\",{\"1\":{\"161\":1}}],[\"locale\",{\"0\":{\"79\":1},\"1\":{\"79\":1}}],[\"local`\",{\"1\":{\"73\":1}}],[\"loj\",{\"1\":{\"83\":2,\"210\":1}}],[\"load\",{\"1\":{\"41\":1,\"73\":1}}],[\"log\",{\"1\":{\"124\":2,\"139\":2,\"167\":1}}],[\"login\",{\"1\":{\"37\":1,\"40\":1,\"72\":2,\"73\":13,\"85\":2,\"132\":2}}],[\"logs\",{\"1\":{\"16\":1}}],[\"logo\",{\"1\":{\"9\":1,\"27\":4}}],[\"l3\",{\"1\":{\"41\":1}}],[\"l2\",{\"1\":{\"41\":1}}],[\"l1i\",{\"1\":{\"41\":1}}],[\"l1d\",{\"1\":{\"41\":1}}],[\"lemon\",{\"1\":{\"222\":1}}],[\"level\",{\"1\":{\"124\":1}}],[\"less\",{\"1\":{\"124\":1}}],[\"left\",{\"1\":{\"30\":1}}],[\"length\",{\"1\":{\"30\":2}}],[\"l\",{\"1\":{\"30\":5}}],[\"l=i\",{\"1\":{\"30\":1}}],[\"live\",{\"1\":{\"172\":1}}],[\"lightweight\",{\"1\":{\"124\":1}}],[\"list\",{\"1\":{\"87\":1,\"169\":1}}],[\"license\",{\"1\":{\"75\":1}}],[\"lib\",{\"1\":{\"45\":1}}],[\"limit\",{\"1\":{\"29\":1,\"37\":1,\"68\":1,\"106\":1,\"124\":4,\"222\":2}}],[\"link\",{\"1\":{\"186\":1}}],[\"links\",{\"1\":{\"44\":1}}],[\"lineto\",{\"1\":{\"30\":1}}],[\"linewidth=m\",{\"1\":{\"30\":1}}],[\"lines=100\",{\"1\":{\"167\":1}}],[\"lines\",{\"1\":{\"16\":1}}],[\"linux\",{\"0\":{\"11\":1},\"1\":{\"41\":1,\"48\":1,\"80\":1,\"113\":3,\"134\":5,\"172\":2}}],[\"更改用户密码\",{\"0\":{\"151\":1}}],[\"更详细的介绍见\",{\"1\":{\"204\":1}}],[\"更详细的\",{\"1\":{\"137\":1}}],[\"更多可选配置均可添加在此处\",{\"1\":{\"106\":1}}],[\"更多细节可在\",{\"1\":{\"70\":1}}],[\"更多教程请点击右上角的常用教程查看\",{\"0\":{\"7\":1}}],[\"更新完后需重启\",{\"1\":{\"168\":1}}],[\"更新内容\",{\"1\":{\"71\":1}}],[\"更新\",{\"0\":{\"52\":1,\"88\":1,\"99\":1,\"168\":1}}],[\"更新会覆盖此处的所有修改\",{\"1\":{\"21\":1}}],[\"更新升级\",{\"0\":{\"16\":1}}],[\"更省心\",{\"1\":{\"9\":1}}],[\"无输出\",{\"1\":{\"200\":1}}],[\"无特殊情况请\",{\"1\":{\"168\":1}}],[\"无账号密码\",{\"1\":{\"118\":1}}],[\"无论内置评测机是否启动\",{\"1\":{\"107\":1}}],[\"无比赛功能\",{\"1\":{\"83\":1}}],[\"无法正常使用等问题\",{\"1\":{\"139\":1}}],[\"无法记录用户ip等问题\",{\"1\":{\"139\":1}}],[\"无法再导入\",{\"1\":{\"83\":1}}],[\"无法登录\",{\"1\":{\"26\":1}}],[\"无需手动操作\",{\"1\":{\"111\":1}}],[\"无需手动维护\",{\"1\":{\"9\":1}}],[\"无需改动源代码\",{\"1\":{\"80\":1}}],[\"无需购置云服务器\",{\"1\":{\"9\":1}}],[\"无服务器快速体验系统功能\",{\"1\":{\"9\":1}}],[\"超过两万题的题库可以直接复制使用\",{\"1\":{\"9\":1}}],[\"abc\",{\"1\":{\"222\":1}}],[\"abc123\",{\"1\":{\"98\":1}}],[\"a3\",{\"1\":{\"205\":2,\"221\":2}}],[\"a2\",{\"1\":{\"205\":2,\"221\":2}}],[\"a1\",{\"1\":{\"205\":2,\"221\":2}}],[\"an\",{\"1\":{\"214\":1}}],[\"ans\",{\"1\":{\"202\":25,\"221\":1,\"222\":2}}],[\"answers\",{\"1\":{\"203\":1,\"219\":1}}],[\"answer\",{\"1\":{\"200\":2}}],[\"and\",{\"1\":{\"124\":1,\"200\":2}}],[\"android\",{\"1\":{\"27\":1}}],[\"a+b\",{\"1\":{\"198\":1,\"200\":6,\"201\":1}}],[\"attach\",{\"1\":{\"167\":1}}],[\"automaticly\",{\"1\":{\"222\":1}}],[\"auto\",{\"1\":{\"141\":1,\"222\":1}}],[\"authsource\",{\"1\":{\"156\":1}}],[\"auth\",{\"1\":{\"124\":1,\"126\":1}}],[\"author\",{\"1\":{\"75\":1}}],[\"authorize\",{\"1\":{\"73\":1}}],[\"authorization\",{\"1\":{\"41\":1,\"73\":1}}],[\"astyle\",{\"1\":{\"132\":10}}],[\"async\",{\"1\":{\"68\":3,\"73\":2,\"77\":7}}],[\"ahead\",{\"1\":{\"124\":1}}],[\"aliyun\",{\"1\":{\"214\":1}}],[\"alibaba\",{\"1\":{\"134\":1}}],[\"alpine\",{\"1\":{\"134\":2}}],[\"alternates\",{\"1\":{\"124\":1}}],[\"allow\",{\"1\":{\"132\":1}}],[\"allowedlangs\",{\"1\":{\"132\":1}}],[\"all\",{\"1\":{\"73\":2,\"167\":2}}],[\"amazon\",{\"1\":{\"83\":1}}],[\"ajax\",{\"1\":{\"77\":1}}],[\"argv\",{\"1\":{\"198\":1,\"199\":1,\"200\":5,\"201\":1}}],[\"argc\",{\"1\":{\"198\":1,\"199\":1,\"200\":5,\"201\":1}}],[\"args\",{\"1\":{\"77\":5}}],[\"are\",{\"1\":{\"113\":1,\"222\":1}}],[\"arch\",{\"0\":{\"11\":1},\"1\":{\"41\":1}}],[\"agent\",{\"1\":{\"73\":1}}],[\"agpl3\",{\"1\":{\"3\":4}}],[\"agpl\",{\"1\":{\"2\":2,\"3\":1,\"31\":1}}],[\"await\",{\"1\":{\"73\":5,\"77\":4}}],[\"admin\",{\"1\":{\"119\":1,\"194\":1}}],[\"adocs\",{\"1\":{\"68\":1}}],[\"additional\",{\"1\":{\"197\":1,\"205\":2}}],[\"add\",{\"1\":{\"50\":2,\"73\":1,\"76\":2,\"77\":3,\"86\":3,\"97\":2,\"123\":2,\"153\":1,\"199\":3}}],[\"addprogress\",{\"1\":{\"45\":1}}],[\"addon\",{\"1\":{\"27\":3,\"50\":4,\"75\":2,\"76\":1,\"86\":2,\"87\":1,\"89\":1,\"97\":1,\"103\":1,\"123\":1,\"160\":1,\"161\":1,\"162\":1}}],[\"after\",{\"1\":{\"68\":2,\"124\":4}}],[\"avx\",{\"1\":{\"134\":2}}],[\"avatar\",{\"1\":{\"73\":1,\"186\":1}}],[\"available\",{\"1\":{\"41\":1}}],[\"avgload\",{\"1\":{\"41\":1}}],[\"apt\",{\"1\":{\"48\":1,\"136\":1}}],[\"api`\",{\"1\":{\"73\":1}}],[\"api\",{\"0\":{\"38\":1},\"1\":{\"47\":1,\"73\":3,\"141\":2}}],[\"appid\",{\"1\":{\"73\":4}}],[\"application\",{\"1\":{\"73\":2,\"78\":1}}],[\"apply\",{\"1\":{\"68\":2,\"73\":1,\"77\":3}}],[\"apple\",{\"1\":{\"27\":1}}],[\"appendchild\",{\"1\":{\"30\":1}}],[\"a=\",{\"1\":{\"30\":1}}],[\"a=e\",{\"1\":{\"30\":1}}],[\"a\",{\"0\":{\"36\":1},\"1\":{\"30\":3,\"44\":6,\"73\":1,\"198\":1,\"199\":2,\"200\":8,\"201\":1,\"203\":3,\"205\":1,\"218\":1,\"219\":2,\"222\":3}}],[\"a>\",{\"1\":{\"19\":1}}],[\"ac的代码如下\",{\"1\":{\"201\":1}}],[\"acm\",{\"1\":{\"81\":5,\"115\":1}}],[\"accept\",{\"1\":{\"73\":2,\"78\":1}}],[\"accesskey\",{\"1\":{\"141\":2}}],[\"access\",{\"1\":{\"73\":3,\"139\":1,\"214\":1}}],[\"active\",{\"1\":{\"41\":1}}],[\"ac\",{\"1\":{\"9\":1,\"44\":2,\"45\":1,\"48\":1,\"81\":1,\"83\":2,\"98\":1,\"135\":4,\"139\":1,\"145\":1,\"162\":1,\"198\":1,\"200\":1,\"202\":1}}],[\"flushes\",{\"1\":{\"124\":1}}],[\"flush\",{\"1\":{\"124\":1}}],[\"flags\",{\"1\":{\"41\":1}}],[\"fst\",{\"1\":{\"124\":4}}],[\"fs\",{\"1\":{\"113\":1,\"141\":3}}],[\"fdiagnostics\",{\"1\":{\"110\":2}}],[\"fpc\",{\"1\":{\"136\":1,\"137\":1}}],[\"fps\",{\"0\":{\"91\":1,\"92\":1,\"211\":1},\"1\":{\"80\":2,\"81\":3,\"85\":2,\"92\":6,\"211\":1}}],[\"fpu\",{\"1\":{\"41\":1}}],[\"from\",{\"1\":{\"68\":2,\"73\":1,\"77\":1,\"142\":1}}],[\"free\",{\"1\":{\"41\":1,\"132\":1}}],[\"freebasic\",{\"1\":{\"22\":1}}],[\"faqs\",{\"1\":{\"131\":1}}],[\"faq\",{\"0\":{\"129\":1}}],[\"fast\",{\"1\":{\"124\":1}}],[\"failed\",{\"1\":{\"47\":1}}],[\"false\",{\"1\":{\"43\":1,\"77\":1,\"141\":1}}],[\"family\",{\"1\":{\"41\":1}}],[\"favicon\",{\"1\":{\"27\":4}}],[\"f=m\",{\"1\":{\"30\":1}}],[\"findone\",{\"1\":{\"77\":1}}],[\"fixed\",{\"1\":{\"30\":1}}],[\"filter\",{\"1\":{\"73\":1}}],[\"fillrect\",{\"1\":{\"30\":1}}],[\"file子目录用来存放给做题者用的额外文件\",{\"1\":{\"197\":1}}],[\"filename\",{\"1\":{\"77\":1,\"199\":1,\"204\":1,\"222\":1}}],[\"files\",{\"1\":{\"40\":1,\"44\":2,\"124\":1,\"139\":1,\"199\":1,\"222\":4}}],[\"file\",{\"0\":{\"15\":1,\"32\":1},\"1\":{\"15\":1,\"21\":1,\"43\":1,\"115\":1,\"118\":1,\"124\":1,\"139\":3,\"140\":1,\"141\":20,\"158\":1,\"159\":2,\"192\":1,\"197\":1,\"199\":1,\"201\":1,\"205\":3,\"214\":6,\"222\":1}}],[\"function\",{\"1\":{\"30\":5,\"68\":3,\"73\":3,\"77\":3}}],[\"found\",{\"1\":{\"200\":2}}],[\"foo\",{\"1\":{\"110\":1,\"135\":1,\"163\":2,\"214\":4,\"222\":3}}],[\"footer\",{\"1\":{\"19\":1,\"30\":1}}],[\"forward\",{\"1\":{\"146\":1}}],[\"forwarded\",{\"1\":{\"139\":3,\"146\":1}}],[\"format\",{\"0\":{\"205\":1},\"1\":{\"139\":1}}],[\"forbiddenerror\",{\"1\":{\"73\":2}}],[\"for\",{\"1\":{\"30\":2,\"139\":3,\"146\":2,\"222\":1}}],[\"foreach\",{\"1\":{\"30\":1}}],[\"fork\",{\"1\":{\"3\":1}}],[\"f\",{\"0\":{\"6\":1},\"1\":{\"30\":1}}],[\"好消息\",{\"0\":{\"6\":1}}],[\"为此我们设计了\",{\"1\":{\"194\":1}}],[\"为了便于系统间进行数据交换\",{\"1\":{\"205\":1}}],[\"为了保证数据安全\",{\"1\":{\"157\":1}}],[\"为了避免宿主机环境变化对于评测的影响\",{\"1\":{\"136\":1}}],[\"为不小于\",{\"1\":{\"148\":1}}],[\"为防止数据丢失\",{\"1\":{\"135\":1}}],[\"为什么使用\",{\"1\":{\"80\":1}}],[\"为什么我的提交页面没有语言可选\",{\"0\":{\"35\":1}}],[\"为什么我无法批量下载多个文件\",{\"0\":{\"34\":1}}],[\"为什么我配置完反向代理\",{\"0\":{\"13\":1}}],[\"为什么我安装完成之后仍然无法访问\",{\"0\":{\"12\":1}}],[\"为空或\",{\"1\":{\"78\":1}}],[\"为固定传入参数\",{\"1\":{\"77\":1}}],[\"为数据库驱动\",{\"1\":{\"77\":1}}],[\"为传入的参数集合\",{\"1\":{\"77\":1}}],[\"为需要捕获的路由名\",{\"1\":{\"68\":1}}],[\"为例\",{\"1\":{\"50\":1,\"113\":1}}],[\"为允许的单题最大评测时长即可\",{\"1\":{\"29\":1}}],[\"为\",{\"1\":{\"4\":2,\"25\":1,\"26\":1,\"43\":1,\"45\":1,\"77\":2,\"148\":1,\"149\":1,\"151\":1,\"154\":7,\"162\":1,\"190\":1}}],[\"为开源框架\",{\"1\":{\"1\":1}}],[\"排名不分先后\",{\"1\":{\"4\":1}}],[\"鸣谢\",{\"0\":{\"4\":1}}],[\"删除此配置项即可\",{\"1\":{\"222\":1}}],[\"删除讨论等等\",{\"1\":{\"193\":1}}],[\"删除进程后需要执行该指令\",{\"1\":{\"167\":1}}],[\"删除进程\",{\"1\":{\"167\":1}}],[\"删除\",{\"1\":{\"3\":1,\"11\":1}}],[\"修改复制后的题目的测试数据\",{\"1\":{\"183\":1}}],[\"修改方式同上\",{\"1\":{\"162\":1}}],[\"修改页面模板\",{\"0\":{\"162\":1}}],[\"修改页面翻译或是添加新语言\",{\"0\":{\"161\":1}}],[\"修改后添加至\",{\"1\":{\"161\":1}}],[\"修改翻译\",{\"1\":{\"161\":1}}],[\"修改系统设置\",{\"1\":{\"154\":1}}],[\"修改完成后\",{\"1\":{\"126\":1}}],[\"修改完后请重启\",{\"1\":{\"107\":1}}],[\"修改编译选项\",{\"0\":{\"107\":1}}],[\"修改编译命令\",{\"1\":{\"81\":1}}],[\"修改对应的参数\",{\"1\":{\"105\":1}}],[\"修改\",{\"1\":{\"3\":1,\"68\":1,\"109\":1,\"111\":1,\"167\":1}}],[\"且选手机之间无法互相访问\",{\"1\":{\"172\":1}}],[\"且您应当修改系统设置中的\",{\"1\":{\"146\":1}}],[\"且操作完成后需要重启沙箱\",{\"1\":{\"136\":1}}],[\"且希望外网的用户可以访问\",{\"1\":{\"135\":1}}],[\"且输入输出文件较大时可能会引发错误\",{\"1\":{\"109\":1}}],[\"且需要手动在服务器间同步数据\",{\"1\":{\"83\":1}}],[\"且前端的任何更改将即时生效\",{\"1\":{\"51\":1}}],[\"且内部实现可能会在不发布任何通知的情况下进行重命名\",{\"1\":{\"3\":1}}],[\"且提供安装脚本\",{\"1\":{\"0\":1}}],[\"尽可能\",{\"1\":{\"3\":1}}],[\"开始\",{\"1\":{\"136\":1}}],[\"开始部署您的\",{\"1\":{\"83\":1}}],[\"开头的语言\",{\"1\":{\"132\":1}}],[\"开大程序运行栈空间\",{\"0\":{\"111\":1}}],[\"开发组不对\",{\"1\":{\"134\":1}}],[\"开发组不会为您解决任何网络问题\",{\"1\":{\"47\":1}}],[\"开发组会\",{\"1\":{\"3\":1}}],[\"开发模式\",{\"1\":{\"47\":1}}],[\"开发模式安装时出现\",{\"0\":{\"11\":1}}],[\"开发环境仅适合需要进行大量深度修改或希望贡献代码的用户\",{\"1\":{\"47\":1}}],[\"开发环境部署完成后默认不启用任何插件\",{\"1\":{\"50\":1}}],[\"开发环境部署\",{\"0\":{\"47\":1}}],[\"开发者有权对您停止任何技术支持\",{\"1\":{\"3\":1}}],[\"开源\",{\"1\":{\"3\":1}}],[\"开源许可\",{\"0\":{\"2\":1}}],[\"处的\",{\"1\":{\"3\":1}}],[\"multiselect\",{\"1\":{\"203\":1,\"218\":1}}],[\"md\",{\"1\":{\"162\":1,\"197\":1,\"205\":2}}],[\"mdoc\",{\"1\":{\"70\":1}}],[\"myqcloud\",{\"1\":{\"141\":3}}],[\"mysql\",{\"1\":{\"81\":1}}],[\"mkdir\",{\"1\":{\"137\":1}}],[\"mmdb\",{\"1\":{\"93\":1}}],[\"msys\",{\"1\":{\"132\":1}}],[\"ms\",{\"1\":{\"45\":1}}],[\"msrequestanimationframe||function\",{\"1\":{\"30\":1}}],[\"member\",{\"1\":{\"194\":1}}],[\"memsw\",{\"1\":{\"113\":1}}],[\"memory\",{\"1\":{\"41\":1,\"45\":2,\"113\":3,\"202\":1,\"222\":6}}],[\"measurements\",{\"1\":{\"113\":1}}],[\"message\",{\"1\":{\"45\":4}}],[\"meta\",{\"1\":{\"43\":1}}],[\"markdown\",{\"1\":{\"197\":1,\"205\":1,\"214\":2}}],[\"mariadb\",{\"1\":{\"81\":1}}],[\"manual\",{\"1\":{\"137\":1}}],[\"manufacturer\",{\"1\":{\"41\":1}}],[\"master\",{\"1\":{\"124\":1}}],[\"maillower\",{\"1\":{\"57\":1}}],[\"mail\",{\"1\":{\"57\":1,\"142\":1,\"153\":1}}],[\"main\",{\"1\":{\"30\":1,\"162\":1,\"198\":1,\"199\":1,\"200\":3,\"201\":1}}],[\"machine\",{\"1\":{\"41\":1}}],[\"maximum\",{\"1\":{\"124\":2}}],[\"maxmind\",{\"1\":{\"93\":1}}],[\"max\",{\"1\":{\"30\":6,\"106\":1,\"124\":5,\"222\":1}}],[\"m=math\",{\"1\":{\"30\":1}}],[\"m=\",{\"1\":{\"30\":1}}],[\"m=i\",{\"1\":{\"30\":1}}],[\"m>=t\",{\"1\":{\"30\":1}}],[\"m\",{\"1\":{\"30\":4}}],[\"min\",{\"1\":{\"222\":2}}],[\"minio\",{\"1\":{\"15\":2,\"141\":8}}],[\"microsoft\",{\"1\":{\"132\":1}}],[\"migratevijos\",{\"1\":{\"118\":1}}],[\"migrateuniversaloj\",{\"1\":{\"117\":1}}],[\"migratesyzoj\",{\"1\":{\"116\":1}}],[\"migratehustoj\",{\"1\":{\"115\":1}}],[\"migrate\",{\"0\":{\"114\":1},\"1\":{\"80\":1,\"85\":1}}],[\"mid\",{\"1\":{\"41\":1}}],[\"mit\",{\"1\":{\"30\":1,\"75\":2}}],[\"miit\",{\"1\":{\"19\":1}}],[\"mirai\",{\"1\":{\"3\":1}}],[\"more\",{\"1\":{\"222\":1}}],[\"mount\",{\"1\":{\"109\":2,\"132\":1,\"137\":1}}],[\"mongorestore\",{\"1\":{\"159\":1}}],[\"mongodump\",{\"1\":{\"158\":1}}],[\"mongodb\",{\"0\":{\"24\":1},\"1\":{\"33\":1,\"48\":2,\"77\":1,\"81\":2,\"156\":1,\"158\":1,\"159\":2,\"166\":2}}],[\"mono\",{\"1\":{\"132\":1,\"136\":1}}],[\"monaco\",{\"1\":{\"107\":2,\"132\":12}}],[\"mode\",{\"1\":{\"222\":1}}],[\"modes\",{\"1\":{\"107\":1}}],[\"model\",{\"1\":{\"41\":1,\"54\":1,\"77\":2}}],[\"module\",{\"1\":{\"73\":1,\"77\":2}}],[\"modified\",{\"1\":{\"3\":1}}],[\"mozrequestanimationframe||window\",{\"1\":{\"30\":1}}],[\"moveto\",{\"1\":{\"30\":1}}],[\"moe>\",{\"1\":{\"75\":1}}],[\"moe\",{\"1\":{\"1\":1,\"163\":6}}],[\"鉴于\",{\"1\":{\"3\":1}}],[\"请前往控制面板中查看\",{\"1\":{\"222\":1}}],[\"请详细至子分类\",{\"1\":{\"222\":2}}],[\"请尝试\",{\"1\":{\"214\":1}}],[\"请点击题库页面右下角的\",{\"1\":{\"207\":1}}],[\"请检查下述列表是否均按需求配置完成\",{\"1\":{\"172\":1}}],[\"请每次备份后检查生成的备份文件的大小和内容\",{\"1\":{\"158\":1}}],[\"请请不要在数据库运行时直接拷贝数据库文件夹\",{\"1\":{\"158\":1}}],[\"请定期备份\",{\"1\":{\"157\":1}}],[\"请完成数据库配置\",{\"1\":{\"147\":1}}],[\"请在\",{\"1\":{\"141\":1}}],[\"请根据你使用的存储端类型阅读对应教程\",{\"1\":{\"140\":1}}],[\"请根据您数据库的安装填写\",{\"1\":{\"51\":1}}],[\"请直接修改\",{\"1\":{\"160\":1}}],[\"请直接编辑位于\",{\"0\":{\"139\":1}}],[\"请直接使用文件夹\",{\"1\":{\"86\":1}}],[\"请百度搜索\",{\"1\":{\"135\":1}}],[\"请务必确保文件名中含有数字\",{\"1\":{\"221\":1}}],[\"请务必确认您使用了支持\",{\"1\":{\"47\":1}}],[\"请务必定期备份数据库\",{\"1\":{\"134\":1}}],[\"请避免使用\",{\"1\":{\"134\":1}}],[\"请尽量不要使用突发性能实例或共享型实例\",{\"1\":{\"134\":1}}],[\"请选择适合您的方案并继续\",{\"1\":{\"133\":1}}],[\"请更新到\",{\"1\":{\"130\":1}}],[\"请先进入一个讨论节点\",{\"1\":{\"179\":1}}],[\"请先使用\",{\"1\":{\"160\":1}}],[\"请先停止正在运行的\",{\"1\":{\"115\":1,\"118\":1}}],[\"请先完成\",{\"1\":{\"115\":1,\"118\":1}}],[\"请以\",{\"1\":{\"95\":1}}],[\"请勿删除\",{\"1\":{\"137\":1}}],[\"请勿安装\",{\"1\":{\"93\":1}}],[\"请勿手动操作\",{\"1\":{\"62\":1}}],[\"请不要把备份数据和\",{\"1\":{\"158\":1}}],[\"请不要在生产环境中使用\",{\"1\":{\"135\":1}}],[\"请不要填写此项\",{\"1\":{\"115\":1}}],[\"请不要将插件与插件嵌套摆放\",{\"1\":{\"86\":1}}],[\"请不要启用来历不明的插件\",{\"1\":{\"84\":1}}],[\"请不要要求增加相关功能\",{\"1\":{\"9\":1}}],[\"请求第三方的\",{\"1\":{\"73\":1}}],[\"请求\",{\"1\":{\"68\":1}}],[\"请求流程\",{\"1\":{\"68\":1}}],[\"请求缺失或是修改的文件\",{\"1\":{\"44\":1}}],[\"请按照下文说明创建管理员账户即可正常使用\",{\"1\":{\"51\":1}}],[\"请注意配置\",{\"1\":{\"139\":1}}],[\"请注意系统设置中的\",{\"1\":{\"139\":1}}],[\"请注意不要误删\",{\"1\":{\"136\":1}}],[\"请注意备份相关文件\",{\"1\":{\"115\":1,\"118\":1}}],[\"请注意\",{\"1\":{\"51\":1,\"67\":1,\"115\":1,\"118\":1}}],[\"请安装\",{\"1\":{\"48\":1}}],[\"请确保\",{\"1\":{\"148\":1}}],[\"请确保这些端口空闲\",{\"1\":{\"135\":1}}],[\"请确保你已阅读\",{\"1\":{\"73\":1}}],[\"请确保安全组放行了\",{\"1\":{\"12\":1}}],[\"请确认您的站点已经可以访问并正常登录\",{\"1\":{\"95\":1}}],[\"请确认您的开发环境至少拥有\",{\"1\":{\"47\":1}}],[\"请确认您已阅读\",{\"1\":{\"67\":1}}],[\"请基于插件系统进行你所需要的功能添加与修改\",{\"1\":{\"47\":1}}],[\"请老实用安装脚本\",{\"1\":{\"36\":1}}],[\"请使用个性化程度更高的subtasks\",{\"1\":{\"222\":1}}],[\"请使用原\",{\"1\":{\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"请使用\",{\"1\":{\"48\":2,\"136\":1,\"163\":1,\"167\":1}}],[\"请使用现代浏览器进行操作\",{\"1\":{\"34\":1}}],[\"请使用插件api\",{\"1\":{\"21\":1}}],[\"请参照邮件服务商说明\",{\"1\":{\"142\":2}}],[\"请参照您使用的虚拟机软件说明\",{\"1\":{\"134\":1}}],[\"请参照\",{\"1\":{\"32\":1,\"48\":1,\"95\":1,\"137\":1}}],[\"请谨慎操作\",{\"1\":{\"28\":1,\"163\":1}}],[\"请重启\",{\"1\":{\"25\":1,\"115\":1,\"116\":1,\"117\":1,\"118\":1}}],[\"请自行开发相关功能\",{\"1\":{\"9\":1}}],[\"请考虑联系我们以购买许可\",{\"1\":{\"3\":1}}],[\"请提交\",{\"1\":{\"0\":1}}],[\"协议的反向代理\",{\"1\":{\"139\":1}}],[\"协议的服务\",{\"1\":{\"83\":1}}],[\"协议中\",{\"1\":{\"73\":1}}],[\"协议与\",{\"1\":{\"3\":1}}],[\"协议第七条\",{\"1\":{\"3\":1}}],[\"h文件上传到附加文件列表中\",{\"1\":{\"199\":1}}],[\"higher\",{\"1\":{\"222\":1}}],[\"highlight\",{\"1\":{\"107\":1,\"132\":29}}],[\"hierarchy=0\",{\"1\":{\"113\":2}}],[\"hidden\",{\"1\":{\"77\":1}}],[\"hdu\",{\"1\":{\"81\":1}}],[\"hustoj\",{\"0\":{\"115\":1},\"1\":{\"80\":2,\"81\":1,\"85\":1,\"115\":6,\"116\":1,\"222\":1}}],[\"hustcc\",{\"1\":{\"30\":1}}],[\"how\",{\"1\":{\"214\":1}}],[\"homework\",{\"1\":{\"189\":1}}],[\"home\",{\"1\":{\"115\":1}}],[\"homehandler\",{\"1\":{\"68\":4}}],[\"hoj\",{\"1\":{\"85\":2}}],[\"hosts\",{\"1\":{\"98\":1}}],[\"hostname\",{\"1\":{\"41\":1}}],[\"host\",{\"1\":{\"13\":1,\"115\":2,\"116\":2,\"118\":2,\"126\":1,\"139\":1,\"142\":1}}],[\"h\",{\"1\":{\"68\":3,\"199\":6,\"200\":2,\"222\":1}}],[\"haproxy\",{\"1\":{\"139\":1}}],[\"has\",{\"1\":{\"222\":2}}],[\"haskell\",{\"1\":{\"132\":2,\"136\":1}}],[\"hash\",{\"1\":{\"43\":1}}],[\"handle>\",{\"1\":{\"132\":1}}],[\"handle\",{\"1\":{\"132\":1,\"139\":2}}],[\"handler\",{\"1\":{\"68\":4,\"73\":2,\"77\":5}}],[\"hack\",{\"1\":{\"81\":1}}],[\"have\",{\"0\":{\"36\":1},\"1\":{\"73\":1}}],[\"h++\",{\"1\":{\"30\":1}}],[\"h=0\",{\"1\":{\"30\":1}}],[\"help\",{\"1\":{\"214\":1}}],[\"headless\",{\"1\":{\"136\":1}}],[\"headers\",{\"1\":{\"78\":1}}],[\"header\",{\"1\":{\"13\":1}}],[\"hex\",{\"1\":{\"33\":2}}],[\"height=window\",{\"1\":{\"30\":1}}],[\"herf=\",{\"1\":{\"19\":1}}],[\"html\",{\"1\":{\"19\":1,\"30\":1,\"77\":2,\"162\":1,\"214\":1}}],[\"https\",{\"1\":{\"9\":1,\"19\":1,\"30\":1,\"34\":1,\"44\":2,\"48\":1,\"49\":1,\"73\":2,\"75\":1,\"81\":1,\"98\":1,\"119\":1,\"124\":1,\"135\":4,\"141\":4,\"145\":1,\"162\":1,\"173\":1,\"202\":1,\"204\":1,\"214\":2}}],[\"http\",{\"1\":{\"3\":1,\"98\":1,\"135\":1,\"139\":1,\"141\":1,\"196\":1,\"198\":1,\"199\":1,\"200\":2,\"201\":1,\"203\":1}}],[\"hydro题目存储格式\",{\"0\":{\"197\":1},\"1\":{\"196\":1}}],[\"hydro常见题型的制做心得\",{\"0\":{\"196\":1}}],[\"hydrohydro\",{\"1\":{\"148\":2,\"151\":2}}],[\"hydro会在服务初始化完成后调用该函数\",{\"1\":{\"77\":1}}],[\"hydrojudge\",{\"0\":{\"94\":1},\"1\":{\"48\":2,\"80\":1,\"85\":1,\"97\":4,\"98\":2,\"99\":1,\"103\":2,\"105\":1,\"107\":1,\"137\":1}}],[\"hydro开发环境目前仅支持\",{\"1\":{\"48\":1}}],[\"hydrooj的剪贴板组件\",{\"1\":{\"75\":1}}],[\"hydrooj\",{\"0\":{\"127\":1},\"1\":{\"14\":1,\"16\":2,\"21\":1,\"25\":4,\"27\":1,\"37\":2,\"50\":4,\"51\":1,\"54\":1,\"68\":2,\"70\":1,\"72\":2,\"73\":2,\"75\":2,\"76\":2,\"77\":2,\"85\":16,\"86\":7,\"87\":1,\"89\":3,\"90\":2,\"97\":4,\"103\":3,\"123\":3,\"126\":2,\"127\":1,\"128\":1,\"130\":1,\"135\":1,\"148\":2,\"149\":2,\"150\":1,\"151\":2,\"152\":1,\"153\":4,\"154\":9,\"156\":1,\"157\":2,\"160\":1,\"166\":1,\"167\":1,\"168\":2,\"169\":1,\"173\":1,\"209\":1}}],[\"hydro\",{\"0\":{\"15\":1,\"26\":1,\"31\":1,\"49\":1,\"51\":1,\"133\":1,\"147\":1,\"205\":1,\"209\":1},\"1\":{\"0\":3,\"1\":2,\"3\":7,\"4\":2,\"9\":1,\"15\":1,\"16\":1,\"21\":3,\"23\":1,\"24\":1,\"26\":1,\"27\":1,\"33\":1,\"44\":2,\"45\":2,\"46\":1,\"48\":2,\"49\":5,\"51\":2,\"62\":1,\"70\":1,\"72\":1,\"73\":1,\"75\":3,\"77\":3,\"79\":1,\"80\":7,\"81\":5,\"84\":1,\"85\":2,\"97\":4,\"98\":5,\"101\":1,\"105\":1,\"106\":1,\"107\":2,\"109\":3,\"111\":5,\"115\":4,\"116\":1,\"117\":1,\"118\":4,\"119\":1,\"131\":1,\"132\":1,\"134\":2,\"135\":5,\"136\":6,\"137\":1,\"139\":4,\"140\":2,\"141\":3,\"144\":1,\"145\":1,\"148\":6,\"156\":1,\"158\":1,\"159\":2,\"162\":2,\"163\":2,\"165\":1,\"166\":3,\"167\":4,\"168\":1,\"173\":2,\"177\":1,\"191\":1,\"202\":1,\"204\":1,\"205\":2,\"209\":1,\"210\":1}}],[\"插件需要\",{\"1\":{\"93\":1}}],[\"插件对站点的所有内容具有完全的访问权限\",{\"1\":{\"84\":1}}],[\"插件直接导入\",{\"1\":{\"80\":1}}],[\"插件绝对路径\",{\"1\":{\"76\":1}}],[\"插件开发\",{\"1\":{\"73\":1}}],[\"插件编写\",{\"1\":{\"68\":1}}],[\"插件的情况下才会生效\",{\"1\":{\"51\":1}}],[\"插件说明部分完成沙箱的安装配置\",{\"1\":{\"48\":1}}],[\"插件\",{\"0\":{\"50\":1,\"84\":1,\"123\":1},\"1\":{\"3\":1,\"47\":1,\"80\":2,\"90\":1,\"173\":1,\"214\":1}}],[\"同样支持在\",{\"1\":{\"134\":1}}],[\"同样需要以\",{\"1\":{\"3\":1}}],[\"同时设置添加回源http请求头\",{\"1\":{\"146\":1}}],[\"同时欢迎使用其他存储类型的用户向我们提供详细的存储教程\",{\"1\":{\"140\":1}}],[\"同时\",{\"1\":{\"83\":1}}],[\"同时支持\",{\"1\":{\"68\":1}}],[\"同时群内可能存在部分令您感到不适或感到冒犯的内容\",{\"1\":{\"1\":1}}],[\"同\",{\"1\":{\"43\":1}}],[\"同学们应该理解\",{\"1\":{\"10\":1}}],[\"扩展名应为\",{\"1\":{\"222\":1}}],[\"扩展阅读\",{\"1\":{\"46\":1}}],[\"扩展\",{\"1\":{\"3\":1,\"80\":1}}],[\"若上传文件为\",{\"1\":{\"221\":1}}],[\"若留空则使用自动分配的数字题号\",{\"1\":{\"207\":1}}],[\"若同时存在多个语言的题面\",{\"1\":{\"205\":1}}],[\"若因为删除训练计划内题目导致训练计划无法打开\",{\"1\":{\"190\":1}}],[\"若因为删除作业\",{\"1\":{\"189\":1}}],[\"若有需要\",{\"1\":{\"194\":1}}],[\"若有多个则使用逗号分隔\",{\"1\":{\"190\":2}}],[\"若有必要\",{\"1\":{\"3\":1}}],[\"若选择后\",{\"1\":{\"179\":1}}],[\"若确需要\",{\"1\":{\"156\":1}}],[\"若操作失误带来的影响通常是灾难性的\",{\"1\":{\"156\":1}}],[\"若一切正常\",{\"1\":{\"148\":1}}],[\"若不想让普通用户上传文件\",{\"1\":{\"192\":1}}],[\"若不具有此权限\",{\"1\":{\"192\":1}}],[\"若不给出则按照默认设置\",{\"1\":{\"147\":1}}],[\"若不清楚请填写邮件地址\",{\"1\":{\"142\":1}}],[\"若要在训练中创建三个章节\",{\"1\":{\"190\":1}}],[\"若要获得更精确的内存计量\",{\"1\":{\"113\":1}}],[\"若要重新打开\",{\"1\":{\"25\":1}}],[\"若\",{\"1\":{\"78\":1,\"153\":1}}],[\"若需创建用户则从前往后尝试\",{\"1\":{\"73\":1}}],[\"若需要使用\",{\"1\":{\"48\":1}}],[\"若无说明则预填写的内容即为默认值\",{\"1\":{\"222\":1}}],[\"若无要求则留空\",{\"1\":{\"190\":1}}],[\"若无则填写空字符串\",{\"1\":{\"115\":1,\"116\":1,\"118\":1}}],[\"若无此后缀表示捕获该路由的所有请求\",{\"1\":{\"68\":1}}],[\"若无密码则留空\",{\"1\":{\"51\":1}}],[\"若无效则跳转登录逻辑\",{\"1\":{\"40\":1}}],[\"若使用标准\",{\"1\":{\"222\":1}}],[\"若使用的路由器不支持该功能可以在选手机使用\",{\"1\":{\"172\":1}}],[\"若使用反向代理\",{\"1\":{\"139\":1}}],[\"若使用\",{\"1\":{\"48\":1}}],[\"若某用户具有\",{\"1\":{\"46\":1}}],[\"若推送的评测任务中使用了的测试数据缺失\",{\"1\":{\"44\":1}}],[\"若登录失效\",{\"1\":{\"40\":1}}],[\"若您想要创建训练\",{\"1\":{\"190\":1}}],[\"若您想要创建比赛\",{\"1\":{\"189\":1}}],[\"若您想发布一个讨论\",{\"1\":{\"179\":1}}],[\"若您的\",{\"1\":{\"118\":1}}],[\"若您的文件超过大小限制\",{\"1\":{\"92\":1}}],[\"若您使用自动脚本安装\",{\"1\":{\"157\":1}}],[\"若您使用\",{\"1\":{\"118\":1,\"139\":1}}],[\"若您在配置完评测机后\",{\"1\":{\"95\":1}}],[\"若您需要对这些模块闭源处理\",{\"1\":{\"3\":1}}],[\"若您对源码做出修改\",{\"1\":{\"3\":1}}],[\"若对此有顾虑请勿加群\",{\"1\":{\"1\":1}}],[\"本程序的输出将作为用户程序的输入\",{\"1\":{\"200\":1}}],[\"本题型的特点是不需要手工给出每个用例的预期输出\",{\"1\":{\"200\":1}}],[\"本题要额外上传两个文件\",{\"1\":{\"199\":1}}],[\"本题的ac代码和类型一的一样\",{\"1\":{\"200\":1}}],[\"本题的ac代码为\",{\"1\":{\"199\":1}}],[\"本题的\",{\"1\":{\"198\":1}}],[\"本类型和类型一的区别在于出题者要向做题者提供一个额外的头文件\",{\"1\":{\"199\":1}}],[\"本文档中用到的字段有\",{\"1\":{\"204\":1}}],[\"本文为作者使用hydro时的实验记录\",{\"1\":{\"196\":1}}],[\"本文部分内容同样适用于\",{\"1\":{\"171\":1}}],[\"本镜像基于标准\",{\"1\":{\"172\":1}}],[\"本指南适用于希望进行线下赛\",{\"1\":{\"171\":1}}],[\"本地\",{\"1\":{\"81\":4}}],[\"本例中未实现删除功能\",{\"1\":{\"77\":1}}],[\"本页和各大浏览器均达成了合作\",{\"0\":{\"6\":1}}],[\"本仓库\",{\"1\":{\"3\":1}}],[\"本项目中的\",{\"1\":{\"2\":1}}],[\"本项目\",{\"1\":{\"0\":1}}],[\"oss\",{\"1\":{\"214\":1}}],[\"osinfo\",{\"1\":{\"41\":1}}],[\"object\",{\"1\":{\"214\":2}}],[\"objective\",{\"1\":{\"203\":1,\"219\":1,\"222\":1}}],[\"objects\",{\"1\":{\"124\":1}}],[\"ofs\",{\"1\":{\"201\":2}}],[\"ofstream\",{\"1\":{\"201\":1}}],[\"of\",{\"1\":{\"200\":2}}],[\"ok\",{\"1\":{\"200\":2}}],[\"ouf\",{\"1\":{\"200\":1}}],[\"out文件进行读写\",{\"1\":{\"204\":1}}],[\"out的内容进行对比\",{\"1\":{\"201\":1}}],[\"outlook\",{\"1\":{\"142\":1}}],[\"output\",{\"1\":{\"45\":1,\"139\":1,\"200\":5,\"202\":25,\"222\":7}}],[\"out\",{\"1\":{\"44\":3,\"198\":1,\"201\":2,\"202\":1,\"205\":3,\"221\":4,\"222\":10}}],[\"ocaml\",{\"1\":{\"132\":2}}],[\"o2\",{\"1\":{\"110\":1}}],[\"oi\",{\"1\":{\"81\":5,\"115\":1}}],[\"oi排名\",{\"1\":{\"20\":1}}],[\"oi排名跟普通排名有何区别\",{\"0\":{\"20\":1}}],[\"oauth\",{\"1\":{\"73\":10}}],[\"owner\",{\"1\":{\"43\":1,\"54\":1,\"55\":1,\"77\":3}}],[\"option\",{\"1\":{\"222\":3}}],[\"optional\",{\"1\":{\"43\":1,\"222\":1}}],[\"openjdk\",{\"1\":{\"136\":1}}],[\"opencloudos\",{\"1\":{\"134\":1}}],[\"operation\",{\"1\":{\"68\":1,\"77\":6}}],[\"opcount\",{\"0\":{\"64\":1}}],[\"oplog\",{\"0\":{\"58\":1}}],[\"opacity\",{\"1\":{\"30\":2}}],[\"onsite\",{\"1\":{\"173\":2}}],[\"onlyoffice\",{\"1\":{\"85\":1,\"214\":1}}],[\"online\",{\"1\":{\"0\":1}}],[\"on\",{\"1\":{\"68\":1,\"77\":1}}],[\"onmouseout=function\",{\"1\":{\"30\":1}}],[\"onmousemove=function\",{\"1\":{\"30\":1}}],[\"onresize=n\",{\"1\":{\"30\":1}}],[\"o=o\",{\"1\":{\"30\":1}}],[\"o=document\",{\"1\":{\"30\":1}}],[\"o=n+1\",{\"1\":{\"30\":1}}],[\"o++\",{\"1\":{\"30\":1}}],[\"o\",{\"1\":{\"202\":2}}],[\"database\",{\"1\":{\"124\":1}}],[\"datadir\",{\"1\":{\"115\":2,\"116\":2}}],[\"data\",{\"0\":{\"15\":1},\"1\":{\"15\":1,\"21\":2,\"43\":1,\"115\":1,\"116\":1,\"124\":2,\"139\":1,\"140\":1,\"158\":1,\"159\":3,\"162\":2}}],[\"dark\",{\"1\":{\"27\":3}}],[\"db\",{\"1\":{\"21\":1,\"33\":1,\"77\":2,\"132\":1,\"156\":1,\"159\":1}}],[\"diffutils\",{\"1\":{\"136\":1,\"137\":1}}],[\"diagnostics\",{\"1\":{\"132\":1}}],[\"dict\",{\"1\":{\"71\":1}}],[\"disposition\",{\"1\":{\"214\":1}}],[\"display\",{\"1\":{\"132\":30}}],[\"disable\",{\"1\":{\"101\":1}}],[\"distro\",{\"1\":{\"41\":1}}],[\"discuss\",{\"1\":{\"9\":1}}],[\"dir`\",{\"1\":{\"169\":1}}],[\"dir\",{\"1\":{\"21\":1}}],[\"directory\",{\"0\":{\"15\":1,\"32\":1},\"1\":{\"222\":1}}],[\"d\",{\"1\":{\"3\":1,\"30\":1,\"44\":3,\"76\":1,\"81\":1,\"132\":2,\"135\":1,\"200\":16,\"202\":1,\"222\":2}}],[\"不会读取\",{\"1\":{\"222\":1}}],[\"不会填请留空\",{\"1\":{\"35\":1}}],[\"不存在\",{\"1\":{\"222\":1}}],[\"不同答案对应不同分数\",{\"1\":{\"219\":1}}],[\"不同服务商提供的\",{\"1\":{\"134\":1}}],[\"不需要上传其他文件\",{\"1\":{\"219\":1}}],[\"不能全为数字\",{\"1\":{\"207\":1}}],[\"不能留空\",{\"1\":{\"189\":1}}],[\"不能复制一个复制来的题目\",{\"1\":{\"183\":1}}],[\"不超过4核\",{\"1\":{\"167\":1}}],[\"不可在其他\",{\"1\":{\"173\":1}}],[\"不可登出\",{\"1\":{\"173\":1}}],[\"不可以直接操作数据库\",{\"1\":{\"156\":1}}],[\"不可移除本项目的版权声明与作者\",{\"1\":{\"3\":1}}],[\"不建议删除\",{\"1\":{\"136\":2}}],[\"不配置安装反向代理\",{\"1\":{\"135\":1}}],[\"不保证\",{\"1\":{\"131\":1}}],[\"不保证真实有效\",{\"1\":{\"41\":1}}],[\"不安装第三方软件会导致系统无法正常运行\",{\"1\":{\"85\":1,\"90\":1}}],[\"不支持\",{\"1\":{\"81\":1,\"134\":1}}],[\"不允许查看\",{\"1\":{\"68\":1,\"183\":1}}],[\"不推荐\",{\"1\":{\"37\":1}}],[\"不要更新pm2\",{\"1\":{\"168\":1}}],[\"不要折腾开发模式\",{\"1\":{\"36\":1}}],[\"不要钱\",{\"1\":{\"31\":1}}],[\"不要多加换行\",{\"1\":{\"30\":1}}],[\"不要直接改代码\",{\"1\":{\"21\":1}}],[\"不要贪图题目数量而忽视其质量\",{\"1\":{\"17\":1}}],[\"不要导入过多你暂时用不上的题目\",{\"1\":{\"17\":1}}],[\"不得不对所有人提交的答案的形式进行限定\",{\"1\":{\"10\":1}}],[\"不得以宣传为目的使用作者姓名\",{\"1\":{\"3\":1}}],[\"不和谐事件\",{\"1\":{\"3\":1}}],[\"c1\",{\"1\":{\"222\":4}}],[\"c11\",{\"1\":{\"132\":1}}],[\"cena\",{\"1\":{\"222\":1}}],[\"centos\",{\"1\":{\"134\":3}}],[\"cin\",{\"1\":{\"200\":1}}],[\"cin>>a>>b\",{\"1\":{\"198\":1,\"199\":1,\"200\":1}}],[\"city\",{\"1\":{\"93\":1}}],[\"csv\",{\"1\":{\"163\":2}}],[\"css\",{\"1\":{\"146\":1}}],[\"csstext=\",{\"1\":{\"30\":1}}],[\"csrftokenerror\",{\"1\":{\"139\":1}}],[\"csharp\",{\"1\":{\"132\":2}}],[\"cs\",{\"1\":{\"132\":2}}],[\"cpp\",{\"1\":{\"132\":14,\"222\":1}}],[\"cpu\",{\"1\":{\"41\":1,\"95\":1,\"112\":2,\"134\":4}}],[\"cmdline\",{\"1\":{\"113\":2}}],[\"cwd\",{\"1\":{\"109\":1}}],[\"cfg\",{\"1\":{\"124\":3}}],[\"cf\",{\"1\":{\"81\":1}}],[\"cgroup2\",{\"1\":{\"113\":2}}],[\"cgroup\",{\"1\":{\"80\":1,\"95\":1,\"113\":7}}],[\"ctx\",{\"1\":{\"68\":4,\"73\":3,\"77\":2}}],[\"ctrl+点击文件名\",{\"1\":{\"34\":1}}],[\"ctrl\",{\"0\":{\"6\":1}}],[\"cd\",{\"1\":{\"49\":1,\"169\":1}}],[\"cdn\",{\"0\":{\"145\":1,\"146\":1},\"1\":{\"44\":2,\"144\":2,\"145\":4,\"146\":5}}],[\"currentsystem\",{\"1\":{\"137\":1}}],[\"currentloadirq\",{\"1\":{\"41\":1}}],[\"currentloadidle\",{\"1\":{\"41\":1}}],[\"currentloadnice\",{\"1\":{\"41\":1}}],[\"currentloadsystem\",{\"1\":{\"41\":1}}],[\"currentloaduser\",{\"1\":{\"41\":1}}],[\"currentload\",{\"1\":{\"41\":1}}],[\"curl\",{\"1\":{\"48\":1,\"98\":1,\"135\":2}}],[\"chk\",{\"1\":{\"222\":1}}],[\"char\",{\"1\":{\"198\":1,\"199\":1,\"200\":3,\"201\":1}}],[\"channel\",{\"1\":{\"124\":2}}],[\"checkpriv\",{\"1\":{\"77\":1}}],[\"checker\",{\"1\":{\"45\":1,\"200\":6,\"204\":3,\"222\":2}}],[\"chrome\",{\"1\":{\"27\":1}}],[\"ccr\",{\"1\":{\"222\":1}}],[\"cc11o2\",{\"1\":{\"222\":1}}],[\"cc11\",{\"1\":{\"43\":1}}],[\"cc\",{\"1\":{\"43\":1,\"200\":4,\"204\":1,\"222\":5}}],[\"c+\",{\"1\":{\"30\":1}}],[\"c++\",{\"0\":{\"110\":1},\"1\":{\"22\":1,\"110\":1,\"132\":1,\"136\":1,\"222\":1}}],[\"c++语言的同学来说\",{\"1\":{\"10\":1}}],[\"caicpc\",{\"1\":{\"172\":2}}],[\"callback`\",{\"1\":{\"73\":1}}],[\"callback\",{\"1\":{\"73\":4}}],[\"cases\",{\"1\":{\"200\":2,\"202\":5,\"204\":1,\"222\":10}}],[\"case\",{\"1\":{\"45\":1}}],[\"cache\",{\"1\":{\"41\":1,\"170\":1}}],[\"cached\",{\"1\":{\"41\":1}}],[\"canvas\",{\"1\":{\"30\":2}}],[\"caddyfile\",{\"1\":{\"139\":1}}],[\"caddy\",{\"0\":{\"13\":1,\"139\":1},\"1\":{\"135\":1,\"139\":3,\"166\":1}}],[\"copied\",{\"1\":{\"222\":1}}],[\"cos\",{\"1\":{\"141\":3}}],[\"coreutils\",{\"1\":{\"137\":1}}],[\"core\",{\"1\":{\"132\":1}}],[\"cores\",{\"1\":{\"41\":1}}],[\"cout\",{\"1\":{\"198\":1,\"199\":1,\"200\":2}}],[\"could\",{\"1\":{\"113\":1}}],[\"count\",{\"1\":{\"30\":1}}],[\"collect\",{\"1\":{\"137\":1,\"170\":1}}],[\"collections\",{\"1\":{\"77\":1}}],[\"collection\",{\"1\":{\"77\":1}}],[\"coll\",{\"1\":{\"77\":3}}],[\"color=always\",{\"1\":{\"110\":2}}],[\"color\",{\"1\":{\"30\":1}}],[\"codeforces\",{\"0\":{\"132\":1},\"1\":{\"85\":1,\"132\":69}}],[\"code\",{\"1\":{\"43\":2,\"45\":3,\"56\":1,\"68\":1,\"73\":3}}],[\"codepage\",{\"1\":{\"41\":1}}],[\"codename\",{\"1\":{\"41\":1}}],[\"cookie\",{\"1\":{\"41\":1,\"44\":1}}],[\"conf\",{\"1\":{\"112\":1}}],[\"confirm\",{\"1\":{\"77\":1}}],[\"configuration\",{\"1\":{\"124\":1}}],[\"config\",{\"1\":{\"20\":1,\"21\":1,\"24\":1,\"98\":1,\"106\":1,\"107\":1,\"124\":3,\"141\":1,\"156\":1,\"159\":1,\"199\":2,\"200\":2,\"202\":1,\"203\":1,\"205\":1,\"219\":1,\"222\":3}}],[\"consolidate\",{\"1\":{\"124\":1}}],[\"const\",{\"1\":{\"73\":6,\"77\":6}}],[\"consider\",{\"0\":{\"36\":1}}],[\"context\",{\"1\":{\"68\":4,\"73\":2}}],[\"content\",{\"1\":{\"54\":1,\"55\":1,\"77\":8,\"214\":1}}],[\"contesttype\",{\"1\":{\"115\":2,\"116\":1}}],[\"contest\",{\"1\":{\"43\":2,\"189\":1}}],[\"connection\",{\"1\":{\"47\":1,\"156\":1}}],[\"connect\",{\"1\":{\"47\":2}}],[\"conn\",{\"1\":{\"40\":1,\"41\":1}}],[\"concat\",{\"1\":{\"30\":1}}],[\"comment\",{\"1\":{\"132\":29}}],[\"commands\",{\"0\":{\"36\":1}}],[\"compactions\",{\"1\":{\"124\":1}}],[\"compress\",{\"1\":{\"124\":1}}],[\"compose\",{\"1\":{\"118\":1}}],[\"compile\",{\"1\":{\"110\":1}}],[\"compiler\",{\"1\":{\"45\":1}}],[\"compilertext\",{\"1\":{\"45\":1}}],[\"com\",{\"1\":{\"30\":1,\"49\":1,\"73\":3,\"75\":1,\"119\":1,\"124\":1,\"141\":3,\"142\":2,\"153\":2,\"173\":1,\"214\":2}}],[\"clang++17\",{\"1\":{\"132\":1}}],[\"clang等是考察程序本身的内存申请空间\",{\"1\":{\"22\":1}}],[\"class1\",{\"1\":{\"163\":2}}],[\"class\",{\"1\":{\"77\":2}}],[\"clean\",{\"1\":{\"170\":1}}],[\"cleanup\",{\"1\":{\"77\":2}}],[\"clearrect\",{\"1\":{\"30\":1}}],[\"cloud\",{\"1\":{\"134\":1,\"214\":1}}],[\"clone\",{\"1\":{\"49\":1}}],[\"close\",{\"0\":{\"11\":2}}],[\"client\",{\"1\":{\"73\":3,\"85\":1,\"173\":1}}],[\"clienty\",{\"1\":{\"30\":1}}],[\"clientx\",{\"1\":{\"30\":1}}],[\"clientheight\",{\"1\":{\"30\":1}}],[\"clientheight||document\",{\"1\":{\"30\":1}}],[\"clientwidth\",{\"1\":{\"30\":1}}],[\"clientwidth||document\",{\"1\":{\"30\":1}}],[\"cli\",{\"0\":{\"147\":1},\"1\":{\"25\":2,\"37\":1,\"77\":1,\"135\":1,\"147\":2,\"148\":2,\"149\":2,\"150\":1,\"151\":2,\"152\":1,\"153\":4,\"154\":10,\"209\":1}}],[\"cn\",{\"1\":{\"19\":1,\"205\":1}}],[\"createelement\",{\"1\":{\"30\":1}}],[\"create\",{\"1\":{\"27\":1,\"75\":1,\"77\":6,\"119\":1,\"148\":2,\"154\":1,\"160\":1,\"185\":1,\"192\":1,\"207\":1}}],[\"crontab\",{\"1\":{\"14\":2}}],[\"criyle\",{\"1\":{\"4\":1,\"95\":1}}],[\"c\",{\"0\":{\"110\":1},\"1\":{\"3\":1,\"30\":5,\"110\":3,\"111\":1,\"124\":1,\"132\":8,\"136\":2,\"200\":9,\"203\":1,\"218\":1,\"222\":3}}],[\"bgcolor=\",{\"1\":{\"214\":1}}],[\"bit\",{\"1\":{\"132\":1}}],[\"bin\",{\"1\":{\"110\":1,\"111\":1,\"136\":1,\"137\":1}}],[\"bio\",{\"1\":{\"73\":2}}],[\"blob\",{\"1\":{\"124\":1}}],[\"blog\",{\"1\":{\"85\":1}}],[\"blacklist\",{\"0\":{\"59\":1},\"1\":{\"153\":3}}],[\"boolean\",{\"1\":{\"77\":3}}],[\"body\",{\"1\":{\"30\":2,\"73\":11,\"77\":3,\"78\":2}}],[\"brand\",{\"1\":{\"41\":1}}],[\"bucket\",{\"1\":{\"141\":2}}],[\"busybox\",{\"1\":{\"136\":1}}],[\"builtins\",{\"1\":{\"137\":1}}],[\"builtin\",{\"1\":{\"101\":1}}],[\"buildinfo\",{\"1\":{\"137\":2}}],[\"buildenv\",{\"1\":{\"137\":1}}],[\"build\",{\"1\":{\"49\":1,\"51\":1,\"52\":1,\"137\":2}}],[\"buffer\",{\"1\":{\"124\":1}}],[\"buffers\",{\"1\":{\"41\":1}}],[\"buffcache\",{\"1\":{\"41\":1}}],[\"bug\",{\"1\":{\"0\":1,\"51\":1}}],[\"baseurl\",{\"1\":{\"135\":1}}],[\"bash\",{\"1\":{\"111\":1,\"136\":1,\"137\":2}}],[\"bar\",{\"1\":{\"135\":1,\"163\":2}}],[\"backend\",{\"1\":{\"124\":1}}],[\"back\",{\"1\":{\"77\":1}}],[\"backup\",{\"1\":{\"14\":1,\"21\":1,\"157\":1}}],[\"backuphydrooj\",{\"1\":{\"14\":1}}],[\"badge\",{\"1\":{\"33\":1}}],[\"be\",{\"1\":{\"222\":1}}],[\"before\",{\"1\":{\"68\":2}}],[\"bearer\",{\"1\":{\"41\":1}}],[\"benchmark\",{\"1\":{\"37\":1}}],[\"been\",{\"0\":{\"36\":1},\"1\":{\"222\":1}}],[\"beginpath\",{\"1\":{\"30\":1}}],[\"beian\",{\"1\":{\"19\":1}}],[\"bytes\",{\"1\":{\"43\":1,\"113\":1}}],[\"by\",{\"1\":{\"3\":3}}],[\"b\",{\"1\":{\"3\":1,\"198\":1,\"199\":2,\"200\":8,\"201\":1,\"203\":3,\"205\":1,\"218\":1,\"219\":2,\"222\":2}}],[\"70\",{\"1\":{\"222\":1}}],[\"72h\",{\"1\":{\"139\":1}}],[\"7\",{\"1\":{\"3\":3,\"41\":1,\"81\":1,\"132\":10,\"202\":1,\"214\":1}}],[\"您无需手动上传\",{\"1\":{\"222\":1}}],[\"您无法查看作业中的题目\",{\"1\":{\"180\":1}}],[\"您只需提供\",{\"1\":{\"221\":1}}],[\"您也可以创建\",{\"1\":{\"194\":1}}],[\"您也可以联系我们购买其他授权\",{\"1\":{\"2\":1}}],[\"您将在此域中拥有管理员权限\",{\"1\":{\"186\":1}}],[\"您仍然可以提交题目\",{\"1\":{\"180\":1}}],[\"您仍然可以订正其中的题目\",{\"1\":{\"178\":1,\"180\":1}}],[\"您与他人的做题情况会被实时统计在\",{\"1\":{\"180\":1}}],[\"您的腾讯云\",{\"1\":{\"141\":2}}],[\"您应当能在上方导航栏看到控制面板入口\",{\"1\":{\"135\":1}}],[\"您应当能够在\",{\"1\":{\"115\":1,\"118\":1}}],[\"您应该预先下载您所要支持的语言的编译器\",{\"1\":{\"95\":1}}],[\"您还需要前往\",{\"1\":{\"107\":1}}],[\"您还需要将以下文件放在该目录\",{\"1\":{\"27\":1}}],[\"您需要留意运行此指令返回的数字\",{\"1\":{\"152\":1}}],[\"您需要按照如下方式手动安装沙箱服务\",{\"1\":{\"95\":1}}],[\"您需要重新启动沙箱\",{\"1\":{\"95\":1}}],[\"您需要将以下文件放在该目录中\",{\"1\":{\"27\":1}}],[\"您可使用\",{\"1\":{\"157\":1}}],[\"您可按需更改\",{\"1\":{\"28\":1}}],[\"您可以直接选择文件\",{\"1\":{\"221\":1}}],[\"您可以先创建题目\",{\"1\":{\"214\":1}}],[\"您可以考虑使用内容分发网络\",{\"1\":{\"144\":1}}],[\"您可以通过检查\",{\"1\":{\"113\":1}}],[\"您可以通过一键安装脚本快速安装独立评测机\",{\"1\":{\"94\":1}}],[\"您可以使用\",{\"1\":{\"99\":1}}],[\"您可以上传\",{\"1\":{\"92\":1}}],[\"您可以在题目右侧\",{\"1\":{\"216\":1}}],[\"您可以在作业的详情页面中\",{\"1\":{\"180\":1}}],[\"您可以在比赛的详细界面内点击\",{\"1\":{\"178\":1}}],[\"您可以在\",{\"1\":{\"51\":1,\"187\":1,\"189\":1,\"190\":1}}],[\"您可以在遵守\",{\"1\":{\"2\":1}}],[\"您可以尝试换源\",{\"1\":{\"47\":1}}],[\"您可以以\",{\"1\":{\"3\":1}}],[\"您在使用本项目时\",{\"1\":{\"3\":1}}],[\"如下面所示\",{\"1\":{\"199\":1}}],[\"如下图所示\",{\"1\":{\"197\":1,\"198\":2,\"199\":1}}],[\"如下配置\",{\"1\":{\"132\":1}}],[\"如member\",{\"1\":{\"195\":1}}],[\"如创建题目\",{\"1\":{\"193\":1}}],[\"如创建用户\",{\"1\":{\"192\":1}}],[\"如创建邮箱为\",{\"1\":{\"148\":1}}],[\"如不同班级\",{\"1\":{\"185\":1}}],[\"如将\",{\"1\":{\"151\":1}}],[\"如设置\",{\"1\":{\"149\":1}}],[\"如想了解详细安装方法请前往\",{\"1\":{\"131\":1}}],[\"如仅安装插件不配置\",{\"1\":{\"90\":1}}],[\"如仅安装不配置\",{\"1\":{\"85\":1}}],[\"如\",{\"1\":{\"77\":1,\"145\":1,\"162\":1,\"205\":2}}],[\"如登陆状态\",{\"1\":{\"65\":1}}],[\"如题目的提交状态\",{\"1\":{\"55\":1}}],[\"如您没有相关使用经验请仅建立并配置资源\",{\"1\":{\"146\":1}}],[\"如您希望改善\",{\"1\":{\"144\":1}}],[\"如您需要可运行安装脚本一键迁移\",{\"1\":{\"117\":1}}],[\"如您需要可与我们联系\",{\"1\":{\"0\":1}}],[\"如您的服务器不满足该软件要求不建议安装\",{\"1\":{\"90\":1}}],[\"如您使用\",{\"1\":{\"48\":1}}],[\"如何在背景中添加线条特效\",{\"0\":{\"30\":1}}],[\"如何重置数据\",{\"0\":{\"28\":1}}],[\"如何修改网站图标\",{\"0\":{\"27\":1}}],[\"如何关闭\",{\"0\":{\"25\":1}}],[\"如何限制未登录用户访问\",{\"0\":{\"18\":1}}],[\"如何快速上手了解系统功能\",{\"0\":{\"9\":1}}],[\"如果设置测试方式为interactive\",{\"1\":{\"204\":1}}],[\"如果指定了测试程序时\",{\"1\":{\"204\":1}}],[\"如果某个子任务没有提供cases部分时\",{\"1\":{\"202\":1}}],[\"如果想在本地建立好题目\",{\"1\":{\"197\":1}}],[\"如果\",{\"1\":{\"193\":1,\"222\":1}}],[\"如果需要对域做特殊的权限控制\",{\"1\":{\"194\":1}}],[\"如果需要发气球请提早给气球打气\",{\"1\":{\"175\":1}}],[\"如果需要根据座位号自动登录\",{\"1\":{\"173\":1}}],[\"如果手动修改进程列表且已经覆盖掉保存的原列表\",{\"1\":{\"167\":1}}],[\"如果使用\",{\"1\":{\"163\":1}}],[\"如果使用其他服务商且没有发现问题\",{\"1\":{\"142\":1}}],[\"如果之前没有做过的话\",{\"1\":{\"160\":1}}],[\"如果只是想不同机器之间迁移部署\",{\"1\":{\"159\":1}}],[\"如果关闭了\",{\"1\":{\"141\":1}}],[\"如果有任何问题建议先查阅云服务商文档及咨询云服务商工程师\",{\"1\":{\"146\":1}}],[\"如果有特殊需求\",{\"1\":{\"135\":1}}],[\"如果有需要修改单题测试点数量上限等设置\",{\"1\":{\"106\":1}}],[\"如果此路径与您路径相同\",{\"1\":{\"115\":1}}],[\"如果系统使用的\",{\"1\":{\"95\":1}}],[\"如果不希望自己录入输入数据\",{\"1\":{\"200\":1}}],[\"如果不调整沙箱的空间大小\",{\"1\":{\"109\":1}}],[\"如果不使用自动脚本\",{\"1\":{\"95\":1}}],[\"如果不这样做\",{\"1\":{\"10\":1}}],[\"如果在\",{\"1\":{\"77\":1}}],[\"如果存在\",{\"1\":{\"77\":2}}],[\"如果比赛\",{\"1\":{\"43\":1}}],[\"如果客户端需要进行特殊设置\",{\"1\":{\"42\":1}}],[\"如果希望数据的分值不平均分配\",{\"1\":{\"20\":1}}],[\"如果老系统更新有疑问\",{\"1\":{\"16\":1}}],[\"如果您在使用外部的存储服务\",{\"1\":{\"214\":1}}],[\"如果您的压缩包较大无法上传我们也提供cli导入方法\",{\"1\":{\"209\":1}}],[\"如果您的服务器位于国内\",{\"1\":{\"139\":1}}],[\"如果您使用安装脚本部署\",{\"1\":{\"160\":1}}],[\"如果您使用的是\",{\"1\":{\"12\":1}}],[\"如果您预算充足\",{\"1\":{\"146\":1}}],[\"如果您为轻量使用\",{\"1\":{\"141\":1}}],[\"如果您直接复制配置示例\",{\"1\":{\"126\":1}}],[\"如果您添加了新的语言\",{\"1\":{\"107\":1}}],[\"如果您正在使用开发者模式\",{\"1\":{\"160\":1}}],[\"如果您正在使用\",{\"1\":{\"80\":3}}],[\"如果您需要编译\",{\"1\":{\"47\":1}}],[\"如果您没有过\",{\"1\":{\"47\":1}}],[\"如果您对以上条目感到不适\",{\"1\":{\"3\":1}}],[\"如果题目有测试用例\",{\"1\":{\"197\":1}}],[\"如果题目要求每两行输出之间要空一行\",{\"1\":{\"10\":1}}],[\"如果题目没有要求程序输出\",{\"1\":{\"10\":1}}],[\"如果运行过程中出现内存\",{\"1\":{\"10\":1}}],[\"如果学生程序的输出与老师之前提供的输出完全一致\",{\"1\":{\"10\":1}}],[\"如果认为自己绝不会误操作\",{\"1\":{\"9\":1}}],[\"如果你需要更加复杂的编译环境配置\",{\"1\":{\"137\":1}}],[\"如果你的服务部署在内网\",{\"1\":{\"135\":1}}],[\"如果你的机器内存较小\",{\"1\":{\"134\":1}}],[\"如果你有\",{\"1\":{\"134\":1}}],[\"如果你有需要绑定自己的域名或是改\",{\"1\":{\"9\":1}}],[\"如果你不知道这是什么\",{\"1\":{\"93\":1}}],[\"如果你正在安装一个其他途径获取的插件\",{\"1\":{\"86\":1}}],[\"如果你搞不明白这个问题\",{\"1\":{\"36\":1}}],[\"如果你钱多\",{\"1\":{\"31\":1}}],[\"如果你是在这之前安装的\",{\"1\":{\"136\":1}}],[\"如果你是\",{\"1\":{\"23\":1}}],[\"如果你没有二开很多功能的需求\",{\"1\":{\"9\":1}}],[\"如确需闭源\",{\"1\":{\"2\":1}}],[\"许可证和下述附加条款章节的前提下免费使用这些代码\",{\"1\":{\"2\":1}}],[\"02\",{\"1\":{\"132\":1}}],[\"091\",{\"1\":{\"132\":1}}],[\"000000000000000000000000\",{\"1\":{\"43\":1}}],[\"04\",{\"1\":{\"41\":1,\"134\":2}}],[\"01\",{\"1\":{\"41\":7}}],[\"03\",{\"1\":{\"30\":2,\"196\":1}}],[\"0\",{\"0\":{\"173\":1},\"1\":{\"2\":2,\"3\":1,\"25\":4,\"30\":8,\"41\":11,\"75\":4,\"95\":2,\"112\":1,\"124\":2,\"126\":2,\"132\":15,\"137\":2,\"139\":2,\"141\":2,\"153\":1,\"198\":1,\"199\":1,\"200\":1,\"201\":1,\"202\":1,\"222\":5}}],[\"34\",{\"1\":{\"132\":2}}],[\"31\",{\"1\":{\"132\":2,\"134\":1}}],[\"36\",{\"1\":{\"132\":2}}],[\"3306\",{\"1\":{\"115\":1,\"116\":1}}],[\"30\",{\"1\":{\"203\":1,\"219\":1,\"222\":1}}],[\"300\",{\"1\":{\"124\":2}}],[\"30s\",{\"1\":{\"41\":1}}],[\"3075653000\",{\"1\":{\"41\":1}}],[\"32m\",{\"1\":{\"222\":2}}],[\"32768\",{\"1\":{\"41\":2}}],[\"32\",{\"1\":{\"41\":2,\"132\":2}}],[\"32x32\",{\"1\":{\"27\":2}}],[\"3\",{\"1\":{\"2\":2,\"3\":1,\"46\":1,\"81\":1,\"119\":1,\"132\":12,\"190\":3,\"197\":1,\"198\":1,\"202\":12,\"203\":3,\"214\":3,\"218\":2,\"219\":1}}],[\"p10004\",{\"1\":{\"203\":1}}],[\"p10003\",{\"1\":{\"201\":1}}],[\"p10005\",{\"1\":{\"200\":1}}],[\"p10002\",{\"1\":{\"200\":1}}],[\"p10001\",{\"1\":{\"199\":1}}],[\"p10000\",{\"1\":{\"198\":1}}],[\"pkgs\",{\"1\":{\"137\":3}}],[\"pku\",{\"1\":{\"81\":1}}],[\"py3\",{\"1\":{\"222\":1}}],[\"py\",{\"1\":{\"222\":1}}],[\"pypy\",{\"1\":{\"132\":2}}],[\"python3\",{\"1\":{\"137\":1}}],[\"python3packages\",{\"1\":{\"136\":1}}],[\"python3minimal\",{\"1\":{\"136\":1}}],[\"pythonpackages\",{\"1\":{\"136\":1}}],[\"python2\",{\"1\":{\"136\":3}}],[\"python\",{\"0\":{\"23\":1},\"1\":{\"132\":6}}],[\"php\",{\"1\":{\"132\":2,\"136\":2}}],[\"physicalcores\",{\"1\":{\"41\":1}}],[\"pdf\",{\"1\":{\"205\":2,\"214\":5}}],[\"pdf文档等\",{\"1\":{\"197\":1}}],[\"pdict\",{\"1\":{\"70\":1}}],[\"pdocs\",{\"1\":{\"70\":1}}],[\"pdoc\",{\"1\":{\"70\":1}}],[\"psdoc\",{\"1\":{\"70\":1}}],[\"pse\",{\"1\":{\"41\":1}}],[\"personalized\",{\"1\":{\"222\":1}}],[\"perl\",{\"1\":{\"132\":2}}],[\"permission\",{\"0\":{\"193\":1},\"1\":{\"191\":1,\"193\":1}}],[\"permissionerror\",{\"1\":{\"77\":2}}],[\"perm\",{\"1\":{\"46\":1,\"191\":1,\"193\":2,\"194\":1,\"207\":1}}],[\"percentage\",{\"1\":{\"45\":2}}],[\"pin\",{\"1\":{\"179\":1}}],[\"ping\",{\"1\":{\"41\":1}}],[\"pids\",{\"1\":{\"190\":4}}],[\"pid\",{\"1\":{\"43\":2,\"44\":3,\"205\":1}}],[\"pip3\",{\"1\":{\"23\":1}}],[\"plain\",{\"1\":{\"132\":2}}],[\"platform\",{\"1\":{\"41\":1}}],[\"platinum\",{\"1\":{\"41\":1}}],[\"plugin\",{\"0\":{\"36\":1},\"1\":{\"75\":2}}],[\"please\",{\"1\":{\"10\":1,\"222\":1}}],[\"p\",{\"1\":{\"30\":1,\"81\":1,\"112\":1,\"135\":1,\"198\":1,\"199\":1,\"200\":2,\"201\":1,\"202\":1,\"203\":1}}],[\"p=2\",{\"1\":{\"30\":1}}],[\"pool\",{\"1\":{\"124\":2}}],[\"port\",{\"1\":{\"115\":2,\"116\":2,\"118\":2,\"126\":1,\"142\":1}}],[\"port=2333\",{\"1\":{\"51\":2}}],[\"poj\",{\"1\":{\"81\":1,\"85\":1}}],[\"point\",{\"1\":{\"75\":1}}],[\"postbuild\",{\"1\":{\"137\":1}}],[\"postgres\",{\"1\":{\"81\":1}}],[\"postdelete\",{\"1\":{\"77\":1}}],[\"postconfirmdelete\",{\"1\":{\"77\":1}}],[\"post\",{\"1\":{\"40\":1,\"44\":1,\"73\":1,\"77\":6}}],[\"position\",{\"1\":{\"30\":1}}],[\"powered\",{\"1\":{\"3\":2}}],[\"png\",{\"1\":{\"27\":7,\"146\":1,\"205\":1}}],[\"push\",{\"1\":{\"30\":1}}],[\"public\",{\"1\":{\"27\":1}}],[\"pull\",{\"1\":{\"0\":1,\"52\":1,\"142\":1}}],[\"prs\",{\"1\":{\"141\":1}}],[\"priority\",{\"1\":{\"222\":1}}],[\"prismjs\",{\"1\":{\"107\":1}}],[\"privilege\",{\"0\":{\"192\":1},\"1\":{\"191\":1,\"192\":1}}],[\"privileged\",{\"1\":{\"134\":1}}],[\"private\",{\"1\":{\"75\":1,\"77\":1}}],[\"priv\",{\"1\":{\"25\":1,\"46\":2,\"57\":1,\"77\":6,\"98\":1,\"150\":1,\"154\":2,\"185\":1,\"191\":1,\"192\":3}}],[\"previewed\",{\"1\":{\"214\":1}}],[\"prepare\",{\"1\":{\"77\":3}}],[\"premature\",{\"0\":{\"11\":2}}],[\"product\",{\"1\":{\"214\":1}}],[\"production\",{\"1\":{\"49\":1,\"52\":1}}],[\"probelm\",{\"1\":{\"197\":1}}],[\"problemowner\",{\"1\":{\"43\":1}}],[\"problem\",{\"0\":{\"205\":1},\"1\":{\"43\":1,\"44\":1,\"154\":2,\"162\":1,\"197\":1,\"205\":4,\"207\":1,\"209\":1}}],[\"proxy\",{\"1\":{\"139\":1}}],[\"prometheus\",{\"1\":{\"85\":1}}],[\"prom\",{\"1\":{\"85\":1}}],[\"promise\",{\"1\":{\"77\":1}}],[\"promise\",{\"1\":{\"77\":1}}],[\"promise\",{\"1\":{\"73\":2}}],[\"profile权限\",{\"1\":{\"77\":1}}],[\"profile\",{\"1\":{\"77\":2,\"137\":1,\"192\":1}}],[\"providemodule\",{\"1\":{\"73\":1}}],[\"prototype\",{\"1\":{\"68\":1}}],[\"progress\",{\"1\":{\"45\":3}}],[\"processors\",{\"1\":{\"41\":1}}],[\"pattern\",{\"1\":{\"169\":1}}],[\"path>\",{\"1\":{\"154\":2,\"209\":1}}],[\"pathstyle\",{\"1\":{\"141\":3}}],[\"pathstolink\",{\"1\":{\"137\":1}}],[\"paths\",{\"1\":{\"137\":1}}],[\"path\",{\"1\":{\"77\":2,\"124\":2,\"139\":1,\"209\":1}}],[\"page\",{\"1\":{\"162\":1}}],[\"page=\",{\"1\":{\"162\":1}}],[\"partials\",{\"1\":{\"162\":2}}],[\"party\",{\"0\":{\"36\":1}}],[\"parallelism\",{\"1\":{\"106\":1,\"124\":1}}],[\"param\",{\"1\":{\"77\":5}}],[\"package\",{\"1\":{\"75\":1,\"86\":1}}],[\"packages\",{\"1\":{\"2\":1,\"45\":1,\"50\":1,\"54\":1,\"70\":1,\"160\":1}}],[\"pas\",{\"1\":{\"222\":1}}],[\"pass\",{\"1\":{\"142\":1}}],[\"passwd\",{\"1\":{\"137\":2}}],[\"password3\",{\"1\":{\"163\":2}}],[\"password2\",{\"1\":{\"163\":2}}],[\"password1\",{\"1\":{\"163\":2}}],[\"password>\",{\"1\":{\"132\":1}}],[\"password\",{\"1\":{\"40\":2,\"98\":1,\"115\":2,\"116\":2,\"118\":2,\"124\":1,\"132\":1}}],[\"pasteshowhandler\",{\"1\":{\"77\":2}}],[\"pastecreatehandler\",{\"1\":{\"77\":2}}],[\"pasteid\",{\"1\":{\"77\":6}}],[\"paste\",{\"1\":{\"77\":15}}],[\"pastebinmodel\",{\"1\":{\"77\":4}}],[\"pastebin\",{\"1\":{\"75\":2,\"77\":3}}],[\"pascalabc\",{\"1\":{\"132\":1}}],[\"pascal\",{\"1\":{\"22\":1,\"132\":4,\"136\":1}}],[\"pm2\",{\"0\":{\"165\":1,\"167\":1},\"1\":{\"15\":1,\"16\":3,\"23\":1,\"25\":1,\"37\":1,\"95\":1,\"98\":1,\"109\":1,\"111\":3,\"124\":2,\"127\":1,\"136\":3,\"165\":1,\"166\":3,\"167\":13,\"168\":1}}],[\"else\",{\"1\":{\"200\":2}}],[\"elasticsearch\",{\"1\":{\"90\":3}}],[\"elastic\",{\"0\":{\"90\":1},\"1\":{\"85\":3,\"90\":1}}],[\"east\",{\"1\":{\"141\":1}}],[\"easy\",{\"1\":{\"92\":1}}],[\"echo\",{\"1\":{\"137\":1}}],[\"etc\",{\"1\":{\"112\":1,\"113\":1,\"137\":2}}],[\"etag\",{\"1\":{\"43\":3}}],[\"esnext\",{\"1\":{\"77\":1}}],[\"ensure\",{\"1\":{\"214\":1}}],[\"enable=memory\",{\"1\":{\"113\":2}}],[\"entry\",{\"1\":{\"75\":1}}],[\"env\",{\"1\":{\"48\":1,\"122\":1,\"136\":18}}],[\"endl\",{\"1\":{\"200\":1}}],[\"endpointforjudge\",{\"1\":{\"141\":3}}],[\"endpointforuser\",{\"1\":{\"141\":3}}],[\"endpoint\",{\"1\":{\"73\":6,\"90\":1,\"141\":3}}],[\"end\",{\"1\":{\"45\":2}}],[\"edit\",{\"1\":{\"46\":1,\"71\":1,\"189\":3,\"190\":2}}],[\"event\",{\"0\":{\"62\":1},\"1\":{\"30\":1}}],[\"e=e||window\",{\"1\":{\"30\":1}}],[\"exist\",{\"1\":{\"222\":1}}],[\"expected\",{\"1\":{\"200\":2}}],[\"export\",{\"1\":{\"68\":2,\"73\":1,\"77\":1,\"154\":1}}],[\"excel\",{\"1\":{\"163\":2}}],[\"example\",{\"1\":{\"124\":1,\"222\":1}}],[\"examples\",{\"1\":{\"2\":1,\"222\":1}}],[\"execute\",{\"1\":{\"132\":1}}],[\"exec\",{\"1\":{\"109\":1}}],[\"execve\",{\"0\":{\"32\":1}}],[\"extends\",{\"1\":{\"77\":2}}],[\"extra\",{\"1\":{\"19\":1,\"30\":1,\"199\":1,\"222\":5}}],[\"empty\",{\"0\":{\"15\":1}}],[\"email`\",{\"1\":{\"73\":1}}],[\"email\",{\"1\":{\"1\":1,\"73\":4,\"186\":1}}],[\"e\",{\"1\":{\"14\":1,\"30\":21,\"136\":1}}],[\"error\",{\"1\":{\"73\":4,\"124\":1}}],[\"err\",{\"0\":{\"11\":1}}],[\"注意空格缩进\",{\"1\":{\"219\":1}}],[\"注意新版的客观题\",{\"1\":{\"203\":1}}],[\"注意数字编号必须和\",{\"1\":{\"198\":1}}],[\"注意\",{\"1\":{\"135\":1}}],[\"注册账户后\",{\"1\":{\"185\":1}}],[\"注册一个账号\",{\"1\":{\"135\":1}}],[\"注册一个名为\",{\"1\":{\"77\":1}}],[\"注册\",{\"1\":{\"95\":1,\"154\":1}}],[\"注册即可\",{\"1\":{\"86\":1}}],[\"注册时启用\",{\"1\":{\"85\":1}}],[\"注册此模块\",{\"1\":{\"73\":1}}],[\"注册验证码等\",{\"1\":{\"65\":1}}],[\"注4\",{\"1\":{\"43\":1}}],[\"注3\",{\"1\":{\"43\":1}}],[\"注\",{\"1\":{\"41\":1,\"156\":1}}],[\"注2\",{\"1\":{\"1\":1,\"43\":1}}],[\"注1\",{\"1\":{\"1\":1,\"43\":1}}],[\"ulimit\",{\"1\":{\"111\":2}}],[\"uoj\",{\"1\":{\"81\":1,\"85\":1}}],[\"uri\",{\"1\":{\"73\":2}}],[\"url\",{\"1\":{\"73\":4,\"75\":1,\"77\":1,\"98\":1,\"135\":1,\"141\":1,\"162\":1,\"186\":2}}],[\"utils\",{\"1\":{\"45\":1}}],[\"utf8\",{\"1\":{\"92\":1}}],[\"utf\",{\"1\":{\"41\":1,\"163\":1}}],[\"ubuntu\",{\"1\":{\"41\":1,\"113\":1,\"134\":2}}],[\"unzip\",{\"1\":{\"136\":1,\"137\":1}}],[\"unified\",{\"1\":{\"113\":2}}],[\"universaloj\",{\"0\":{\"117\":1},\"1\":{\"80\":1,\"85\":1,\"117\":2}}],[\"unlimited\",{\"1\":{\"111\":2}}],[\"unamelower\",{\"1\":{\"57\":1}}],[\"uname\",{\"1\":{\"40\":1,\"57\":1,\"73\":1,\"98\":1}}],[\"undefinedmoe\",{\"1\":{\"1\":1}}],[\"undefined\",{\"1\":{\"1\":1,\"75\":2,\"163\":6}}],[\"us\",{\"1\":{\"141\":1}}],[\"usage\",{\"1\":{\"113\":2}}],[\"usr\",{\"1\":{\"110\":1,\"111\":1}}],[\"using\",{\"0\":{\"36\":1},\"1\":{\"113\":1,\"198\":1,\"199\":1,\"200\":2,\"201\":1}}],[\"used\",{\"1\":{\"41\":1}}],[\"use\",{\"1\":{\"33\":1,\"132\":1,\"222\":1}}],[\"user3\",{\"1\":{\"163\":2}}],[\"user2\",{\"1\":{\"163\":2}}],[\"user1\",{\"1\":{\"163\":2}}],[\"userid\",{\"1\":{\"77\":2}}],[\"userinfo\",{\"1\":{\"73\":7}}],[\"user`\",{\"1\":{\"73\":1}}],[\"userfacingerror\",{\"1\":{\"73\":2}}],[\"username\",{\"1\":{\"40\":1,\"115\":2,\"116\":2,\"118\":2}}],[\"user\",{\"0\":{\"57\":1},\"1\":{\"25\":3,\"33\":1,\"37\":1,\"43\":1,\"73\":3,\"77\":5,\"134\":1,\"135\":1,\"142\":1,\"148\":2,\"149\":2,\"150\":1,\"151\":2,\"152\":1,\"153\":1,\"154\":6,\"192\":1,\"199\":1,\"204\":1,\"214\":1,\"222\":1}}],[\"ups\",{\"1\":{\"134\":1}}],[\"upload\",{\"1\":{\"115\":1}}],[\"uploaddir\",{\"1\":{\"115\":2}}],[\"updateone\",{\"1\":{\"132\":1}}],[\"update\",{\"1\":{\"33\":1,\"113\":1}}],[\"upgrade\",{\"1\":{\"16\":1,\"88\":1,\"99\":1,\"168\":1}}],[\"u\",{\"1\":{\"30\":3}}],[\"u=i\",{\"1\":{\"30\":1}}],[\"uid>\",{\"1\":{\"33\":1}}],[\"uid\",{\"1\":{\"25\":1,\"26\":1,\"43\":3,\"55\":1,\"56\":1,\"148\":3,\"149\":1,\"151\":1,\"152\":1,\"154\":2}}],[\"uid=2\",{\"1\":{\"1\":1}}],[\"ui\",{\"1\":{\"2\":1,\"47\":1,\"49\":1,\"50\":2,\"51\":2,\"52\":1,\"85\":1,\"160\":1}}],[\"img\",{\"1\":{\"214\":1}}],[\"importer\",{\"0\":{\"91\":1},\"1\":{\"80\":1,\"85\":1,\"92\":1,\"211\":1}}],[\"import\",{\"1\":{\"68\":2,\"73\":1,\"77\":1,\"80\":1,\"85\":2,\"137\":1,\"154\":1,\"209\":1,\"212\":1}}],[\"icpc\",{\"1\":{\"172\":1}}],[\"icon\",{\"1\":{\"27\":1}}],[\"ico\",{\"1\":{\"27\":1}}],[\"ignorecollisions\",{\"1\":{\"137\":1}}],[\"io\",{\"1\":{\"109\":1,\"222\":1}}],[\"ioi\",{\"1\":{\"81\":3}}],[\"is\",{\"1\":{\"200\":2,\"214\":1}}],[\"isprivate\",{\"1\":{\"77\":6}}],[\"issues\",{\"1\":{\"0\":1}}],[\"i18n\",{\"1\":{\"73\":1}}],[\"ifs>>a>>b\",{\"1\":{\"201\":1}}],[\"ifs\",{\"1\":{\"201\":1}}],[\"ifstream\",{\"1\":{\"201\":1}}],[\"if\",{\"1\":{\"68\":1,\"73\":3,\"77\":2,\"200\":2,\"202\":2,\"222\":2}}],[\"ia\",{\"1\":{\"48\":1,\"122\":1,\"136\":16}}],[\"iptables\",{\"1\":{\"172\":1}}],[\"ip\",{\"0\":{\"37\":1},\"1\":{\"37\":1,\"139\":1,\"153\":3,\"154\":1,\"172\":1,\"173\":3}}],[\"id为子任务编号\",{\"1\":{\"202\":2}}],[\"id=$\",{\"1\":{\"73\":1}}],[\"id=a\",{\"1\":{\"30\":1}}],[\"ide\",{\"1\":{\"47\":1,\"76\":1,\"139\":1}}],[\"id\",{\"1\":{\"33\":1,\"41\":1,\"43\":8,\"44\":3,\"45\":5,\"56\":1,\"57\":1,\"68\":1,\"70\":1,\"73\":7,\"77\":14,\"85\":1,\"107\":1,\"132\":1,\"154\":6,\"166\":2,\"182\":1,\"186\":3,\"190\":6,\"202\":5,\"207\":1}}],[\"i=document\",{\"1\":{\"30\":1}}],[\"i=e\",{\"1\":{\"30\":1}}],[\"i+a\",{\"1\":{\"30\":1}}],[\"in$\",{\"1\":{\"222\":1}}],[\"in文件和test\",{\"1\":{\"204\":1}}],[\"in中\",{\"1\":{\"201\":1}}],[\"inf\",{\"1\":{\"200\":2}}],[\"info\",{\"1\":{\"41\":1,\"109\":1}}],[\"int\",{\"1\":{\"198\":3,\"199\":9,\"200\":14,\"201\":3}}],[\"interactor\",{\"1\":{\"200\":2,\"222\":2}}],[\"interactive\",{\"1\":{\"16\":1,\"88\":1,\"99\":1,\"168\":1,\"200\":1,\"222\":1}}],[\"interface\",{\"1\":{\"70\":1,\"73\":1,\"77\":3}}],[\"intel\",{\"1\":{\"41\":2,\"112\":1}}],[\"include\",{\"1\":{\"199\":1}}],[\"include\",{\"1\":{\"198\":1,\"199\":1,\"200\":4,\"201\":1}}],[\"inactive\",{\"1\":{\"124\":2}}],[\"inaccurate\",{\"1\":{\"113\":1}}],[\"inet\",{\"1\":{\"124\":1}}],[\"inodes\",{\"1\":{\"109\":1}}],[\"insertedid\",{\"1\":{\"77\":1}}],[\"insertone\",{\"1\":{\"77\":1}}],[\"instead\",{\"0\":{\"36\":1}}],[\"install\",{\"1\":{\"2\":1,\"23\":1,\"48\":1}}],[\"init\",{\"1\":{\"75\":4,\"76\":1,\"95\":1}}],[\"in\",{\"0\":{\"36\":1},\"1\":{\"43\":1,\"44\":3,\"45\":2,\"113\":2,\"198\":3,\"200\":2,\"201\":2,\"202\":26,\"204\":1,\"205\":3,\"214\":1,\"221\":5,\"222\":12}}],[\"index\",{\"1\":{\"30\":1,\"75\":2,\"77\":1}}],[\"innerheight||document\",{\"1\":{\"30\":1}}],[\"innerwidth||document\",{\"1\":{\"30\":1}}],[\"input2\",{\"1\":{\"222\":1}}],[\"input1\",{\"1\":{\"222\":1}}],[\"input\",{\"1\":{\"10\":1,\"43\":3,\"200\":5,\"202\":25,\"203\":1,\"204\":1,\"214\":1,\"218\":1,\"222\":9}}],[\"i\",{\"1\":{\"1\":1,\"30\":5,\"73\":2,\"167\":1}}],[\"联系我们\",{\"0\":{\"1\":1},\"1\":{\"133\":1}}],[\"在有\",{\"1\":{\"222\":1}}],[\"在默认配置下\",{\"1\":{\"222\":1}}],[\"在用户列表中仅会显示权限不为\",{\"1\":{\"194\":1}}],[\"在用户量较多的时候这会非常混乱难以管理\",{\"1\":{\"194\":1}}],[\"在所有域均生效\",{\"1\":{\"192\":1}}],[\"在页面右侧找到\",{\"1\":{\"189\":1}}],[\"在左侧选中用户\",{\"1\":{\"188\":1}}],[\"在该实例的所有域中均有效\",{\"1\":{\"185\":1}}],[\"在该目录下创建文件\",{\"1\":{\"98\":1}}],[\"在弹出的窗口中输入需要复制到的域的\",{\"1\":{\"182\":1}}],[\"在作业截止之后\",{\"1\":{\"180\":1}}],[\"在作业进入延期阶段后\",{\"1\":{\"180\":1}}],[\"在作业持续时间内\",{\"1\":{\"180\":1}}],[\"在作业开始之前\",{\"1\":{\"180\":1}}],[\"在比赛截止之后\",{\"1\":{\"178\":1}}],[\"在题目的\",{\"1\":{\"197\":1}}],[\"在题目获得大量递交之后\",{\"1\":{\"177\":1}}],[\"在题库右侧\",{\"1\":{\"92\":1}}],[\"在地址列表的用户均会自动登录上指定的对应账户\",{\"1\":{\"173\":1}}],[\"在赛场旁摆放一台电脑\",{\"1\":{\"173\":1}}],[\"在内网部署评测设施的用户\",{\"1\":{\"171\":1}}],[\"在交互式界面中选择想要更新的组件\",{\"1\":{\"168\":1}}],[\"在部分环境\",{\"1\":{\"167\":1}}],[\"在部署\",{\"1\":{\"98\":1}}],[\"在添加\",{\"1\":{\"167\":1}}],[\"在第二行的\",{\"1\":{\"162\":1}}],[\"在绝大部分情况下均不需要\",{\"1\":{\"156\":1}}],[\"在使用\",{\"1\":{\"147\":1}}],[\"在大部分情况下即可大幅度改善访问质量\",{\"1\":{\"146\":1}}],[\"在控制面板中将\",{\"1\":{\"145\":1}}],[\"在控制面板上出现内容为\",{\"1\":{\"113\":1}}],[\"在您访问的\",{\"1\":{\"162\":1}}],[\"在您的服务器带宽较小的情况下\",{\"1\":{\"144\":1}}],[\"在您部署\",{\"1\":{\"3\":1}}],[\"在线编辑题目配置\",{\"1\":{\"222\":1}}],[\"在线\",{\"1\":{\"139\":1}}],[\"在下方列出你所需要的包\",{\"1\":{\"137\":1}}],[\"在新版即在允许提交的语言中选中所有\",{\"1\":{\"132\":1}}],[\"在新版本\",{\"1\":{\"92\":1}}],[\"在脚本管理中找到重建题目索引\",{\"1\":{\"128\":1}}],[\"在注册过程中没有看见传统验证码属正常现象\",{\"1\":{\"119\":1}}],[\"在迁移完成后请不要卸载该插件\",{\"1\":{\"118\":1}}],[\"在迁移数据之前\",{\"1\":{\"115\":1,\"118\":1}}],[\"在其中\",{\"1\":{\"113\":1}}],[\"在很多时候系统默认为程序提供的栈空间并不能满足我们的需求\",{\"1\":{\"111\":1}}],[\"在服务器上运行下面的代码找到\",{\"1\":{\"109\":1}}],[\"在安装\",{\"1\":{\"97\":1}}],[\"在安装插件后需要将mmdb拷贝至插件同一目录下方可启用\",{\"1\":{\"93\":1}}],[\"在配置评测机之前\",{\"1\":{\"95\":1}}],[\"在打开的窗口中\",{\"1\":{\"92\":1}}],[\"在html表单提交的多选框中\",{\"1\":{\"77\":1}}],[\"在表单提交时的\",{\"1\":{\"77\":1}}],[\"在路由中定义所有的函数应均为异步函数\",{\"1\":{\"77\":1}}],[\"在本机安装\",{\"1\":{\"76\":1}}],[\"在本机环境编写插件\",{\"0\":{\"76\":1}}],[\"在阅读本节之前\",{\"1\":{\"67\":1,\"73\":1}}],[\"在系统内置了三个角色\",{\"1\":{\"194\":1}}],[\"在系统中的所有用户\",{\"1\":{\"57\":1}}],[\"在系统设置内正确填写\",{\"1\":{\"90\":1}}],[\"在系统设置中\",{\"1\":{\"110\":1}}],[\"在系统设置中找到\",{\"1\":{\"30\":1}}],[\"在系统设置中修改\",{\"1\":{\"29\":1}}],[\"在系统设置\",{\"1\":{\"19\":1}}],[\"在反复修改时可节省编译时间\",{\"1\":{\"51\":1}}],[\"在开发之前\",{\"1\":{\"47\":1}}],[\"在连接建立后\",{\"1\":{\"42\":1}}],[\"在了解了上面的情况以后\",{\"1\":{\"10\":1}}],[\"在提问前请先阅读\",{\"1\":{\"3\":1}}],[\"在\",{\"1\":{\"0\":1,\"70\":1,\"73\":1,\"101\":1,\"105\":1,\"106\":1,\"107\":1,\"124\":1,\"132\":2,\"161\":1,\"162\":1,\"173\":2,\"186\":1}}],[\"提问\",{\"1\":{\"133\":1}}],[\"提问的智慧\",{\"1\":{\"1\":1,\"3\":1}}],[\"提高测评精度\",{\"0\":{\"112\":1}}],[\"提交语言限制\",{\"1\":{\"222\":1}}],[\"提交答案题\",{\"1\":{\"80\":1}}],[\"提交记录\",{\"1\":{\"70\":1}}],[\"提示文字\",{\"1\":{\"197\":1}}],[\"提示\",{\"1\":{\"77\":1,\"139\":1,\"142\":1,\"222\":1}}],[\"提供好题目和各个子任务的输入\",{\"1\":{\"202\":1}}],[\"提供的\",{\"1\":{\"142\":1}}],[\"提供的源替代官方源\",{\"1\":{\"48\":1}}],[\"提供\",{\"1\":{\"77\":2}}],[\"提供多个用户名\",{\"1\":{\"73\":1}}],[\"提供数据库服务\",{\"1\":{\"48\":1}}],[\"提供了一个小工具\",{\"1\":{\"210\":1}}],[\"提供了一些配置样例\",{\"1\":{\"139\":1}}],[\"提供了\",{\"1\":{\"77\":1}}],[\"提供了此方法\",{\"1\":{\"77\":1}}],[\"提供了ui框架\",{\"1\":{\"4\":1}}],[\"提供了代码托管与自动构建\",{\"1\":{\"4\":1}}],[\"提供评测沙箱实现\",{\"1\":{\"4\":1}}],[\"提供收费的功能定制服务\",{\"1\":{\"0\":1}}],[\"提出\",{\"1\":{\"0\":1}}],[\"欢迎社区参与多国化翻译工作\",{\"1\":{\"161\":1}}],[\"欢迎向此列表\",{\"1\":{\"142\":1}}],[\"欢迎进行捐助\",{\"1\":{\"0\":1}}],[\"欢迎\",{\"1\":{\"0\":1}}],[\"仓库\",{\"1\":{\"0\":1}}],[\"轻量\",{\"1\":{\"0\":1}}]],\"serializationVersion\":2}}")).map(([e,t])=>[e,zt(t,{fields:["h","t","c"],storeFields:["h","t","c"]})]));self.onmessage=({data:{type:e="all",query:t,locale:s,options:n}})=>{e==="suggest"?self.postMessage(st(t,v[s],n)):e==="search"?self.postMessage(et(t,v[s],n)):self.postMessage({suggestions:st(t,v[s],n),results:et(t,v[s],n)})};
+//# sourceMappingURL=index.js.map
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 00000000..d5ee314c
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1,3 @@
+
+
+https://hydro.js.org/ 2024-04-12T12:11:12.000Z daily https://hydro.js.org/FAQ/ 2024-07-24T09:09:52.000Z daily https://hydro.js.org/api/ 2023-11-22T01:11:53.000Z daily https://hydro.js.org/api/judge.html 2023-11-23T03:00:48.000Z daily https://hydro.js.org/dev/PERM_PRIV.html 2024-01-05T09:19:22.000Z daily https://hydro.js.org/dev/ 2024-07-23T09:45:08.000Z daily https://hydro.js.org/dev/db-layout.html 2024-02-29T15:46:47.000Z daily https://hydro.js.org/dev/frontend-modify.html 2021-08-13T04:13:21.000Z daily https://hydro.js.org/dev/hook.html 2024-04-03T09:19:20.000Z daily https://hydro.js.org/dev/naming.html 2024-02-29T15:39:38.000Z daily https://hydro.js.org/dev/third-party-auth.html 2023-12-26T15:12:47.000Z daily https://hydro.js.org/dev/typescript.html 2024-03-02T07:55:17.000Z daily https://hydro.js.org/docs/ 2024-04-12T12:11:12.000Z daily https://hydro.js.org/plugins/ 2024-04-22T01:02:47.000Z daily https://hydro.js.org/plugins/elastic.html 2024-04-22T01:06:00.000Z daily https://hydro.js.org/plugins/fps-importer.html 2024-04-22T01:07:54.000Z daily https://hydro.js.org/plugins/geoip.html 2023-02-25T05:29:05.000Z daily https://hydro.js.org/plugins/hydrojudge.html 2024-04-12T12:11:12.000Z daily https://hydro.js.org/plugins/migrate.html 2023-05-12T03:18:30.000Z daily https://hydro.js.org/plugins/recaptcha.html 2021-04-20T05:10:12.000Z daily https://hydro.js.org/plugins/sonic.html 2023-02-25T05:29:05.000Z daily https://hydro.js.org/plugins/vjudge.html 2024-04-22T01:00:23.000Z daily https://hydro.js.org/docs/install/ 2024-01-18T07:19:14.000Z daily https://hydro.js.org/docs/install/compiler.html 2023-02-26T07:44:01.000Z daily https://hydro.js.org/docs/install/proxy.html 2023-08-23T08:55:42.000Z daily https://hydro.js.org/docs/install/s3.html 2024-06-29T13:57:26.000Z daily https://hydro.js.org/docs/install/smtp.html 2024-07-18T07:40:07.000Z daily https://hydro.js.org/docs/system/FAQ.html 2022-03-14T10:46:41.000Z daily https://hydro.js.org/docs/system/cdn.html 2023-05-17T15:15:27.000Z daily https://hydro.js.org/docs/system/cli.html 2023-05-12T03:18:30.000Z daily https://hydro.js.org/docs/system/database.html 2024-04-03T09:17:20.000Z daily https://hydro.js.org/docs/system/frontend-modify.html 2022-02-25T15:35:42.000Z daily https://hydro.js.org/docs/system/import-user.html 2022-12-29T09:30:13.000Z daily https://hydro.js.org/docs/system/maintain.html 2023-08-24T08:31:37.000Z daily https://hydro.js.org/docs/system/onsite-contest.html 2024-07-13T14:37:53.000Z daily https://hydro.js.org/docs/user/ 2021-05-08T17:02:49.000Z daily https://hydro.js.org/docs/user/copy-problem.html 2022-02-25T15:35:42.000Z daily https://hydro.js.org/docs/user/domain.html 2023-03-20T01:53:27.000Z daily https://hydro.js.org/docs/user/permission.html 2024-06-19T11:24:39.000Z daily https://hydro.js.org/docs/user/problem-create.html 2024-04-03T09:19:20.000Z daily https://hydro.js.org/docs/user/problem-format.html 2023-05-19T14:49:26.000Z daily https://hydro.js.org/docs/user/problem.html 2024-06-29T14:11:03.000Z daily https://hydro.js.org/docs/user/testdata.html 2023-05-12T03:18:30.000Z daily
\ No newline at end of file
diff --git a/sitemap.xsl b/sitemap.xsl
new file mode 100644
index 00000000..8ad0f233
--- /dev/null
+++ b/sitemap.xsl
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+ XML Sitemap
+
+
+
+
+ XML Sitemap
+
+
+ URLs list
+
+
+
+
+
+ Priority
+ Change Frequency
+ Last Updated Time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.5
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/twoslash.css b/twoslash.css
new file mode 100644
index 00000000..5e64a0eb
--- /dev/null
+++ b/twoslash.css
@@ -0,0 +1,336 @@
+pre {
+ position: relative;
+}
+
+pre.shiki {
+ overflow-x: auto;
+}
+
+pre.shiki:hover .dim {
+ opacity: 1;
+}
+
+pre.shiki div.dim {
+ opacity: 0.5;
+}
+
+pre.shiki div.dim,
+pre.shiki div.highlight {
+ margin: 0;
+ padding: 0;
+}
+
+pre.shiki div.highlight {
+ opacity: 1;
+ background-color: #f1f8ff;
+}
+
+pre.shiki div.line {
+ min-height: 1rem;
+}
+
+/** Don't show the language identifiers */
+pre.shiki .language-id {
+ display: none;
+}
+
+/* Visually differentiates twoslash code samples */
+pre.twoslash {
+ border-color: #719af4;
+}
+
+/** When you mouse over the pre, show the underlines */
+pre.twoslash:hover data-lsp {
+ border-color: #747474;
+}
+
+/** The tooltip-like which provides the LSP response */
+pre.twoslash data-lsp::before {
+ content: attr(lsp);
+ position: absolute;
+ pointer-events: none;
+ transform: translate(0, 1rem);
+
+ opacity: 0;
+
+ background-color: #3f3f3f;
+ color: #fff;
+ max-width: 500px;
+ text-align: left;
+ padding: 5px 8px;
+ border-radius: 2px;
+ font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New,
+ monospace;
+ font-size: 14px;
+ white-space: normal;
+ z-index: 999;
+
+ transition: opacity 0.1s ease;
+}
+
+pre.twoslash data-lsp:hover::before {
+ opacity: 90%;
+}
+
+/* Respect no animations */
+@media (prefers-reduced-motion: reduce) {
+ pre.twoslash data-lsp::before {
+ transition: none;
+ }
+}
+
+pre .code-title {
+ display: none;
+}
+
+/* The try button */
+pre .code-container > a {
+ position: absolute;
+ right: 8px;
+ bottom: 8px;
+ border-radius: 4px;
+ border: 1px solid #719af4;
+ padding: 0 8px;
+ color: #719af4;
+ text-decoration: none;
+ opacity: 0;
+ transition: opacity var(--t-color);
+}
+
+/* Respect no animations */
+@media (prefers-reduced-motion: reduce) {
+ pre .code-container > a {
+ transition: none;
+ }
+}
+
+pre .code-container > a:hover {
+ color: white;
+ background-color: #719af4;
+}
+
+pre .code-container:hover a {
+ opacity: 1;
+}
+
+pre code {
+ font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New,
+ monospace;
+ white-space: pre;
+ -webkit-overflow-scrolling: touch;
+}
+
+pre code a {
+ text-decoration: none;
+}
+
+pre data-err {
+ /* Extracted from VS Code */
+ background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")
+ repeat-x bottom left;
+ padding-bottom: 3px;
+}
+
+pre .query {
+ margin-bottom: 10px;
+ color: #137998;
+ display: inline-block;
+}
+
+/* In order to have the 'popped out' style design and to not break the layout
+ /* we need to place a fake and un-selectable copy of the error which _isn't_ broken out
+ /* behind the actual error message.
+ /* This sections keeps both of those two in in sync */
+
+pre .error,
+pre .error-behind {
+ margin-left: -14px;
+ margin-top: 8px;
+ margin-bottom: 4px;
+ padding: 6px;
+ padding-left: 14px;
+ width: calc(100% - 20px);
+ white-space: pre-wrap;
+ display: block;
+}
+
+pre .error {
+ position: absolute;
+ background-color: #fee;
+ border-left: 2px solid #bf1818;
+ /* Give the space to the error code */
+ display: flex;
+ align-items: center;
+ color: black;
+}
+
+pre .error .code {
+ display: none;
+}
+
+pre .error-behind {
+ user-select: none;
+ visibility: transparent;
+ color: #fee;
+}
+
+/* Queries */
+pre .arrow {
+ /* Transparent background */
+ background-color: #eee;
+ position: relative;
+ top: -7px;
+ margin-left: 0.1rem;
+ /* Edges */
+ border-left: 1px solid #eee;
+ border-top: 1px solid #eee;
+ transform: translateY(25%) rotate(45deg);
+ /* Size */
+ height: 8px;
+ width: 8px;
+}
+
+pre .popover {
+ margin-bottom: 10px;
+ background-color: #eee;
+ display: inline-block;
+ padding: 0 0.5rem 0.3rem;
+ margin-top: 10px;
+ border-radius: 3px;
+}
+
+/* Completion */
+pre .inline-completions ul.dropdown {
+ display: inline-block;
+ position: absolute;
+ width: 240px;
+ background-color: gainsboro;
+ color: grey;
+ padding-top: 4px;
+ font-family: var(--code-font);
+ font-size: 0.8rem;
+ margin: 0;
+ padding: 0;
+ border-left: 4px solid #4b9edd;
+}
+
+pre .inline-completions ul.dropdown::before {
+ background-color: #4b9edd;
+ width: 2px;
+ position: absolute;
+ top: -1.2rem;
+ left: -3px;
+ content: " ";
+}
+
+pre .inline-completions ul.dropdown li {
+ overflow-x: hidden;
+ padding-left: 4px;
+ margin-bottom: 4px;
+}
+
+pre .inline-completions ul.dropdown li.deprecated {
+ text-decoration: line-through;
+}
+
+pre .inline-completions ul.dropdown li span.result-found {
+ color: #4b9edd;
+}
+
+pre .inline-completions ul.dropdown li span.result {
+ width: 500px;
+ color: black;
+ display: inline-block;
+}
+
+.dark-theme .markdown pre {
+ background-color: #d8d8d8;
+ border-color: #ddd;
+ filter: invert(98%) hue-rotate(180deg);
+}
+
+data-lsp {
+ /* Ensures there's no 1px jump when the hover happens */
+ border-bottom: 1px dotted transparent;
+ /* Fades in unobtrusively */
+ transition: border-color var(--t-color);
+}
+
+/* Respect no animations */
+@media (prefers-reduced-motion: reduce) {
+ data-lsp {
+ transition: none;
+ }
+}
+
+/** Annotations support, providing a tool for meta commentary */
+.tag-container {
+ position: relative;
+}
+
+.tag-container .twoslash-annotation {
+ position: absolute;
+ font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New,
+ monospace;
+ right: -10px;
+ /** Default annotation text to 200px */
+ width: 500px;
+ color: #187abf;
+ background-color: #fcf3d9 bb;
+}
+
+.tag-container .twoslash-annotation p {
+ text-align: left;
+ font-size: 0.8rem;
+ line-height: 0.9rem;
+}
+
+.tag-container .twoslash-annotation svg {
+ float: left;
+ margin-left: -44px;
+}
+
+.tag-container .twoslash-annotation.left {
+ right: auto;
+ left: -200px;
+}
+
+.tag-container .twoslash-annotation.left svg {
+ float: right;
+ margin-right: -5px;
+}
+
+/** Support for showing console log/warn/errors inline */
+pre .logger {
+ display: flex;
+ align-items: center;
+ color: black;
+ padding: 6px;
+ padding-left: 8px;
+ width: calc(100% - 19px);
+ white-space: pre-wrap;
+}
+
+pre .logger svg {
+ margin-right: 9px;
+}
+
+pre .logger.error-log {
+ background-color: #fee;
+ border-left: 2px solid #bf1818;
+}
+
+pre .logger.warn-log {
+ background-color: #ffe;
+ border-left: 2px solid #eae662;
+}
+
+pre .logger.log-log {
+ background-color: #e9e9e9;
+ border-left: 2px solid #ababab;
+}
+
+pre .logger.log-log svg {
+ margin-left: 6px;
+ margin-right: 9px;
+}
\ No newline at end of file