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..fcba2aaa --- /dev/null +++ b/404.html @@ -0,0 +1,2556 @@ + + + + + + + + + + + + + + + + + + + + + + + + SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + +
+ +

404 - Not found

+ +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..e746452e --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.spojapanguild.net \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000..1cf13b9f Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.b547eccd.min.js b/assets/javascripts/bundle.b547eccd.min.js new file mode 100644 index 00000000..29543694 --- /dev/null +++ b/assets/javascripts/bundle.b547eccd.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var Yi=Object.create;var _r=Object.defineProperty;var Bi=Object.getOwnPropertyDescriptor;var Gi=Object.getOwnPropertyNames,Bt=Object.getOwnPropertySymbols,Ji=Object.getPrototypeOf,Ar=Object.prototype.hasOwnProperty,uo=Object.prototype.propertyIsEnumerable;var fo=(e,t,r)=>t in e?_r(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,k=(e,t)=>{for(var r in t||(t={}))Ar.call(t,r)&&fo(e,r,t[r]);if(Bt)for(var r of Bt(t))uo.call(t,r)&&fo(e,r,t[r]);return e};var ho=(e,t)=>{var r={};for(var o in e)Ar.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Bt)for(var o of Bt(e))t.indexOf(o)<0&&uo.call(e,o)&&(r[o]=e[o]);return r};var Cr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Xi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Gi(t))!Ar.call(e,n)&&n!==r&&_r(e,n,{get:()=>t[n],enumerable:!(o=Bi(t,n))||o.enumerable});return e};var Gt=(e,t,r)=>(r=e!=null?Yi(Ji(e)):{},Xi(t||!e||!e.__esModule?_r(r,"default",{value:e,enumerable:!0}):r,e));var bo=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var go=Cr((Hr,vo)=>{(function(e,t){typeof Hr=="object"&&typeof vo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Hr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function c(H){var mt=H.type,Fe=H.tagName;return!!(Fe==="INPUT"&&s[mt]&&!H.readOnly||Fe==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function p(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(H){o=!1}function d(H){a(H.target)&&(o||c(H.target))&&p(H.target)}function g(H){a(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function M(H){document.visibilityState==="hidden"&&(n&&(o=!0),ee())}function ee(){document.addEventListener("mousemove",Z),document.addEventListener("mousedown",Z),document.addEventListener("mouseup",Z),document.addEventListener("pointermove",Z),document.addEventListener("pointerdown",Z),document.addEventListener("pointerup",Z),document.addEventListener("touchmove",Z),document.addEventListener("touchstart",Z),document.addEventListener("touchend",Z)}function ne(){document.removeEventListener("mousemove",Z),document.removeEventListener("mousedown",Z),document.removeEventListener("mouseup",Z),document.removeEventListener("pointermove",Z),document.removeEventListener("pointerdown",Z),document.removeEventListener("pointerup",Z),document.removeEventListener("touchmove",Z),document.removeEventListener("touchstart",Z),document.removeEventListener("touchend",Z)}function Z(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ne())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",M,!0),ee(),r.addEventListener("focus",d,!0),r.addEventListener("blur",g,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var io=Cr((Vt,no)=>{(function(t,r){typeof Vt=="object"&&typeof no=="object"?no.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Vt=="object"?Vt.ClipboardJS=r():t.ClipboardJS=r()})(Vt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Qi}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(z){try{return document.execCommand(z)}catch(A){return!1}}var d=function(A){var L=f()(A);return u("cut"),L},g=d;function M(z){var A=document.documentElement.getAttribute("dir")==="rtl",L=document.createElement("textarea");L.style.fontSize="12pt",L.style.border="0",L.style.padding="0",L.style.margin="0",L.style.position="absolute",L.style[A?"right":"left"]="-9999px";var D=window.pageYOffset||document.documentElement.scrollTop;return L.style.top="".concat(D,"px"),L.setAttribute("readonly",""),L.value=z,L}var ee=function(A,L){var D=M(A);L.container.appendChild(D);var N=f()(D);return u("copy"),D.remove(),N},ne=function(A){var L=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},D="";return typeof A=="string"?D=ee(A,L):A instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(A==null?void 0:A.type)?D=ee(A.value,L):(D=f()(A),u("copy")),D},Z=ne;function H(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(L){return typeof L}:H=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},H(z)}var mt=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},L=A.action,D=L===void 0?"copy":L,N=A.container,G=A.target,We=A.text;if(D!=="copy"&&D!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(G!==void 0)if(G&&H(G)==="object"&&G.nodeType===1){if(D==="copy"&&G.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(D==="cut"&&(G.hasAttribute("readonly")||G.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(We)return Z(We,{container:N});if(G)return D==="cut"?g(G):Z(G,{container:N})},Fe=mt;function P(z){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?P=function(L){return typeof L}:P=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},P(z)}function se(z,A){if(!(z instanceof A))throw new TypeError("Cannot call a class as a function")}function ce(z,A){for(var L=0;L0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof N.action=="function"?N.action:this.defaultAction,this.target=typeof N.target=="function"?N.target:this.defaultTarget,this.text=typeof N.text=="function"?N.text:this.defaultText,this.container=P(N.container)==="object"?N.container:document.body}},{key:"listenClick",value:function(N){var G=this;this.listener=p()(N,"click",function(We){return G.onClick(We)})}},{key:"onClick",value:function(N){var G=N.delegateTarget||N.currentTarget,We=this.action(G)||"copy",Yt=Fe({action:We,container:this.container,target:this.target(G),text:this.text(G)});this.emit(Yt?"success":"error",{action:We,text:Yt,trigger:G,clearSelection:function(){G&&G.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(N){return Lr("action",N)}},{key:"defaultTarget",value:function(N){var G=Lr("target",N);if(G)return document.querySelector(G)}},{key:"defaultText",value:function(N){return Lr("text",N)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(N){var G=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return Z(N,G)}},{key:"cut",value:function(N){return g(N)}},{key:"isSupported",value:function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],G=typeof N=="string"?[N]:N,We=!!document.queryCommandSupported;return G.forEach(function(Yt){We=We&&!!document.queryCommandSupported(Yt)}),We}}]),L}(a()),Qi=Ki},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,d,g){var M=p.apply(this,arguments);return l.addEventListener(u,M,g),{destroy:function(){l.removeEventListener(u,M,g)}}}function c(l,f,u,d,g){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(M){return a(M,f,u,d,g)}))}function p(l,f,u,d){return function(g){g.delegateTarget=s(g.target,f),g.delegateTarget&&d.call(l,g)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,d,g){if(!u&&!d&&!g)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(g))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,g);if(s.nodeList(u))return l(u,d,g);if(s.string(u))return f(u,d,g);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,g){return u.addEventListener(d,g),{destroy:function(){u.removeEventListener(d,g)}}}function l(u,d,g){return Array.prototype.forEach.call(u,function(M){M.addEventListener(d,g)}),{destroy:function(){Array.prototype.forEach.call(u,function(M){M.removeEventListener(d,g)})}}}function f(u,d,g){return a(document.body,u,d,g)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";var ls=/["'&<>]/;ui.exports=ms;function ms(e){var t=""+e,r=ls.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function q(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function Y(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,d)})})}function a(u,d){try{c(o[u](d))}catch(g){f(i[0][3],g)}}function c(u){u.value instanceof ft?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,d){u(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function Eo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Se=="function"?Se(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function I(e){return typeof e=="function"}function gt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Xt=gt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Je(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var ze=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Se(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(M){t={error:M}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(I(l))try{l()}catch(M){i=M instanceof Xt?M.errors:[M]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=Se(f),d=u.next();!d.done;d=u.next()){var g=d.value;try{wo(g)}catch(M){i=i!=null?i:[],M instanceof Xt?i=Y(Y([],q(i)),q(M.errors)):i.push(M)}}}catch(M){o={error:M}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Xt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)wo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Je(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Je(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var kr=ze.EMPTY;function Zt(e){return e instanceof ze||e&&"closed"in e&&I(e.remove)&&I(e.add)&&I(e.unsubscribe)}function wo(e){I(e)?e():e.unsubscribe()}var Ue={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var xt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?kr:(this.currentObservers=null,a.push(r),new ze(function(){o.currentObservers=null,Je(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new Co(r,o)},t}(j);var Co=function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:kr},t}(w);var jr=function(e){ie(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(w);var Pt={now:function(){return(Pt.delegate||Date).now()},delegate:void 0};var It=function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Pt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(Tt);var ko=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(St);var Dr=new ko($o);var Ro=function(e){ie(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=wt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(wt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(Tt);var Po=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(St);var ge=new Po(Ro);var x=new j(function(e){return e.complete()});function rr(e){return e&&I(e.schedule)}function Nr(e){return e[e.length-1]}function st(e){return I(Nr(e))?e.pop():void 0}function Ie(e){return rr(Nr(e))?e.pop():void 0}function or(e,t){return typeof Nr(e)=="number"?e.pop():t}var Ot=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function nr(e){return I(e==null?void 0:e.then)}function ir(e){return I(e[Et])}function ar(e){return Symbol.asyncIterator&&I(e==null?void 0:e[Symbol.asyncIterator])}function sr(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function sa(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var cr=sa();function pr(e){return I(e==null?void 0:e[cr])}function lr(e){return yo(this,arguments,function(){var r,o,n,i;return Jt(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ft(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ft(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ft(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function mr(e){return I(e==null?void 0:e.getReader)}function W(e){if(e instanceof j)return e;if(e!=null){if(ir(e))return ca(e);if(Ot(e))return pa(e);if(nr(e))return la(e);if(ar(e))return Io(e);if(pr(e))return ma(e);if(mr(e))return fa(e)}throw sr(e)}function ca(e){return new j(function(t){var r=e[Et]();if(I(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function pa(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?v(function(n,i){return e(n,i,o)}):be,ye(1),r?tt(t):Zo(function(){return new ur}))}}function Yr(e){return e<=0?function(){return x}:y(function(t,r){var o=[];t.subscribe(E(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new w}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,g=!1,M=!1,ee=function(){f==null||f.unsubscribe(),f=void 0},ne=function(){ee(),l=u=void 0,g=M=!1},Z=function(){var H=l;ne(),H==null||H.unsubscribe()};return y(function(H,mt){d++,!M&&!g&&ee();var Fe=u=u!=null?u:r();mt.add(function(){d--,d===0&&!M&&!g&&(f=Br(Z,c))}),Fe.subscribe(mt),!l&&d>0&&(l=new dt({next:function(P){return Fe.next(P)},error:function(P){M=!0,ee(),f=Br(ne,n,P),Fe.error(P)},complete:function(){g=!0,ee(),f=Br(ne,s),Fe.complete()}}),W(H).subscribe(l))})(p)}}function Br(e,t){for(var r=[],o=2;oe.next(document)),e}function C(e,t=document){return Array.from(t.querySelectorAll(e))}function F(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ve(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var Ca=O(h(document.body,"focusin"),h(document.body,"focusout")).pipe(_e(1),K(void 0),m(()=>Ve()||document.body),X(1));function Ke(e){return Ca.pipe(m(t=>e.contains(t)),Q())}function ot(e,t){return $(()=>O(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?jt(r=>He(+!r*t)):be,K(e.matches(":hover"))))}function Qe(e){return{x:e.offsetLeft,y:e.offsetTop}}function nn(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function an(e){return O(h(window,"load"),h(window,"resize")).pipe($e(0,ge),m(()=>Qe(e)),K(Qe(e)))}function br(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ye(e){return O(h(e,"scroll"),h(window,"resize")).pipe($e(0,ge),m(()=>br(e)),K(br(e)))}function sn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)sn(e,r)}function S(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)sn(o,n);return o}function vr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function _t(e){let t=S("script",{src:e});return $(()=>(document.head.appendChild(t),O(h(t,"load"),h(t,"error").pipe(b(()=>Vr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),ye(1))))}var cn=new w,Ha=$(()=>typeof ResizeObserver=="undefined"?_t("https://unpkg.com/resize-observer-polyfill"):R(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>cn.next(t)))),b(e=>O(Ze,R(e)).pipe(_(()=>e.disconnect()))),X(1));function ue(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ae(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return Ha.pipe(T(r=>r.observe(t)),b(r=>cn.pipe(v(o=>o.target===t),_(()=>r.unobserve(t)))),m(()=>ue(e)),K(ue(e)))}function At(e){return{width:e.scrollWidth,height:e.scrollHeight}}function gr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function pn(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.body),t}var ln=new w,$a=$(()=>R(new IntersectionObserver(e=>{for(let t of e)ln.next(t)},{threshold:0}))).pipe(b(e=>O(Ze,R(e)).pipe(_(()=>e.disconnect()))),X(1));function Ct(e){return $a.pipe(T(t=>t.observe(e)),b(t=>ln.pipe(v(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function mn(e,t=16){return Ye(e).pipe(m(({y:r})=>{let o=ue(e),n=At(e);return r>=n.height-o.height-t}),Q())}var xr={drawer:F("[data-md-toggle=drawer]"),search:F("[data-md-toggle=search]")};function fn(e){return xr[e].checked}function nt(e,t){xr[e].checked!==t&&xr[e].click()}function Be(e){let t=xr[e];return h(t,"change").pipe(m(()=>t.checked),K(t.checked))}function ka(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ra(){return O(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(K(!1))}function un(){let e=h(window,"keydown").pipe(v(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:fn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),v(({mode:t,type:r})=>{if(t==="global"){let o=Ve();if(typeof o!="undefined")return!ka(o,r)}return!0}),le());return Ra().pipe(b(t=>t?x:e))}function Ee(){return new URL(location.href)}function it(e,t=!1){if(B("navigation.instant")&&!t){let r=S("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function dn(){return new w}function hn(){return location.hash.slice(1)}function bn(e){let t=S("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Zr(e){return O(h(window,"hashchange"),e).pipe(m(hn),K(hn()),v(t=>t.length>0),X(1))}function vn(e){return Zr(e).pipe(m(t=>fe(`[id="${t}"]`)),v(t=>typeof t!="undefined"))}function Ut(e){let t=matchMedia(e);return dr(r=>t.addListener(()=>r(t.matches))).pipe(K(t.matches))}function gn(){let e=matchMedia("print");return O(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(K(e.matches))}function eo(e,t){return e.pipe(b(r=>r?t():x))}function to(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ge(e,t){return to(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),X(1))}function yr(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),X(1))}function xn(e,t){let r=new DOMParser;return to(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),X(1))}function yn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function En(){return O(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(yn),K(yn()))}function wn(){return{width:innerWidth,height:innerHeight}}function Tn(){return h(window,"resize",{passive:!0}).pipe(m(wn),K(wn()))}function Sn(){return V([En(),Tn()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function Er(e,{viewport$:t,header$:r}){let o=t.pipe(re("size")),n=V([o,r]).pipe(m(()=>Qe(e)));return V([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function Pa(e){return h(e,"message",t=>t.data)}function Ia(e){let t=new w;return t.subscribe(r=>e.postMessage(r)),t}function On(e,t=new Worker(e)){let r=Pa(t),o=Ia(t),n=new w;n.subscribe(o);let i=o.pipe(te(),ae(!0));return n.pipe(te(),Ne(r.pipe(U(i))),le())}var Fa=F("#__config"),Ht=JSON.parse(Fa.textContent);Ht.base=`${new URL(Ht.base,Ee())}`;function we(){return Ht}function B(e){return Ht.features.includes(e)}function Me(e,t){return typeof t!="undefined"?Ht.translations[e].replace("#",t.toString()):Ht.translations[e]}function Ce(e,t=document){return F(`[data-md-component=${e}]`,t)}function me(e,t=document){return C(`[data-md-component=${e}]`,t)}function ja(e){let t=F(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>F(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function Mn(e){if(!B("announce.dismiss")||!e.childElementCount)return x;if(!e.hidden){let t=F(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return $(()=>{let t=new w;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),ja(e).pipe(T(r=>t.next(r)),_(()=>t.complete()),m(r=>k({ref:e},r)))})}function Wa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function Ln(e,t){let r=new w;return r.subscribe(({hidden:o})=>{e.hidden=o}),Wa(e,t).pipe(T(o=>r.next(o)),_(()=>r.complete()),m(o=>k({ref:e},o)))}function Dt(e,t){return t==="inline"?S("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},S("div",{class:"md-tooltip__inner md-typeset"})):S("div",{class:"md-tooltip",id:e,role:"tooltip"},S("div",{class:"md-tooltip__inner md-typeset"}))}function wr(...e){return S("div",{class:"md-tooltip2",role:"dialog"},S("div",{class:"md-tooltip2__inner md-typeset"},e))}function _n(...e){return S("div",{class:"md-tooltip2",role:"tooltip"},S("div",{class:"md-tooltip2__inner md-typeset"},e))}function An(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return S("aside",{class:"md-annotation",tabIndex:0},Dt(t),S("a",{href:r,class:"md-annotation__index",tabIndex:-1},S("span",{"data-md-annotation-id":e})))}else return S("aside",{class:"md-annotation",tabIndex:0},Dt(t),S("span",{class:"md-annotation__index",tabIndex:-1},S("span",{"data-md-annotation-id":e})))}function Cn(e){return S("button",{class:"md-code__button",title:Me("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function Hn(){return S("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function $n(){return S("nav",{class:"md-code__nav"})}function ro(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,S("del",null,p)," "],[]).slice(0,-1),i=we(),s=new URL(e.location,i.base);B("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=we();return S("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},S("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&S("div",{class:"md-search-result__icon md-icon"}),r>0&&S("h1",null,e.title),r<=0&&S("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return S("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&S("p",{class:"md-search-result__terms"},Me("search.result.term.missing"),": ",...n)))}function kn(e){let t=e[0].score,r=[...e],o=we(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scorero(l,1)),...c.length?[S("details",{class:"md-search-result__more"},S("summary",{tabIndex:-1},S("div",null,c.length>0&&c.length===1?Me("search.result.more.one"):Me("search.result.more.other",c.length))),...c.map(l=>ro(l,1)))]:[]];return S("li",{class:"md-search-result__item"},p)}function Rn(e){return S("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>S("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?vr(r):r)))}function oo(e){let t=`tabbed-control tabbed-control--${e}`;return S("div",{class:t,hidden:!0},S("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function Pn(e){return S("div",{class:"md-typeset__scrollwrap"},S("div",{class:"md-typeset__table"},e))}function Ua(e){let t=we(),r=new URL(`../${e.version}/`,t.base);return S("li",{class:"md-version__item"},S("a",{href:`${r}`,class:"md-version__link"},e.title))}function In(e,t){return S("div",{class:"md-version"},S("button",{class:"md-version__current","aria-label":Me("select.version")},t.title),S("ul",{class:"md-version__list"},e.map(Ua)))}var Da=0;function Na(e){let t=V([Ke(e),ot(e,250)]).pipe(m(([o,n])=>o||n),Q()),r=$(()=>pn(e)).pipe(J(Ye),vt(1),m(()=>nn(e)));return t.pipe(ke(o=>o),b(()=>V([t,r])),m(([o,n])=>({active:o,offset:n})),le())}function Nt(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Da++}`;return $(()=>{let i=new w,s=new jr(!1);i.pipe(te(),ae(!1)).subscribe(s);let a=s.pipe(jt(p=>He(+!p*250,Dr)),Q(),b(p=>p?r:x),T(p=>p.id=n),le());V([i.pipe(m(({active:p})=>p)),a.pipe(b(p=>ot(p,250)),K(!1))]).pipe(m(p=>p.some(l=>l))).subscribe(s);let c=s.pipe(v(p=>p),oe(a,o),m(([p,l,{size:f}])=>{let u=e.getBoundingClientRect(),d=u.width/2;if(l.role==="tooltip")return{x:d,y:8+u.height};if(u.y>=f.height/2){let{height:g}=ue(l);return{x:d,y:-16-g}}else return{x:d,y:16+u.height}}));return V([a,i,c]).subscribe(([p,{offset:l},f])=>{p.style.setProperty("--md-tooltip-host-x",`${l.x}px`),p.style.setProperty("--md-tooltip-host-y",`${l.y}px`),p.style.setProperty("--md-tooltip-x",`${f.x}px`),p.style.setProperty("--md-tooltip-y",`${f.y}px`),p.classList.toggle("md-tooltip2--top",f.y<0),p.classList.toggle("md-tooltip2--bottom",f.y>=0)}),s.pipe(v(p=>p),oe(a,(p,l)=>l),v(p=>p.role==="tooltip")).subscribe(p=>{let l=ue(F(":scope > *",p));p.style.setProperty("--md-tooltip-width",`${l.width}px`),p.style.setProperty("--md-tooltip-tail","0px")}),s.pipe(Q(),xe(ge),oe(a)).subscribe(([p,l])=>{l.classList.toggle("md-tooltip2--active",p)}),V([s.pipe(v(p=>p)),a]).subscribe(([p,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),s.pipe(v(p=>!p)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Na(e).pipe(T(p=>i.next(p)),_(()=>i.complete()),m(p=>k({ref:e},p)))})}function Va(e,t){let r=$(()=>V([an(e),Ye(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=ue(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Ke(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),ye(+!o||1/0))))}function Fn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return $(()=>{let i=new w,s=i.pipe(te(),ae(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),Ct(e).pipe(U(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),O(i.pipe(v(({active:a})=>a)),i.pipe(_e(250),v(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe($e(16,ge)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(vt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(U(s),v(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(U(s),oe(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Ve())==null||p.blur()}}),r.pipe(U(s),v(a=>a===o),rt(125)).subscribe(()=>e.focus()),Va(e,t).pipe(T(a=>i.next(a)),_(()=>i.complete()),m(a=>k({ref:e},a)))})}function za(e){let t=we();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(typeof t.annotate!="undefined"){let o=e.closest("[class|=language]");if(o)for(let n of Array.from(o.classList)){if(!n.startsWith("language-"))continue;let[,i]=n.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return C(r.join(", "),e)}function qa(e){let t=[];for(let r of za(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function jn(e,t){t.append(...Array.from(e.childNodes))}function Tr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of qa(t)){let[,c]=a.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${c})`,e)&&(s.set(c,An(c,i)),a.replaceWith(s.get(c)))}return s.size===0?x:$(()=>{let a=new w,c=a.pipe(te(),ae(!0)),p=[];for(let[l,f]of s)p.push([F(".md-typeset",f),F(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?jn(f,u):jn(u,f)}),O(...[...s].map(([,l])=>Fn(l,t,{target$:r}))).pipe(_(()=>a.complete()),le())})}function Wn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Wn(t)}}function Un(e,t){return $(()=>{let r=Wn(e);return typeof r!="undefined"?Tr(r,e,t):x})}var Nn=Gt(io());var Ka=0;function Qa(e,t){document.body.append(e);let{width:r}=ue(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=gr(t),n=typeof o!="undefined"?Ye(o):R({x:0,y:0}),i=O(Ke(t),ot(t)).pipe(Q());return V([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Qe(t),l=ue(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function pt(e){let t=e.title;if(!t.length)return x;let r=`__tooltip_${Ka++}`,o=Dt(r,"inline"),n=F(".md-typeset",o);return n.innerHTML=t,$(()=>{let i=new w;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),O(i.pipe(v(({active:s})=>s)),i.pipe(_e(250),v(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe($e(16,ge)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(vt(125,ge),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Qa(o,e).pipe(T(s=>i.next(s)),_(()=>i.complete()),m(s=>k({ref:e},s)))}).pipe(Xe(pe))}var Ya=0,Dn=O(h(window,"keydown").pipe(m(()=>!0)),O(h(window,"keyup"),h(window,"contextmenu")).pipe(m(()=>!1))).pipe(K(!1),X(1));function Vn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Vn(t)}}function Ba(e){return Ae(e).pipe(m(({width:t})=>({scrollable:At(e).width>t})),re("scrollable"))}function zn(e,t){let{matches:r}=matchMedia("(hover)"),o=$(()=>{let n=new w,i=n.pipe(Yr(1));n.subscribe(({scrollable:d})=>{d&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[],a=e.closest("pre"),c=a.closest("[id]"),p=c?c.id:Ya++;a.id=`__code_${p}`;let l=[],f=e.closest(".highlight");if(f instanceof HTMLElement){let d=Vn(f);if(typeof d!="undefined"&&(f.classList.contains("annotate")||B("content.code.annotate"))){let g=Tr(d,e,t);l.push(Ae(f).pipe(U(i),m(({width:M,height:ee})=>M&&ee),Q(),b(M=>M?g:x)))}}let u=C(":scope > span[id]",e);if(u.length&&(e.classList.add("md-code__content"),e.closest(".select")||B("content.code.select")&&!e.closest(".no-select"))){let d=+u[0].id.split("-").pop(),g=Hn();s.push(g),B("content.tooltips")&&l.push(pt(g));let M=h(g,"click").pipe(Wt(P=>!P,!1),T(()=>g.blur()),le());M.subscribe(P=>{g.classList.toggle("md-code__button--active",P)});let ee=de(u).pipe(J(P=>ot(P).pipe(m(se=>[P,se]))));M.pipe(b(P=>P?ee:x)).subscribe(([P,se])=>{let ce=fe(".hll.select",P);if(ce&&!se)ce.replaceWith(...Array.from(ce.childNodes));else if(!ce&&se){let he=document.createElement("span");he.className="hll select",he.append(...Array.from(P.childNodes).slice(1)),P.append(he)}});let ne=de(u).pipe(J(P=>h(P,"mousedown").pipe(T(se=>se.preventDefault()),m(()=>P)))),Z=M.pipe(b(P=>P?ne:x),oe(Dn),m(([P,se])=>{var he;let ce=u.indexOf(P)+d;if(se===!1)return[ce,ce];{let Te=C(".hll",e).map(je=>u.indexOf(je.parentElement)+d);return(he=window.getSelection())==null||he.removeAllRanges(),[Math.min(ce,...Te),Math.max(ce,...Te)]}})),H=Zr(x).pipe(v(P=>P.startsWith(`__codelineno-${p}-`)));H.subscribe(P=>{let[,,se]=P.split("-"),ce=se.split(":").map(Te=>+Te-d+1);ce.length===1&&ce.push(ce[0]);for(let Te of C(".hll:not(.select)",e))Te.replaceWith(...Array.from(Te.childNodes));let he=u.slice(ce[0]-1,ce[1]);for(let Te of he){let je=document.createElement("span");je.className="hll",je.append(...Array.from(Te.childNodes).slice(1)),Te.append(je)}}),H.pipe(ye(1),xe(pe)).subscribe(P=>{if(P.includes(":")){let se=document.getElementById(P.split(":")[0]);se&&setTimeout(()=>{let ce=se,he=-64;for(;ce!==document.body;)he+=ce.offsetTop,ce=ce.offsetParent;window.scrollTo({top:he})},1)}});let Fe=de(C('a[href^="#__codelineno"]',f)).pipe(J(P=>h(P,"click").pipe(T(se=>se.preventDefault()),m(()=>P)))).pipe(U(i),oe(Dn),m(([P,se])=>{let he=+F(`[id="${P.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(se===!1)return[he,he];{let Te=C(".hll",e).map(je=>+je.parentElement.id.split("-").pop());return[Math.min(he,...Te),Math.max(he,...Te)]}}));O(Z,Fe).subscribe(P=>{let se=`#__codelineno-${p}-`;P[0]===P[1]?se+=P[0]:se+=`${P[0]}:${P[1]}`,history.replaceState({},"",se),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+se,oldURL:window.location.href}))})}if(Nn.default.isSupported()&&(e.closest(".copy")||B("content.code.copy")&&!e.closest(".no-copy"))){let d=Cn(a.id);s.push(d),B("content.tooltips")&&l.push(pt(d))}if(s.length){let d=$n();d.append(...s),a.insertBefore(d,e)}return Ba(e).pipe(T(d=>n.next(d)),_(()=>n.complete()),m(d=>k({ref:e},d)),Ne(O(...l).pipe(U(i))))});return B("content.lazy")?Ct(e).pipe(v(n=>n),ye(1),b(()=>o)):o}function Ga(e,{target$:t,print$:r}){let o=!0;return O(t.pipe(m(n=>n.closest("details:not([open])")),v(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(v(n=>n||!o),T(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function qn(e,t){return $(()=>{let r=new w;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Ga(e,t).pipe(T(o=>r.next(o)),_(()=>r.complete()),m(o=>k({ref:e},o)))})}function Ja(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],o=e.nextElementSibling;for(;o&&!(o instanceof HTMLHeadingElement);)r.push(o),o=o.nextElementSibling;return r}function Kn(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return x;if(e.pathname===location.pathname)return x;if(!(B("navigation.instant.preview")||e.hasAttribute("data-preview")))return x;let o=V([Ke(e),ot(e)]).pipe(m(([i,s])=>i||s),Q(),v(i=>i));return ht([r,o]).pipe(b(([i])=>{let s=new URL(e.href);return s.search=s.hash="",i.has(`${s}`)?R(s):x}),b(i=>yr(i)),b(i=>{let s=e.hash?`article [id="${e.hash.slice(1)}"]`:"article h1",a=fe(s,i);return typeof a=="undefined"?x:R(Ja(a))})).pipe(b(i=>{let s=new j(a=>{let c=wr(...i);return a.next(c),document.body.append(c),()=>c.remove()});return Nt(e,k({content$:s},t))}))}var Qn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var ao,Za=0;function es(){return typeof mermaid=="undefined"||mermaid instanceof Element?_t("https://unpkg.com/mermaid@10.7.0/dist/mermaid.min.js"):R(void 0)}function Yn(e){return e.classList.remove("mermaid"),ao||(ao=es().pipe(T(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Qn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),X(1))),ao.subscribe(()=>bo(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Za++}`,r=S("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),ao.pipe(m(()=>({ref:e})))}var Bn=S("table");function Gn(e){return e.replaceWith(Bn),Bn.replaceWith(Pn(e)),R({ref:e})}function ts(e){let t=e.find(r=>r.checked)||e[0];return O(...e.map(r=>h(r,"change").pipe(m(()=>F(`label[for="${r.id}"]`))))).pipe(K(F(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Jn(e,{viewport$:t,target$:r}){let o=F(".tabbed-labels",e),n=C(":scope > input",e),i=oo("prev");e.append(i);let s=oo("next");return e.append(s),$(()=>{let a=new w,c=a.pipe(te(),ae(!0));V([a,Ae(e)]).pipe(U(c),$e(1,ge)).subscribe({next([{active:p},l]){let f=Qe(p),{width:u}=ue(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=br(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),V([Ye(o),Ae(o)]).pipe(U(c)).subscribe(([p,l])=>{let f=At(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),O(h(i,"click").pipe(m(()=>-1)),h(s,"click").pipe(m(()=>1))).pipe(U(c)).subscribe(p=>{let{width:l}=ue(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(U(c),v(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=F(`label[for="${p.id}"]`);l.replaceChildren(S("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(U(c),v(f=>!(f.metaKey||f.ctrlKey)),T(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return B("content.tabs.link")&&a.pipe(Re(1),oe(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let g of C("[data-tabs]"))for(let M of C(":scope > input",g)){let ee=F(`label[for="${M.id}"]`);if(ee!==p&&ee.innerText.trim()===f){ee.setAttribute("data-md-switching",""),M.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),a.pipe(U(c)).subscribe(()=>{for(let p of C("audio, video",e))p.pause()}),ts(n).pipe(T(p=>a.next(p)),_(()=>a.complete()),m(p=>k({ref:e},p)))}).pipe(Xe(pe))}function Xn(e,t){let{viewport$:r,target$:o,print$:n}=t;return O(...C(".annotate:not(.highlight)",e).map(i=>Un(i,{target$:o,print$:n})),...C("pre:not(.mermaid) > code",e).map(i=>zn(i,{target$:o,print$:n})),...C("a:not([title])",e).map(i=>Kn(i,t)),...C("pre.mermaid",e).map(i=>Yn(i)),...C("table:not([class])",e).map(i=>Gn(i)),...C("details",e).map(i=>qn(i,{target$:o,print$:n})),...C("[data-tabs]",e).map(i=>Jn(i,{viewport$:r,target$:o})),...C("[title]",e).filter(()=>B("content.tooltips")).map(i=>Nt(i,k({content$:new j(s=>{let a=i.title,c=_n(a);return s.next(c),i.removeAttribute("title"),document.body.append(c),()=>{c.remove(),i.setAttribute("title",a)}})},t))),...C(".footnote-ref",e).filter(()=>B("content.footnote.tooltips")).map(i=>Nt(i,k({content$:new j(s=>{let a=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(a).cloneNode(!0).children),p=wr(...c);return s.next(p),document.body.append(p),()=>p.remove()})},t))))}function rs(e,{alert$:t}){return t.pipe(b(r=>O(R(!0),R(!1).pipe(rt(2e3))).pipe(m(o=>({message:r,active:o})))))}function Zn(e,t){let r=F(".md-typeset",e);return $(()=>{let o=new w;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),rs(e,t).pipe(T(n=>o.next(n)),_(()=>o.complete()),m(n=>k({ref:e},n)))})}function os({viewport$:e}){if(!B("header.autohide"))return R(!1);let t=e.pipe(m(({offset:{y:n}})=>n),et(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Q()),o=Be("search");return V([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Q(),b(n=>n?r:R(!1)),K(!1))}function ei(e,t){return $(()=>V([Ae(e),os(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Q((r,o)=>r.height===o.height&&r.hidden===o.hidden),X(1))}function ti(e,{header$:t,main$:r}){return $(()=>{let o=new w,n=o.pipe(te(),ae(!0));o.pipe(re("active"),De(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=de(C("[title]",e)).pipe(v(()=>B("content.tooltips")),J(s=>pt(s)));return r.subscribe(o),t.pipe(U(n),m(s=>k({ref:e},s)),Ne(i.pipe(U(n))))})}function ns(e,{viewport$:t,header$:r}){return Er(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ue(e);return{active:o>=n}}),re("active"))}function ri(e,t){return $(()=>{let r=new w;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?x:ns(o,t).pipe(T(n=>r.next(n)),_(()=>r.complete()),m(n=>k({ref:e},n)))})}function oi(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Q()),n=o.pipe(b(()=>Ae(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),re("bottom"))));return V([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Q((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function is(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return R(...e).pipe(J(o=>h(o,"change").pipe(m(()=>o))),K(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),X(1))}function ni(e){let t=C("input",e),r=S("meta",{name:"theme-color"});document.head.appendChild(r);let o=S("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Ut("(prefers-color-scheme: light)");return $(()=>{let i=new w;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;a{let s=Ce("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(xe(pe)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),is(t).pipe(U(n.pipe(Re(1))),bt(),T(s=>i.next(s)),_(()=>i.complete()),m(s=>k({ref:e},s)))})}function ii(e,{progress$:t}){return $(()=>{let r=new w;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(T(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}function ai(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function as(e,t){let r=new Map;for(let o of C("url",e)){let n=F("loc",o),i=[ai(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of C("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(ai(new URL(a),t))}}return r}function $t(e){return xn(new URL("sitemap.xml",e)).pipe(m(t=>as(t,new URL(e))),Oe(()=>R(new Map)),le())}function si({document$:e}){let t=new Map;e.pipe(b(()=>C("link[rel=alternate]")),m(r=>new URL(r.href)),v(r=>!t.has(r.toString())),J(r=>$t(r).pipe(m(o=>[r,o])))).subscribe(([r,o])=>{t.set(r.toString().replace(/\/$/,""),o)}),h(document.body,"click").pipe(v(r=>!r.metaKey&&!r.ctrlKey),b(r=>{if(r.target instanceof Element){let o=r.target.closest("a");if(o&&!o.target){let n=[...t].find(([f])=>o.href.startsWith(f));if(typeof n=="undefined")return x;let[i,s]=n,a=Ee();if(a.href.startsWith(i))return x;let c=we(),p=a.href.replace(c.base,"");p=`${i}/${p}`;let l=s.has(p.split("#")[0])?new URL(p,c.base):new URL(i);return r.preventDefault(),R(l)}}return x})).subscribe(r=>it(r,!0))}var so=Gt(io());function ss(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function ci({alert$:e}){so.default.isSupported()&&new j(t=>{new so.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ss(F(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(T(t=>{t.trigger.focus()}),m(()=>Me("clipboard.copied"))).subscribe(e)}function pi(e,t){if(!(e.target instanceof Element))return x;let r=e.target.closest("a");if(r===null)return x;if(r.target||e.metaKey||e.ctrlKey)return x;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),R(r)):x}function li(e){let t=new Map;for(let r of C(":scope > *",e.head))t.set(r.outerHTML,r);return t}function mi(e){for(let t of C("[href], [src]",e))for(let r in["href","src"]){let o=t.getAttribute(r);/^(?:[a-z]+:)?\/\//i.test(o)||(t.href=t.href)}return R(e)}function cs(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...B("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=li(document);for(let[o,n]of li(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values())o.remove();let r=Ce("container");return qe(C("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),x}),te(),ae(e))}function fi({sitemap$:e,location$:t,viewport$:r,progress$:o}){if(location.protocol==="file:")return x;R(document).subscribe(mi);let n=h(document.body,"click").pipe(De(e),b(([a,c])=>pi(a,c)),m(({href:a})=>new URL(a)),le()),i=h(window,"popstate").pipe(m(Ee),le());n.pipe(oe(r)).subscribe(([a,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",a)}),O(n,i).subscribe(t);let s=t.pipe(re("pathname"),b(a=>yr(a,{progress$:o}).pipe(Oe(()=>(it(a,!0),x)))),b(mi),b(cs),le());return O(s.pipe(oe(t,(a,c)=>c)),t.pipe(re("pathname"),b(()=>t),re("hash")),t.pipe(Q((a,c)=>a.pathname===c.pathname&&a.hash===c.hash),b(()=>n),T(()=>history.back()))).subscribe(a=>{var c,p;history.state!==null||!a.hash?window.scrollTo(0,(p=(c=history.state)==null?void 0:c.y)!=null?p:0):(history.scrollRestoration="auto",bn(a.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(re("offset"),_e(100)).subscribe(({offset:a})=>{history.replaceState(a,"")}),B("navigation.instant.prefetch")&&O(h(document.body,"mousemove"),h(document.body,"focusin")).pipe(De(e),b(([a,c])=>pi(a,c)),_e(25),Qr(({href:a})=>a),hr(a=>{let c=document.createElement("link");return c.rel="prefetch",c.href=a.toString(),document.head.appendChild(c),h(c,"load").pipe(m(()=>c),ye(1))})).subscribe(a=>a.remove()),s}var hi=Gt(di());function bi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,hi.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function zt(e){return e.type===1}function Sr(e){return e.type===3}function vi(e,t){let r=On(e);return O(R(location.protocol!=="file:"),Be("search")).pipe(ke(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:B("search.suggest")}}})),r}function gi({document$:e}){let t=we(),r=Ge(new URL("../versions.json",t.base)).pipe(Oe(()=>x)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>h(document.body,"click").pipe(v(i=>!i.metaKey&&!i.ctrlKey),oe(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?x:(i.preventDefault(),R(c))}}return x}),b(i=>{let{version:s}=n.get(i);return $t(new URL(i)).pipe(m(a=>{let p=Ee().href.replace(t.base,"");return a.has(p.split("#")[0])?new URL(`../${s}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>it(n,!0)),V([r,o]).subscribe(([n,i])=>{F(".md-header__topic").appendChild(In(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of me("outdated"))a.hidden=!1})}function us(e,{worker$:t}){let{searchParams:r}=Ee();r.has("q")&&(nt("search",!0),e.value=r.get("q"),e.focus(),Be("search").pipe(ke(i=>!i)).subscribe(()=>{let i=Ee();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Ke(e),n=O(t.pipe(ke(zt)),h(e,"keyup"),o).pipe(m(()=>e.value),Q());return V([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),X(1))}function xi(e,{worker$:t}){let r=new w,o=r.pipe(te(),ae(!0));V([t.pipe(ke(zt)),r],(i,s)=>s).pipe(re("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(re("focus")).subscribe(({focus:i})=>{i&&nt("search",i)}),h(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=F("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),us(e,{worker$:t}).pipe(T(i=>r.next(i)),_(()=>r.complete()),m(i=>k({ref:e},i)),X(1))}function yi(e,{worker$:t,query$:r}){let o=new w,n=mn(e.parentElement).pipe(v(Boolean)),i=e.parentElement,s=F(":scope > :first-child",e),a=F(":scope > :last-child",e);Be("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(oe(r),Gr(t.pipe(ke(zt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?Me("search.result.none"):Me("search.result.placeholder");break;case 1:s.textContent=Me("search.result.one");break;default:let u=vr(l.length);s.textContent=Me("search.result.other",u)}});let c=o.pipe(T(()=>a.innerHTML=""),b(({items:l})=>O(R(...l.slice(0,10)),R(...l.slice(10)).pipe(et(4),Xr(n),b(([f])=>f)))),m(kn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(J(l=>{let f=fe("details",l);return typeof f=="undefined"?x:h(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(v(Sr),m(({data:l})=>l)).pipe(T(l=>o.next(l)),_(()=>o.complete()),m(l=>k({ref:e},l)))}function ds(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=Ee();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Ei(e,t){let r=new w,o=r.pipe(te(),ae(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),ds(e,t).pipe(T(n=>r.next(n)),_(()=>r.complete()),m(n=>k({ref:e},n)))}function wi(e,{worker$:t,keyboard$:r}){let o=new w,n=Ce("search-query"),i=O(h(n,"keydown"),h(n,"focus")).pipe(xe(pe),m(()=>n.value),Q());return o.pipe(De(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(v(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(v(Sr),m(({data:a})=>a)).pipe(T(a=>o.next(a)),_(()=>o.complete()),m(()=>({ref:e})))}function Ti(e,{index$:t,keyboard$:r}){let o=we();try{let n=vi(o.search,t),i=Ce("search-query",e),s=Ce("search-result",e);h(e,"click").pipe(v(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>nt("search",!1)),r.pipe(v(({mode:c})=>c==="search")).subscribe(c=>{let p=Ve();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of C(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":nt("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...C(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Ve()&&i.focus()}}),r.pipe(v(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=xi(i,{worker$:n});return O(a,yi(s,{worker$:n,query$:a})).pipe(Ne(...me("search-share",e).map(c=>Ei(c,{query$:a})),...me("search-suggest",e).map(c=>wi(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ze}}function Si(e,{index$:t,location$:r}){return V([t,r.pipe(K(Ee()),v(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>bi(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=S("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function hs(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return V([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Q((i,s)=>i.height===s.height&&i.locked===s.locked))}function co(e,o){var n=o,{header$:t}=n,r=ho(n,["header$"]);let i=F(".md-sidebar__scrollwrap",e),{y:s}=Qe(i);return $(()=>{let a=new w,c=a.pipe(te(),ae(!0)),p=a.pipe($e(0,ge));return p.pipe(oe(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(ke()).subscribe(()=>{for(let l of C(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ue(f);f.scrollTo({top:u-d/2})}}}),de(C("label[tabindex]",e)).pipe(J(l=>h(l,"click").pipe(xe(pe),m(()=>l),U(c)))).subscribe(l=>{let f=F(`[id="${l.htmlFor}"]`);F(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),hs(e,r).pipe(T(l=>a.next(l)),_(()=>a.complete()),m(l=>k({ref:e},l)))})}function Oi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return ht(Ge(`${r}/releases/latest`).pipe(Oe(()=>x),m(o=>({version:o.tag_name})),tt({})),Ge(r).pipe(Oe(()=>x),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),tt({}))).pipe(m(([o,n])=>k(k({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ge(r).pipe(m(o=>({repositories:o.public_repos})),tt({}))}}function Mi(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ge(r).pipe(Oe(()=>x),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),tt({}))}function Li(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Oi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return Mi(r,o)}return x}var bs;function vs(e){return bs||(bs=$(()=>{let t=__md_get("__source",sessionStorage);if(t)return R(t);if(me("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return x}return Li(e.href).pipe(T(o=>__md_set("__source",o,sessionStorage)))}).pipe(Oe(()=>x),v(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function _i(e){let t=F(":scope > :last-child",e);return $(()=>{let r=new w;return r.subscribe(({facts:o})=>{t.appendChild(Rn(o)),t.classList.add("md-source__repository--active")}),vs(e).pipe(T(o=>r.next(o)),_(()=>r.complete()),m(o=>k({ref:e},o)))})}function gs(e,{viewport$:t,header$:r}){return Ae(document.body).pipe(b(()=>Er(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),re("hidden"))}function Ai(e,t){return $(()=>{let r=new w;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(B("navigation.tabs.sticky")?R({hidden:!1}):gs(e,t)).pipe(T(o=>r.next(o)),_(()=>r.complete()),m(o=>k({ref:e},o)))})}function xs(e,{viewport$:t,header$:r}){let o=new Map,n=C("[href^=\\#]",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=fe(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(re("height"),m(({height:a})=>{let c=Ce("main"),p=F(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Ae(document.body).pipe(re("height"),b(a=>$(()=>{let c=[];return R([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),De(i),b(([c,p])=>t.pipe(Wt(([l,f],{offset:{y:u},size:d})=>{let g=u+d.height>=Math.floor(a.height);for(;f.length;){let[,M]=f[0];if(M-p=u&&!g)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Q((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),K({prev:[],next:[]}),et(2,1),m(([a,c])=>a.prev.length{let i=new w,s=i.pipe(te(),ae(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),B("toc.follow")){let a=O(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(v(({prev:c})=>c.length>0),De(o.pipe(xe(pe))),oe(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=gr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ue(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return B("navigation.tracking")&&t.pipe(U(s),re("offset"),_e(250),Re(1),U(n.pipe(Re(1))),bt({delay:250}),oe(i)).subscribe(([,{prev:a}])=>{let c=Ee(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),xs(e,{viewport$:t,header$:r}).pipe(T(a=>i.next(a)),_(()=>i.complete()),m(a=>k({ref:e},a)))})}function ys(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),et(2,1),m(([s,a])=>s>a&&a>0),Q()),i=r.pipe(m(({active:s})=>s));return V([i,n]).pipe(m(([s,a])=>!(s&&a)),Q(),U(o.pipe(Re(1))),ae(!0),bt({delay:250}),m(s=>({hidden:s})))}function Hi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new w,s=i.pipe(te(),ae(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(s),re("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),ys(e,{viewport$:t,main$:o,target$:n}).pipe(T(a=>i.next(a)),_(()=>i.complete()),m(a=>k({ref:e},a)))}function $i({document$:e}){e.pipe(b(()=>C(".md-ellipsis")),J(t=>Ct(t).pipe(U(e.pipe(Re(1))),v(r=>r),m(()=>t),ye(1))),v(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,pt(o).pipe(U(e.pipe(Re(1))),_(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>C(".md-status")),J(t=>pt(t))).subscribe()}function ki({document$:e,tablet$:t}){e.pipe(b(()=>C(".md-toggle--indeterminate")),T(r=>{r.indeterminate=!0,r.checked=!1}),J(r=>h(r,"change").pipe(Jr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),oe(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Es(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ri({document$:e}){e.pipe(b(()=>C("[data-md-scrollfix]")),T(t=>t.removeAttribute("data-md-scrollfix")),v(Es),J(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Pi({viewport$:e,tablet$:t}){V([Be("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>R(r).pipe(rt(r?400:100))),oe(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ws(){return location.protocol==="file:"?_t(`${new URL("search/search_index.js",Or.base)}`).pipe(m(()=>__index),X(1)):Ge(new URL("search/search_index.json",Or.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var at=on(),Kt=dn(),kt=vn(Kt),po=un(),Pe=Sn(),Mr=Ut("(min-width: 960px)"),Fi=Ut("(min-width: 1220px)"),ji=gn(),Or=we(),Wi=document.forms.namedItem("search")?ws():Ze,lo=new w;ci({alert$:lo});si({document$:at});var mo=new w,Ui=$t(Or.base);B("navigation.instant")&&fi({sitemap$:Ui,location$:Kt,viewport$:Pe,progress$:mo}).subscribe(at);var Ii;((Ii=Or.version)==null?void 0:Ii.provider)==="mike"&&gi({document$:at});O(Kt,kt).pipe(rt(125)).subscribe(()=>{nt("drawer",!1),nt("search",!1)});po.pipe(v(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&it(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&it(r);break;case"Enter":let o=Ve();o instanceof HTMLLabelElement&&o.click()}});$i({document$:at});ki({document$:at,tablet$:Mr});Ri({document$:at});Pi({viewport$:Pe,tablet$:Mr});var lt=ei(Ce("header"),{viewport$:Pe}),qt=at.pipe(m(()=>Ce("main")),b(e=>oi(e,{viewport$:Pe,header$:lt})),X(1)),Ts=O(...me("consent").map(e=>Ln(e,{target$:kt})),...me("dialog").map(e=>Zn(e,{alert$:lo})),...me("header").map(e=>ti(e,{viewport$:Pe,header$:lt,main$:qt})),...me("palette").map(e=>ni(e)),...me("progress").map(e=>ii(e,{progress$:mo})),...me("search").map(e=>Ti(e,{index$:Wi,keyboard$:po})),...me("source").map(e=>_i(e))),Ss=$(()=>O(...me("announce").map(e=>Mn(e)),...me("content").map(e=>Xn(e,{sitemap$:Ui,viewport$:Pe,target$:kt,print$:ji})),...me("content").map(e=>B("search.highlight")?Si(e,{index$:Wi,location$:Kt}):x),...me("header-title").map(e=>ri(e,{viewport$:Pe,header$:lt})),...me("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?eo(Fi,()=>co(e,{viewport$:Pe,header$:lt,main$:qt})):eo(Mr,()=>co(e,{viewport$:Pe,header$:lt,main$:qt}))),...me("tabs").map(e=>Ai(e,{viewport$:Pe,header$:lt})),...me("toc").map(e=>Ci(e,{viewport$:Pe,header$:lt,main$:qt,target$:kt})),...me("top").map(e=>Hi(e,{viewport$:Pe,header$:lt,main$:qt,target$:kt})))),Di=at.pipe(b(()=>Ss),Ne(Ts),X(1));Di.subscribe();window.document$=at;window.location$=Kt;window.target$=kt;window.keyboard$=po;window.viewport$=Pe;window.tablet$=Mr;window.screen$=Fi;window.print$=ji;window.alert$=lo;window.progress$=mo;window.component$=Di;})(); diff --git a/assets/javascripts/lunr/min/lunr.ar.min.js b/assets/javascripts/lunr/min/lunr.ar.min.js new file mode 100644 index 00000000..9b06c26c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ar.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.de.min.js b/assets/javascripts/lunr/min/lunr.de.min.js new file mode 100644 index 00000000..f3b5c108 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.de.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.du.min.js b/assets/javascripts/lunr/min/lunr.du.min.js new file mode 100644 index 00000000..49a0f3f0 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.du.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.el.min.js b/assets/javascripts/lunr/min/lunr.el.min.js new file mode 100644 index 00000000..ace017bd --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.el.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.el=function(){this.pipeline.reset(),void 0===this.searchPipeline&&this.pipeline.add(e.el.trimmer,e.el.normilizer),this.pipeline.add(e.el.stopWordFilter,e.el.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.el.stemmer))},e.el.wordCharacters="A-Za-zΑαΒβΓγΔδΕεΖζΗηΘθΙιΚκΛλΜμΝνΞξΟοΠπΡρΣσςΤτΥυΦφΧχΨψΩωΆάΈέΉήΊίΌόΎύΏώΪΐΫΰΐΰ",e.el.trimmer=e.trimmerSupport.generateTrimmer(e.el.wordCharacters),e.Pipeline.registerFunction(e.el.trimmer,"trimmer-el"),e.el.stemmer=function(){function e(e){return s.test(e)}function t(e){return/[ΑΕΗΙΟΥΩ]$/.test(e)}function r(e){return/[ΑΕΗΙΟΩ]$/.test(e)}function n(n){var s=n;if(n.length<3)return s;if(!e(n))return s;if(i.indexOf(n)>=0)return s;var u=new RegExp("(.*)("+Object.keys(l).join("|")+")$"),o=u.exec(s);return null!==o&&(s=o[1]+l[o[2]]),null!==(o=/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ|ΜΟΥΣΑΜ|ΚΑΠΛΑΜ|ΠΑΡ|ΨΑΡ|ΤΖΟΥΡ|ΤΑΜΠΟΥΡ|ΓΑΛΑΤ|ΦΑΦΛΑΤ)$/.test(o[1])||(s+="ΑΔ")),null!==(o=/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/.exec(s))&&(s=o[1],/(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/.test(o[1])&&(s+="ΕΔ")),null!==(o=/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/.exec(s))&&(s=o[1],/(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/.test(o[1])&&(s+="ΟΥΔ")),null!==(o=/^(.+?)(ΕΩΣ|ΕΩΝ|ΕΑΣ|ΕΑ)$/.exec(s))&&(s=o[1],/^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ|ΣΤΕΡ|ΟΡΦ|ΑΝΔΡ|ΑΝΤΡ)$/.test(o[1])&&(s+="Ε")),null!==(o=/^(.+?)(ΕΙΟ|ΕΙΟΣ|ΕΙΟΙ|ΕΙΑ|ΕΙΑΣ|ΕΙΕΣ|ΕΙΟΥ|ΕΙΟΥΣ|ΕΙΩΝ)$/.exec(s))&&o[1].length>4&&(s=o[1]),null!==(o=/^(.+?)(ΙΟΥΣ|ΙΑΣ|ΙΕΣ|ΙΟΣ|ΙΟΥ|ΙΟΙ|ΙΩΝ|ΙΟΝ|ΙΑ|ΙΟ)$/.exec(s))&&(s=o[1],(t(s)||s.length<2||/^(ΑΓ|ΑΓΓΕΛ|ΑΓΡ|ΑΕΡ|ΑΘΛ|ΑΚΟΥΣ|ΑΞ|ΑΣ|Β|ΒΙΒΛ|ΒΥΤ|Γ|ΓΙΑΓ|ΓΩΝ|Δ|ΔΑΝ|ΔΗΛ|ΔΗΜ|ΔΟΚΙΜ|ΕΛ|ΖΑΧΑΡ|ΗΛ|ΗΠ|ΙΔ|ΙΣΚ|ΙΣΤ|ΙΟΝ|ΙΩΝ|ΚΙΜΩΛ|ΚΟΛΟΝ|ΚΟΡ|ΚΤΗΡ|ΚΥΡ|ΛΑΓ|ΛΟΓ|ΜΑΓ|ΜΠΑΝ|ΜΠΡ|ΝΑΥΤ|ΝΟΤ|ΟΠΑΛ|ΟΞ|ΟΡ|ΟΣ|ΠΑΝΑΓ|ΠΑΤΡ|ΠΗΛ|ΠΗΝ|ΠΛΑΙΣ|ΠΟΝΤ|ΡΑΔ|ΡΟΔ|ΣΚ|ΣΚΟΡΠ|ΣΟΥΝ|ΣΠΑΝ|ΣΤΑΔ|ΣΥΡ|ΤΗΛ|ΤΙΜ|ΤΟΚ|ΤΟΠ|ΤΡΟΧ|ΦΙΛ|ΦΩΤ|Χ|ΧΙΛ|ΧΡΩΜ|ΧΩΡ)$/.test(o[1]))&&(s+="Ι"),/^(ΠΑΛ)$/.test(o[1])&&(s+="ΑΙ")),null!==(o=/^(.+?)(ΙΚΟΣ|ΙΚΟΝ|ΙΚΕΙΣ|ΙΚΟΙ|ΙΚΕΣ|ΙΚΟΥΣ|ΙΚΗ|ΙΚΗΣ|ΙΚΟ|ΙΚΑ|ΙΚΟΥ|ΙΚΩΝ|ΙΚΩΣ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΑΔ|ΑΛ|ΑΜΑΝ|ΑΜΕΡ|ΑΜΜΟΧΑΛ|ΑΝΗΘ|ΑΝΤΙΔ|ΑΠΛ|ΑΤΤ|ΑΦΡ|ΒΑΣ|ΒΡΩΜ|ΓΕΝ|ΓΕΡ|Δ|ΔΙΚΑΝ|ΔΥΤ|ΕΙΔ|ΕΝΔ|ΕΞΩΔ|ΗΘ|ΘΕΤ|ΚΑΛΛΙΝ|ΚΑΛΠ|ΚΑΤΑΔ|ΚΟΥΖΙΝ|ΚΡ|ΚΩΔ|ΛΟΓ|Μ|ΜΕΡ|ΜΟΝΑΔ|ΜΟΥΛ|ΜΟΥΣ|ΜΠΑΓΙΑΤ|ΜΠΑΝ|ΜΠΟΛ|ΜΠΟΣ|ΜΥΣΤ|Ν|ΝΙΤ|ΞΙΚ|ΟΠΤ|ΠΑΝ|ΠΕΤΣ|ΠΙΚΑΝΤ|ΠΙΤΣ|ΠΛΑΣΤ|ΠΛΙΑΤΣ|ΠΟΝΤ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΗΜΑΝΤ|ΣΤΑΤ|ΣΥΝΑΔ|ΣΥΝΟΜΗΛ|ΤΕΛ|ΤΕΧΝ|ΤΡΟΠ|ΤΣΑΜ|ΥΠΟΔ|Φ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΦΥΣ|ΧΑΣ)$/.test(o[1])||/(ΦΟΙΝ)$/.test(o[1]))&&(s+="ΙΚ")),"ΑΓΑΜΕ"===s&&(s="ΑΓΑΜ"),null!==(o=/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΑΜΕ)$/.exec(s))&&(s=o[1],/^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/.test(o[1])&&(s+="ΑΜ")),null!==(o=/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/.exec(s))&&(s=o[1],/^(ΤΡ|ΤΣ)$/.test(o[1])&&(s+="ΑΓΑΝ")),null!==(o=/^(.+?)(ΑΝΕ)$/.exec(s))&&(s=o[1],(r(s)||/^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜΑΝ|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/.test(o[1]))&&(s+="ΑΝ")),null!==(o=/^(.+?)(ΗΣΕΤΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΕΤΕ)$/.exec(s))&&(s=o[1],(r(s)||/(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/.test(o[1])||/^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/.test(o[1]))&&(s+="ΕΤ")),null!==(o=/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/.exec(s))&&(s=o[1],/^ΑΡΧ$/.test(o[1])&&(s+="ΟΝΤ"),/ΚΡΕ$/.test(o[1])&&(s+="ΩΝΤ")),null!==(o=/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/.exec(s))&&(s=o[1],/^ΟΝ$/.test(o[1])&&(s+="ΟΜΑΣΤ")),null!==(o=/^(.+?)(ΙΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/.test(o[1])&&(s+="ΙΕΣΤ")),null!==(o=/^(.+?)(ΕΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΠΡΟ|ΝΙΣ)$/.test(o[1])&&(s+="ΕΣΤ")),null!==(o=/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/.exec(s))&&(s=o[1]),null!==(o=/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/.exec(s))&&(s=o[1],(/(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/.test(o[1])||/^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ)$/.test(o[1]))&&(s+="ΗΚ")),null!==(o=/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/.exec(s))&&(s=o[1],(t(s)||/^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ)$/.test(o[1])||/(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/.test(o[1]))&&(s+="ΟΥΣ")),null!==(o=/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/.exec(s))&&(s=o[1],(/^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/.test(o[1])||/(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/.test(o[1])&&!/^(ΨΟΦ|ΝΑΥΛΟΧ)$/.test(o[1])||/(ΚΟΛΛ)$/.test(o[1]))&&(s+="ΑΓ")),null!==(o=/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/.exec(s))&&(s=o[1],/^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ|Ι)$/.test(o[1])&&(s+="ΗΣ")),null!==(o=/^(.+?)(ΗΣΤΕ)$/.exec(s))&&(s=o[1],/^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/.test(o[1])&&(s+="ΗΣΤ")),null!==(o=/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/.exec(s))&&(s=o[1],/^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/.test(o[1])&&(s+="ΟΥΝ")),null!==(o=/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/.exec(s))&&(s=o[1],/^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/.test(o[1])&&(s+="ΟΥΜ")),null!=(o=/^(.+?)(ΜΑΤΟΙ|ΜΑΤΟΥΣ|ΜΑΤΟ|ΜΑΤΑ|ΜΑΤΩΣ|ΜΑΤΩΝ|ΜΑΤΟΣ|ΜΑΤΕΣ|ΜΑΤΗ|ΜΑΤΗΣ|ΜΑΤΟΥ)$/.exec(s))&&(s=o[1]+"Μ",/^(ΓΡΑΜ)$/.test(o[1])?s+="Α":/^(ΓΕ|ΣΤΑ)$/.test(o[1])&&(s+="ΑΤ")),null!==(o=/^(.+?)(ΟΥΑ)$/.exec(s))&&(s=o[1]+"ΟΥ"),n.length===s.length&&null!==(o=/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ||ΥΑ|ΥΣ|Ω|ΩΝ|ΟΙΣ)$/.exec(s))&&(s=o[1]),null!=(o=/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/.exec(s))&&(/^(ΕΞ|ΕΣ|ΑΝ|ΚΑΤ|Κ|ΠΡ)$/.test(o[1])||(s=o[1]),/^(ΚΑ|Μ|ΕΛΕ|ΛΕ|ΔΕ)$/.test(o[1])&&(s+="ΥΤ")),s}var l={"ΦΑΓΙΑ":"ΦΑ","ΦΑΓΙΟΥ":"ΦΑ","ΦΑΓΙΩΝ":"ΦΑ","ΣΚΑΓΙΑ":"ΣΚΑ","ΣΚΑΓΙΟΥ":"ΣΚΑ","ΣΚΑΓΙΩΝ":"ΣΚΑ","ΣΟΓΙΟΥ":"ΣΟ","ΣΟΓΙΑ":"ΣΟ","ΣΟΓΙΩΝ":"ΣΟ","ΤΑΤΟΓΙΑ":"ΤΑΤΟ","ΤΑΤΟΓΙΟΥ":"ΤΑΤΟ","ΤΑΤΟΓΙΩΝ":"ΤΑΤΟ","ΚΡΕΑΣ":"ΚΡΕ","ΚΡΕΑΤΟΣ":"ΚΡΕ","ΚΡΕΑΤΑ":"ΚΡΕ","ΚΡΕΑΤΩΝ":"ΚΡΕ","ΠΕΡΑΣ":"ΠΕΡ","ΠΕΡΑΤΟΣ":"ΠΕΡ","ΠΕΡΑΤΑ":"ΠΕΡ","ΠΕΡΑΤΩΝ":"ΠΕΡ","ΤΕΡΑΣ":"ΤΕΡ","ΤΕΡΑΤΟΣ":"ΤΕΡ","ΤΕΡΑΤΑ":"ΤΕΡ","ΤΕΡΑΤΩΝ":"ΤΕΡ","ΦΩΣ":"ΦΩ","ΦΩΤΟΣ":"ΦΩ","ΦΩΤΑ":"ΦΩ","ΦΩΤΩΝ":"ΦΩ","ΚΑΘΕΣΤΩΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΟΣ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΑ":"ΚΑΘΕΣΤ","ΚΑΘΕΣΤΩΤΩΝ":"ΚΑΘΕΣΤ","ΓΕΓΟΝΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΟΣ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΑ":"ΓΕΓΟΝ","ΓΕΓΟΝΟΤΩΝ":"ΓΕΓΟΝ","ΕΥΑ":"ΕΥ"},i=["ΑΚΡΙΒΩΣ","ΑΛΑ","ΑΛΛΑ","ΑΛΛΙΩΣ","ΑΛΛΟΤΕ","ΑΜΑ","ΑΝΩ","ΑΝΑ","ΑΝΑΜΕΣΑ","ΑΝΑΜΕΤΑΞΥ","ΑΝΕΥ","ΑΝΤΙ","ΑΝΤΙΠΕΡΑ","ΑΝΤΙΟ","ΑΞΑΦΝΑ","ΑΠΟ","ΑΠΟΨΕ","ΑΡΑ","ΑΡΑΓΕ","ΑΥΡΙΟ","ΑΦΟΙ","ΑΦΟΥ","ΑΦΟΤΟΥ","ΒΡΕ","ΓΕΙΑ","ΓΙΑ","ΓΙΑΤΙ","ΓΡΑΜΜΑ","ΔΕΗ","ΔΕΝ","ΔΗΛΑΔΗ","ΔΙΧΩΣ","ΔΥΟ","ΕΑΝ","ΕΓΩ","ΕΔΩ","ΕΔΑ","ΕΙΘΕ","ΕΙΜΑΙ","ΕΙΜΑΣΤΕ","ΕΙΣΑΙ","ΕΙΣΑΣΤΕ","ΕΙΝΑΙ","ΕΙΣΤΕ","ΕΙΤΕ","ΕΚΕΙ","ΕΚΟ","ΕΛΑ","ΕΜΑΣ","ΕΜΕΙΣ","ΕΝΤΕΛΩΣ","ΕΝΤΟΣ","ΕΝΤΩΜΕΤΑΞΥ","ΕΝΩ","ΕΞΙ","ΕΞΙΣΟΥ","ΕΞΗΣ","ΕΞΩ","ΕΟΚ","ΕΠΑΝΩ","ΕΠΕΙΔΗ","ΕΠΕΙΤΑ","ΕΠΙ","ΕΠΙΣΗΣ","ΕΠΟΜΕΝΩΣ","ΕΠΤΑ","ΕΣΑΣ","ΕΣΕΙΣ","ΕΣΤΩ","ΕΣΥ","ΕΣΩ","ΕΤΣΙ","ΕΥΓΕ","ΕΦΕ","ΕΦΕΞΗΣ","ΕΧΤΕΣ","ΕΩΣ","ΗΔΗ","ΗΜΙ","ΗΠΑ","ΗΤΟΙ","ΘΕΣ","ΙΔΙΩΣ","ΙΔΗ","ΙΚΑ","ΙΣΩΣ","ΚΑΘΕ","ΚΑΘΕΤΙ","ΚΑΘΟΛΟΥ","ΚΑΘΩΣ","ΚΑΙ","ΚΑΝ","ΚΑΠΟΤΕ","ΚΑΠΟΥ","ΚΑΤΑ","ΚΑΤΙ","ΚΑΤΟΠΙΝ","ΚΑΤΩ","ΚΕΙ","ΚΙΧ","ΚΚΕ","ΚΟΛΑΝ","ΚΥΡΙΩΣ","ΚΩΣ","ΜΑΚΑΡΙ","ΜΑΛΙΣΤΑ","ΜΑΛΛΟΝ","ΜΑΙ","ΜΑΟ","ΜΑΟΥΣ","ΜΑΣ","ΜΕΘΑΥΡΙΟ","ΜΕΣ","ΜΕΣΑ","ΜΕΤΑ","ΜΕΤΑΞΥ","ΜΕΧΡΙ","ΜΗΔΕ","ΜΗΝ","ΜΗΠΩΣ","ΜΗΤΕ","ΜΙΑ","ΜΙΑΣ","ΜΙΣ","ΜΜΕ","ΜΟΛΟΝΟΤΙ","ΜΟΥ","ΜΠΑ","ΜΠΑΣ","ΜΠΟΥΦΑΝ","ΜΠΡΟΣ","ΝΑΙ","ΝΕΣ","ΝΤΑ","ΝΤΕ","ΞΑΝΑ","ΟΗΕ","ΟΚΤΩ","ΟΜΩΣ","ΟΝΕ","ΟΠΑ","ΟΠΟΥ","ΟΠΩΣ","ΟΣΟ","ΟΤΑΝ","ΟΤΕ","ΟΤΙ","ΟΥΤΕ","ΟΧΙ","ΠΑΛΙ","ΠΑΝ","ΠΑΝΟ","ΠΑΝΤΟΤΕ","ΠΑΝΤΟΥ","ΠΑΝΤΩΣ","ΠΑΝΩ","ΠΑΡΑ","ΠΕΡΑ","ΠΕΡΙ","ΠΕΡΙΠΟΥ","ΠΙΑ","ΠΙΟ","ΠΙΣΩ","ΠΛΑΙ","ΠΛΕΟΝ","ΠΛΗΝ","ΠΟΤΕ","ΠΟΥ","ΠΡΟ","ΠΡΟΣ","ΠΡΟΧΤΕΣ","ΠΡΟΧΘΕΣ","ΡΟΔΙ","ΠΩΣ","ΣΑΙ","ΣΑΣ","ΣΑΝ","ΣΕΙΣ","ΣΙΑ","ΣΚΙ","ΣΟΙ","ΣΟΥ","ΣΡΙ","ΣΥΝ","ΣΥΝΑΜΑ","ΣΧΕΔΟΝ","ΤΑΔΕ","ΤΑΞΙ","ΤΑΧΑ","ΤΕΙ","ΤΗΝ","ΤΗΣ","ΤΙΠΟΤΑ","ΤΙΠΟΤΕ","ΤΙΣ","ΤΟΝ","ΤΟΤΕ","ΤΟΥ","ΤΟΥΣ","ΤΣΑ","ΤΣΕ","ΤΣΙ","ΤΣΟΥ","ΤΩΝ","ΥΠΟ","ΥΠΟΨΗ","ΥΠΟΨΙΝ","ΥΣΤΕΡΑ","ΦΕΤΟΣ","ΦΙΣ","ΦΠΑ","ΧΑΦ","ΧΘΕΣ","ΧΤΕΣ","ΧΩΡΙΣ","ΩΣ","ΩΣΑΝ","ΩΣΟΤΟΥ","ΩΣΠΟΥ","ΩΣΤΕ","ΩΣΤΟΣΟ"],s=new RegExp("^[ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ]+$");return function(e){return"function"==typeof e.update?e.update(function(e){return n(e.toUpperCase()).toLowerCase()}):n(e.toUpperCase()).toLowerCase()}}(),e.Pipeline.registerFunction(e.el.stemmer,"stemmer-el"),e.el.stopWordFilter=e.generateStopWordFilter("αλλα αν αντι απο αυτα αυτεσ αυτη αυτο αυτοι αυτοσ αυτουσ αυτων για δε δεν εαν ειμαι ειμαστε ειναι εισαι ειστε εκεινα εκεινεσ εκεινη εκεινο εκεινοι εκεινοσ εκεινουσ εκεινων ενω επι η θα ισωσ κ και κατα κι μα με μετα μη μην να ο οι ομωσ οπωσ οσο οτι παρα ποια ποιεσ ποιο ποιοι ποιοσ ποιουσ ποιων που προσ πωσ σε στη στην στο στον τα την τησ το τον τοτε του των ωσ".split(" ")),e.Pipeline.registerFunction(e.el.stopWordFilter,"stopWordFilter-el"),e.el.normilizer=function(){var e={"Ά":"Α","ά":"α","Έ":"Ε","έ":"ε","Ή":"Η","ή":"η","Ί":"Ι","ί":"ι","Ό":"Ο","ο":"ο","Ύ":"Υ","ύ":"υ","Ώ":"Ω","ώ":"ω","Ϊ":"Ι","ϊ":"ι","Ϋ":"Υ","ϋ":"υ","ΐ":"ι","ΰ":"υ"};return function(t){if("function"==typeof t.update)return t.update(function(t){for(var r="",n=0;n=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fi.min.js b/assets/javascripts/lunr/min/lunr.fi.min.js new file mode 100644 index 00000000..29f5dfce --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fi.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fr.min.js b/assets/javascripts/lunr/min/lunr.fr.min.js new file mode 100644 index 00000000..68cd0094 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.he.min.js b/assets/javascripts/lunr/min/lunr.he.min.js new file mode 100644 index 00000000..b863d3ea --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.he.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hi.min.js b/assets/javascripts/lunr/min/lunr.hi.min.js new file mode 100644 index 00000000..7dbc4140 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hu.min.js b/assets/javascripts/lunr/min/lunr.hu.min.js new file mode 100644 index 00000000..ed9d909f --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hu.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hy.min.js b/assets/javascripts/lunr/min/lunr.hy.min.js new file mode 100644 index 00000000..b37f7929 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hy.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.it.min.js b/assets/javascripts/lunr/min/lunr.it.min.js new file mode 100644 index 00000000..344b6a3c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.it.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ja.min.js b/assets/javascripts/lunr/min/lunr.ja.min.js new file mode 100644 index 00000000..5f254ebe --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ja.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.no.min.js b/assets/javascripts/lunr/min/lunr.no.min.js new file mode 100644 index 00000000..92bc7e4e --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.no.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js new file mode 100644 index 00000000..6c16996d --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.pt.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js new file mode 100644 index 00000000..72771401 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ro.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ru.min.js b/assets/javascripts/lunr/min/lunr.ru.min.js new file mode 100644 index 00000000..186cc485 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ru.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.sv.min.js b/assets/javascripts/lunr/min/lunr.sv.min.js new file mode 100644 index 00000000..3e5eb640 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.sv.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ta.min.js b/assets/javascripts/lunr/min/lunr.ta.min.js new file mode 100644 index 00000000..a644bed2 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ta.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.te.min.js b/assets/javascripts/lunr/min/lunr.te.min.js new file mode 100644 index 00000000..9fa7a93b --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.te.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.th.min.js b/assets/javascripts/lunr/min/lunr.th.min.js new file mode 100644 index 00000000..dee3aac6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.th.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.tr.min.js b/assets/javascripts/lunr/min/lunr.tr.min.js new file mode 100644 index 00000000..563f6ec1 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.tr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.vi.min.js b/assets/javascripts/lunr/min/lunr.vi.min.js new file mode 100644 index 00000000..22aed28c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.vi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.zh.min.js b/assets/javascripts/lunr/min/lunr.zh.min.js new file mode 100644 index 00000000..fda66e9c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/tinyseg.js b/assets/javascripts/lunr/tinyseg.js new file mode 100644 index 00000000..167fa6dd --- /dev/null +++ b/assets/javascripts/lunr/tinyseg.js @@ -0,0 +1,206 @@ +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + + return function(lunr) { + // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript + // (c) 2008 Taku Kudo + // TinySegmenter is freely distributable under the terms of a new BSD licence. + // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt + + function TinySegmenter() { + var patterns = { + "[一二三四五六七八九十百千万億兆]":"M", + "[一-龠々〆ヵヶ]":"H", + "[ぁ-ん]":"I", + "[ァ-ヴーア-ン゙ー]":"K", + "[a-zA-Za-zA-Z]":"A", + "[0-90-9]":"N" + } + this.chartype_ = []; + for (var i in patterns) { + var regexp = new RegExp(i); + this.chartype_.push([regexp, patterns[i]]); + } + + this.BIAS__ = -332 + this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; + this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; + this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; + this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; + this.BP2__ = {"BO":60,"OO":-1762}; + this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; + this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; + this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; + this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; + this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; + this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; + this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; + this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; + this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; + this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; + this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; + this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; + this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; + this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; + this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; + this.TW1__ = {"につい":-4681,"東京都":2026}; + this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; + this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; + this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; + this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; + this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; + this.UC3__ = {"A":-1370,"I":2311}; + this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; + this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; + this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; + this.UP1__ = {"O":-214}; + this.UP2__ = {"B":69,"O":935}; + this.UP3__ = {"B":189}; + this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; + this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; + this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; + this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; + this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; + this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; + this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; + this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; + this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; + + return this; + } + TinySegmenter.prototype.ctype_ = function(str) { + for (var i in this.chartype_) { + if (str.match(this.chartype_[i][0])) { + return this.chartype_[i][1]; + } + } + return "O"; + } + + TinySegmenter.prototype.ts_ = function(v) { + if (v) { return v; } + return 0; + } + + TinySegmenter.prototype.segment = function(input) { + if (input == null || input == undefined || input == "") { + return []; + } + var result = []; + var seg = ["B3","B2","B1"]; + var ctype = ["O","O","O"]; + var o = input.split(""); + for (i = 0; i < o.length; ++i) { + seg.push(o[i]); + ctype.push(this.ctype_(o[i])) + } + seg.push("E1"); + seg.push("E2"); + seg.push("E3"); + ctype.push("O"); + ctype.push("O"); + ctype.push("O"); + var word = seg[3]; + var p1 = "U"; + var p2 = "U"; + var p3 = "U"; + for (var i = 4; i < seg.length - 3; ++i) { + var score = this.BIAS__; + var w1 = seg[i-3]; + var w2 = seg[i-2]; + var w3 = seg[i-1]; + var w4 = seg[i]; + var w5 = seg[i+1]; + var w6 = seg[i+2]; + var c1 = ctype[i-3]; + var c2 = ctype[i-2]; + var c3 = ctype[i-1]; + var c4 = ctype[i]; + var c5 = ctype[i+1]; + var c6 = ctype[i+2]; + score += this.ts_(this.UP1__[p1]); + score += this.ts_(this.UP2__[p2]); + score += this.ts_(this.UP3__[p3]); + score += this.ts_(this.BP1__[p1 + p2]); + score += this.ts_(this.BP2__[p2 + p3]); + score += this.ts_(this.UW1__[w1]); + score += this.ts_(this.UW2__[w2]); + score += this.ts_(this.UW3__[w3]); + score += this.ts_(this.UW4__[w4]); + score += this.ts_(this.UW5__[w5]); + score += this.ts_(this.UW6__[w6]); + score += this.ts_(this.BW1__[w2 + w3]); + score += this.ts_(this.BW2__[w3 + w4]); + score += this.ts_(this.BW3__[w4 + w5]); + score += this.ts_(this.TW1__[w1 + w2 + w3]); + score += this.ts_(this.TW2__[w2 + w3 + w4]); + score += this.ts_(this.TW3__[w3 + w4 + w5]); + score += this.ts_(this.TW4__[w4 + w5 + w6]); + score += this.ts_(this.UC1__[c1]); + score += this.ts_(this.UC2__[c2]); + score += this.ts_(this.UC3__[c3]); + score += this.ts_(this.UC4__[c4]); + score += this.ts_(this.UC5__[c5]); + score += this.ts_(this.UC6__[c6]); + score += this.ts_(this.BC1__[c2 + c3]); + score += this.ts_(this.BC2__[c3 + c4]); + score += this.ts_(this.BC3__[c4 + c5]); + score += this.ts_(this.TC1__[c1 + c2 + c3]); + score += this.ts_(this.TC2__[c2 + c3 + c4]); + score += this.ts_(this.TC3__[c3 + c4 + c5]); + score += this.ts_(this.TC4__[c4 + c5 + c6]); + // score += this.ts_(this.TC5__[c4 + c5 + c6]); + score += this.ts_(this.UQ1__[p1 + c1]); + score += this.ts_(this.UQ2__[p2 + c2]); + score += this.ts_(this.UQ3__[p3 + c3]); + score += this.ts_(this.BQ1__[p2 + c2 + c3]); + score += this.ts_(this.BQ2__[p2 + c3 + c4]); + score += this.ts_(this.BQ3__[p3 + c2 + c3]); + score += this.ts_(this.BQ4__[p3 + c3 + c4]); + score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); + score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); + score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); + score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); + var p = "O"; + if (score > 0) { + result.push(word); + word = ""; + p = "B"; + } + p1 = p2; + p2 = p3; + p3 = p; + word += seg[i]; + } + result.push(word); + + return result; + } + + lunr.TinySegmenter = TinySegmenter; + }; + +})); \ No newline at end of file diff --git a/assets/javascripts/lunr/wordcut.js b/assets/javascripts/lunr/wordcut.js new file mode 100644 index 00000000..0d898c9e --- /dev/null +++ b/assets/javascripts/lunr/wordcut.js @@ -0,0 +1,6708 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; + }) + this.addWords(words, false) + } + if(finalize){ + this.finalizeDict(); + } + }, + + dictSeek: function (l, r, ch, strOffset, pos) { + var ans = null; + while (l <= r) { + var m = Math.floor((l + r) / 2), + dict_item = this.dict[m], + len = dict_item.length; + if (len <= strOffset) { + l = m + 1; + } else { + var ch_ = dict_item[strOffset]; + if (ch_ < ch) { + l = m + 1; + } else if (ch_ > ch) { + r = m - 1; + } else { + ans = m; + if (pos == LEFT) { + r = m - 1; + } else { + l = m + 1; + } + } + } + } + return ans; + }, + + isFinal: function (acceptor) { + return this.dict[acceptor.l].length == acceptor.strOffset; + }, + + createAcceptor: function () { + return { + l: 0, + r: this.dict.length - 1, + strOffset: 0, + isFinal: false, + dict: this, + transit: function (ch) { + return this.dict.transit(this, ch); + }, + isError: false, + tag: "DICT", + w: 1, + type: "DICT" + }; + }, + + transit: function (acceptor, ch) { + var l = this.dictSeek(acceptor.l, + acceptor.r, + ch, + acceptor.strOffset, + LEFT); + if (l !== null) { + var r = this.dictSeek(l, + acceptor.r, + ch, + acceptor.strOffset, + RIGHT); + acceptor.l = l; + acceptor.r = r; + acceptor.strOffset++; + acceptor.isFinal = this.isFinal(acceptor); + } else { + acceptor.isError = true; + } + return acceptor; + }, + + sortuniq: function(a){ + return a.sort().filter(function(item, pos, arr){ + return !pos || item != arr[pos - 1]; + }) + }, + + flatten: function(a){ + //[[1,2],[3]] -> [1,2,3] + return [].concat.apply([], a); + } +}; +module.exports = WordcutDict; + +}).call(this,"/dist/tmp") +},{"glob":16,"path":22}],3:[function(require,module,exports){ +var WordRule = { + createAcceptor: function(tag) { + if (tag["WORD_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + var lch = ch.toLowerCase(); + if (lch >= "a" && lch <= "z") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "WORD_RULE", + type: "WORD_RULE", + w: 1}; + } +}; + +var NumberRule = { + createAcceptor: function(tag) { + if (tag["NUMBER_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch >= "0" && ch <= "9") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "NUMBER_RULE", + type: "NUMBER_RULE", + w: 1}; + } +}; + +var SpaceRule = { + tag: "SPACE_RULE", + createAcceptor: function(tag) { + + if (tag["SPACE_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || + ch == "\u00A0" || ch=="\u2003"//nbsp and emsp + ) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: SpaceRule.tag, + w: 1, + type: "SPACE_RULE"}; + } +} + +var SingleSymbolRule = { + tag: "SINSYM", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "SINSYM", + w: 1, + type: "SINSYM"}; + } +} + + +var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; + +module.exports = LatinRules; + +},{}],4:[function(require,module,exports){ +var _ = require("underscore") + , WordcutCore = require("./wordcut_core"); +var PathInfoBuilder = { + + /* + buildByPartAcceptors: function(path, acceptors, i) { + var + var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { + + }, []); + + return genInfos; + } + */ + + buildByAcceptors: function(path, finalAcceptors, i) { + var self = this; + var infos = finalAcceptors.map(function(acceptor) { + var p = i - acceptor.strOffset + 1 + , _info = path[p]; + + var info = {p: p, + mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), + w: acceptor.w + _info.w, + unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, + type: acceptor.type}; + + if (acceptor.type == "PART") { + for(var j = p + 1; j <= i; j++) { + path[j].merge = p; + } + info.merge = p; + } + + return info; + }); + return infos.filter(function(info) { return info; }); + }, + + fallback: function(path, leftBoundary, text, i) { + var _info = path[leftBoundary]; + if (text[i].match(/[\u0E48-\u0E4E]/)) { + if (leftBoundary != 0) + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + mw: 0, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; +/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; */ + } else { + return {p: leftBoundary, + mw: _info.mw, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; + } + }, + + build: function(path, finalAcceptors, i, leftBoundary, text) { + var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); + if (basicPathInfos.length > 0) { + return basicPathInfos; + } else { + return [this.fallback(path, leftBoundary, text, i)]; + } + } +}; + +module.exports = function() { + return _.clone(PathInfoBuilder); +} + +},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ +var _ = require("underscore"); + + +var PathSelector = { + selectPath: function(paths) { + var path = paths.reduce(function(selectedPath, path) { + if (selectedPath == null) { + return path; + } else { + if (path.unk < selectedPath.unk) + return path; + if (path.unk == selectedPath.unk) { + if (path.mw < selectedPath.mw) + return path + if (path.mw == selectedPath.mw) { + if (path.w < selectedPath.w) + return path; + } + } + return selectedPath; + } + }, null); + return path; + }, + + createPath: function() { + return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; + } +}; + +module.exports = function() { + return _.clone(PathSelector); +}; + +},{"underscore":25}],6:[function(require,module,exports){ +function isMatch(pat, offset, ch) { + if (pat.length <= offset) + return false; + var _ch = pat[offset]; + return _ch == ch || + (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); +} + +var Rule0 = { + pat: "เหก็ม", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (isMatch(Rule0.pat, this.strOffset,ch)) { + this.isFinal = (this.strOffset + 1 == Rule0.pat.length); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "THAI_RULE", + type: "THAI_RULE", + w: 1}; + } +}; + +var PartRule = { + createAcceptor: function(tag) { + return {strOffset: 0, + patterns: [ + "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" + ], + isFinal: false, + transit: function(ch) { + var offset = this.strOffset; + this.patterns = this.patterns.filter(function(pat) { + return isMatch(pat, offset, ch); + }); + + if (this.patterns.length > 0) { + var len = 1 + offset; + this.isFinal = this.patterns.some(function(pat) { + return pat.length == len; + }); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "PART", + type: "PART", + unk: 1, + w: 1}; + } +}; + +var ThaiRules = [Rule0, PartRule]; + +module.exports = ThaiRules; + +},{}],7:[function(require,module,exports){ +var sys = require("sys") + , WordcutDict = require("./dict") + , WordcutCore = require("./wordcut_core") + , PathInfoBuilder = require("./path_info_builder") + , PathSelector = require("./path_selector") + , Acceptors = require("./acceptors") + , latinRules = require("./latin_rules") + , thaiRules = require("./thai_rules") + , _ = require("underscore"); + + +var Wordcut = Object.create(WordcutCore); +Wordcut.defaultPathInfoBuilder = PathInfoBuilder; +Wordcut.defaultPathSelector = PathSelector; +Wordcut.defaultAcceptors = Acceptors; +Wordcut.defaultLatinRules = latinRules; +Wordcut.defaultThaiRules = thaiRules; +Wordcut.defaultDict = WordcutDict; + + +Wordcut.initNoDict = function(dict_path) { + var self = this; + self.pathInfoBuilder = new self.defaultPathInfoBuilder; + self.pathSelector = new self.defaultPathSelector; + self.acceptors = new self.defaultAcceptors; + self.defaultLatinRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); + self.defaultThaiRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); +}; + +Wordcut.init = function(dict_path, withDefault, additionalWords) { + withDefault = withDefault || false; + this.initNoDict(); + var dict = _.clone(this.defaultDict); + dict.init(dict_path, withDefault, additionalWords); + this.acceptors.creators.push(dict); +}; + +module.exports = Wordcut; + +},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ +var WordcutCore = { + + buildPath: function(text) { + var self = this + , path = self.pathSelector.createPath() + , leftBoundary = 0; + self.acceptors.reset(); + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + self.acceptors.transit(ch); + + var possiblePathInfos = self + .pathInfoBuilder + .build(path, + self.acceptors.getFinalAcceptors(), + i, + leftBoundary, + text); + var selectedPath = self.pathSelector.selectPath(possiblePathInfos) + + path.push(selectedPath); + if (selectedPath.type !== "UNK") { + leftBoundary = i; + } + } + return path; + }, + + pathToRanges: function(path) { + var e = path.length - 1 + , ranges = []; + + while (e > 0) { + var info = path[e] + , s = info.p; + + if (info.merge !== undefined && ranges.length > 0) { + var r = ranges[ranges.length - 1]; + r.s = info.merge; + s = r.s; + } else { + ranges.push({s:s, e:e}); + } + e = s; + } + return ranges.reverse(); + }, + + rangesToText: function(text, ranges, delimiter) { + return ranges.map(function(r) { + return text.substring(r.s, r.e); + }).join(delimiter); + }, + + cut: function(text, delimiter) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + return this + .rangesToText(text, ranges, + (delimiter === undefined ? "|" : delimiter)); + }, + + cutIntoRanges: function(text, noText) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + if (!noText) { + ranges.forEach(function(r) { + r.text = text.substring(r.s, r.e); + }); + } + return ranges; + }, + + cutIntoArray: function(text) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + return ranges.map(function(r) { + return text.substring(r.s, r.e) + }); + } +}; + +module.exports = WordcutCore; + +},{}],9:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":28}],10:[function(require,module,exports){ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + +},{}],11:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + +},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ + +},{}],13:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],15:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ +(function (process){ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + +}).call(this,require('_process')) +},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],20:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":29}],22:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":24}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + +}).call(this,require('_process')) +},{"_process":24}],24:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],25:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],26:[function(require,module,exports){ +arguments[4][19][0].apply(exports,arguments) +},{"dup":19}],27:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],28:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + +},{}]},{},[7])(7) +}); \ No newline at end of file diff --git a/assets/javascripts/workers/search.1e90e0fb.min.js b/assets/javascripts/workers/search.1e90e0fb.min.js new file mode 100644 index 00000000..ff43aedd --- /dev/null +++ b/assets/javascripts/workers/search.1e90e0fb.min.js @@ -0,0 +1,2 @@ +"use strict";(()=>{var xe=Object.create;var G=Object.defineProperty,ve=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,Te=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Y=Object.getOwnPropertySymbols,Ee=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Z=Math.pow,J=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,_=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(Y)for(var r of Y(e))be.call(e,r)&&J(t,r,e[r]);return t},B=(t,e)=>ve(t,Te(e));var Le=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var we=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Qe(e))!X.call(t,i)&&i!==r&&G(t,i,{get:()=>e[i],enumerable:!(n=Se(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?xe(Ee(t)):{},we(e||!t||!t.__esModule?G(r,"default",{value:t,enumerable:!0}):r,t));var W=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var te=Le((K,ee)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var f=t.utils.clone(r)||{};f.position=[a,c],f.index=s.length,s.push(new t.Token(n.slice(a,o),f))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?f+=2:a==u&&(r+=n[c+1]*i[f+1],c+=2,f+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var f=s.str.charAt(0),g=s.str.charAt(1),l;g in s.node.edges?l=s.node.edges[g]:(l=new t.TokenSet,s.node.edges[g]=l),s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:f+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof K=="object"?ee.exports=r():e.lunr=r()}(this,function(){return t})})()});var de=Pe(te());function re(t,e=document){let r=ke(t,e);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${t}" to be present`);return r}function ke(t,e=document){return e.querySelector(t)||void 0}Object.entries||(Object.entries=function(t){let e=[];for(let r of Object.keys(t))e.push([r,t[r]]);return e});Object.values||(Object.values=function(t){let e=[];for(let r of Object.keys(t))e.push(t[r]);return e});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(t,e){typeof t=="object"?(this.scrollLeft=t.left,this.scrollTop=t.top):(this.scrollLeft=t,this.scrollTop=e)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...t){let e=this.parentNode;if(e){t.length===0&&e.removeChild(this);for(let r=t.length-1;r>=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));function ne(t){let e=new Map;for(let r of t){let[n]=r.location.split("#"),i=e.get(n);typeof i=="undefined"?e.set(n,r):(e.set(r.location,r),r.parent=i)}return e}function H(t,e,r){var s;e=new RegExp(e,"g");let n,i=0;do{n=e.exec(t);let o=(s=n==null?void 0:n.index)!=null?s:t.length;if(in?e(r,1,n,n=i):t.charAt(i)===">"&&(t.charAt(n+1)==="/"?--s===0&&e(r++,2,n,i+1):t.charAt(i-1)!=="/"&&s++===0&&e(r,0,n,i+1),n=i+1);i>n&&e(r,1,n,i)}function se(t,e,r,n=!1){return q([t],e,r,n).pop()}function q(t,e,r,n=!1){let i=[0];for(let s=1;s>>2&1023,c=a[0]>>>12;i.push(+(u>c)+i[i.length-1])}return t.map((s,o)=>{let a=0,u=new Map;for(let f of r.sort((g,l)=>g-l)){let g=f&1048575,l=f>>>20;if(i[l]!==o)continue;let m=u.get(l);typeof m=="undefined"&&u.set(l,m=[]),m.push(g)}if(u.size===0)return s;let c=[];for(let[f,g]of u){let l=e[f],m=l[0]>>>12,x=l[l.length-1]>>>12,v=l[l.length-1]>>>2&1023;n&&m>a&&c.push(s.slice(a,m));let d=s.slice(m,x+v);for(let y of g.sort((b,E)=>E-b)){let b=(l[y]>>>12)-m,E=(l[y]>>>2&1023)+b;d=[d.slice(0,b),"",d.slice(b,E),"",d.slice(E)].join("")}if(a=x+v,c.push(d)===2)break}return n&&a{var f;switch(i[f=o+=s]||(i[f]=[]),a){case 0:case 2:i[o].push(u<<12|c-u<<2|a);break;case 1:let g=r[n].slice(u,c);H(g,lunr.tokenizer.separator,(l,m)=>{if(typeof lunr.segmenter!="undefined"){let x=g.slice(l,m);if(/^[MHIK]$/.test(lunr.segmenter.ctype_(x))){let v=lunr.segmenter.segment(x);for(let d=0,y=0;dr){return t.trim().split(/"([^"]+)"/g).map((r,n)=>n&1?r.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):r).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").split(/\s+/g).reduce((r,n)=>{let i=e(n);return[...r,...Array.isArray(i)?i:[i]]},[]).map(r=>/([~^]$)/.test(r)?`${r}1`:r).map(r=>/(^[+-]|[~^]\d+$)/.test(r)?r:`${r}*`).join(" ")}function ue(t){return ae(t,e=>{let r=[],n=new lunr.QueryLexer(e);n.run();for(let{type:i,str:s,start:o,end:a}of n.lexemes)switch(i){case"FIELD":["title","text","tags"].includes(s)||(e=[e.slice(0,a)," ",e.slice(a+1)].join(""));break;case"TERM":H(s,lunr.tokenizer.separator,(...u)=>{r.push([e.slice(0,o),s.slice(...u),e.slice(a)].join(""))})}return r})}function ce(t){let e=new lunr.Query(["title","text","tags"]);new lunr.QueryParser(t,e).parse();for(let n of e.clauses)n.usePipeline=!0,n.term.startsWith("*")&&(n.wildcard=lunr.Query.wildcard.LEADING,n.term=n.term.slice(1)),n.term.endsWith("*")&&(n.wildcard=lunr.Query.wildcard.TRAILING,n.term=n.term.slice(0,-1));return e.clauses}function le(t,e){var i;let r=new Set(t),n={};for(let s=0;s0;){let o=i[--s];for(let u=1;un[o]-u&&(r.add(t.slice(o,o+u)),i[s++]=o+u);let a=o+n[o];n[a]&&ar=>{if(typeof r[e]=="undefined")return;let n=[r.location,e].join(":");return t.set(n,lunr.tokenizer.table=[]),r[e]}}function Re(t,e){let[r,n]=[new Set(t),new Set(e)];return[...new Set([...r].filter(i=>!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){let i=Oe(this.table=new Map);this.map=ne(r),this.options=n,this.index=lunr(function(){this.metadataWhitelist=["position"],this.b(0),e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang)),this.tokenizer=oe,lunr.tokenizer.separator=new RegExp(e.separator),lunr.segmenter="TinySegmenter"in lunr?new lunr.TinySegmenter:void 0;let s=Re(["trimmer","stopWordFilter","stemmer"],e.pipeline);for(let o of e.lang.map(a=>a==="en"?lunr:lunr[a]))for(let a of s)this.pipeline.remove(o[a]),this.searchPipeline.remove(o[a]);this.ref("location");for(let[o,a]of Object.entries(e.fields))this.field(o,B(_({},a),{extractor:i(o)}));for(let o of r)this.add(o,{boost:o.boost})})}search(e){if(e=e.replace(new RegExp("\\p{sc=Han}+","gu"),s=>[...he(s,this.index.invertedIndex)].join("* ")),e=ue(e),!e)return{items:[]};let r=ce(e).filter(s=>s.presence!==lunr.Query.presence.PROHIBITED),n=this.index.search(e).reduce((s,{ref:o,score:a,matchData:u})=>{let c=this.map.get(o);if(typeof c!="undefined"){c=_({},c),c.tags&&(c.tags=[...c.tags]);let f=le(r,Object.keys(u.metadata));for(let l of this.index.fields){if(typeof c[l]=="undefined")continue;let m=[];for(let d of Object.values(u.metadata))typeof d[l]!="undefined"&&m.push(...d[l].position);if(!m.length)continue;let x=this.table.get([c.location,l].join(":")),v=Array.isArray(c[l])?q:se;c[l]=v(c[l],x,m,l!=="text")}let g=+!c.parent+Object.values(f).filter(l=>l).length/Object.keys(f).length;s.push(B(_({},c),{score:a*(1+Z(g,2)),terms:f}))}return s},[]).sort((s,o)=>o.score-s.score).reduce((s,o)=>{let a=this.map.get(o.location);if(typeof a!="undefined"){let u=a.parent?a.parent.location:a.location;s.set(u,[...s.get(u)||[],o])}return s},new Map);for(let[s,o]of n)if(!o.find(a=>a.location===s)){let a=this.map.get(s);o.push(B(_({},a),{score:0,terms:{}}))}let i;if(this.options.suggest){let s=this.index.query(o=>{for(let a of r)o.term(a.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});i=s.length?Object.keys(s[0].matchData.metadata):[]}return _({items:[...n.values()]},typeof i!="undefined"&&{suggest:i})}};var fe;function Ie(t){return W(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=re("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Fe(t){return W(this,null,function*(){switch(t.type){case 0:return yield Ie(t.data.config),fe=new U(t.data),{type:1};case 2:let e=t.data;try{return{type:3,data:fe.search(e)}}catch(r){return console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`),console.warn(r),{type:3,data:{items:[]}}}default:throw new TypeError("Invalid message type")}})}self.lunr=de.default;addEventListener("message",t=>W(void 0,null,function*(){postMessage(yield Fe(t.data))}));})(); diff --git a/assets/stylesheets/main.76d06c94.min.css b/assets/stylesheets/main.76d06c94.min.css new file mode 100644 index 00000000..921eb607 --- /dev/null +++ b/assets/stylesheets/main.76d06c94.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-ellipsis code{word-break:normal}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link[for]:focus code,.md-nav__link[for]:hover code,.md-nav__link[href]:focus code,.md-nav__link[href]:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:1fr;opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav{margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:1fr;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}.md-path:not([hidden]){display:block}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.984375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.234375em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.984375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon{color:var(--md-default-fg-color--light)}[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:#0000}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.984375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>.md-icon{margin-left:.2rem}[dir=rtl] .md-search__options>.md-icon{margin-right:.2rem}.md-search__options>.md-icon{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>.md-icon:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>.md-icon:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.984375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:focus,.md-search-result__link:hover{background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more>summary{cursor:pointer;display:block;outline:none;position:sticky;scroll-snap-align:start;top:0;z-index:1}.md-search-result__more>summary::marker{display:none}.md-search-result__more>summary::-webkit-details-marker{display:none}.md-search-result__more>summary>div{color:var(--md-typeset-a-color);font-size:.64rem;padding:.75em .8rem;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more>summary>div{padding-left:2.2rem}[dir=rtl] .md-search-result__more>summary>div{padding-right:2.2rem}}.md-search-result__more>summary:focus>div,.md-search-result__more>summary:hover>div{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more[open]>summary{background-color:var(--md-default-bg-color)}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.984375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result .md-typeset{color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.6}.md-search-result .md-typeset h1{color:var(--md-default-fg-color);font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}.md-search-result .md-typeset h1 mark{text-decoration:none}.md-search-result .md-typeset h2{color:var(--md-default-fg-color);font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result .md-typeset h2 mark{text-decoration:none}.md-search-result__terms{color:var(--md-default-fg-color);display:block;font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color);text-decoration:underline}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-shadow{opacity:.5}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:xxx;list-style:none}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(xxx);counter-increment:xxx;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=dialog]>.md-tooltip2__inner{font-size:.64rem;overflow:auto;padding:0 .8rem;pointer-events:auto;width:var(--md-tooltip-width)}[role=dialog]>.md-tooltip2__inner:after,[role=dialog]>.md-tooltip2__inner:before{content:"";display:block;height:.8rem;position:sticky;width:100%;z-index:10}[role=dialog]>.md-tooltip2__inner:before{background:linear-gradient(var(--md-default-bg-color),#0000 75%);top:0}[role=dialog]>.md-tooltip2__inner:after{background:linear-gradient(#0000,var(--md-default-bg-color) 75%);bottom:0}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:-webkit-min-content;width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying]{display:block}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/palette.ab4e12ef.min.css b/assets/stylesheets/palette.ab4e12ef.min.css new file mode 100644 index 00000000..75aaf842 --- /dev/null +++ b/assets/stylesheets/palette.ab4e12ef.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,14%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,14%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,14%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,14%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,0.82);--md-code-bg-color:hsla(var(--md-hue),15%,18%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,18%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,18%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:hsla(var(--md-hue),0%,100%,1);--md-primary-fg-color--light:hsla(var(--md-hue),0%,100%,0.7);--md-primary-fg-color--dark:hsla(var(--md-hue),0%,0%,0.07);--md-primary-bg-color:hsla(var(--md-hue),0%,0%,0.87);--md-primary-bg-color--light:hsla(var(--md-hue),0%,0%,0.54);--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:hsla(var(--md-hue),0%,0%,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:hsla(var(--md-hue),0%,0%,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:hsla(var(--md-hue),0%,0%,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:hsla(var(--md-hue),15%,9%,1);--md-primary-fg-color--light:hsla(var(--md-hue),15%,9%,0.54);--md-primary-fg-color--dark:hsla(var(--md-hue),15%,9%,1);--md-primary-bg-color:hsla(var(--md-hue),15%,100%,1);--md-primary-bg-color--light:hsla(var(--md-hue),15%,100%,0.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-primary=black] .md-header{background-color:hsla(var(--md-hue),15%,9%,1)}@media screen and (max-width:59.984375em){[data-md-color-primary=black] .md-nav__source{background-color:hsla(var(--md-hue),15%,11%,.87)}}@media screen and (max-width:76.234375em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:hsla(var(--md-hue),15%,9%,1)}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:hsla(var(--md-hue),15%,9%,1)}} \ No newline at end of file diff --git a/changelogs/index.html b/changelogs/index.html new file mode 100644 index 00000000..7018ee4e --- /dev/null +++ b/changelogs/index.html @@ -0,0 +1,4271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 更新履歴 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + +
+ + + + + + + + +

変更履歴

+

2024/1/27 ver. 13.0.1

+
+ +
+

2024/1/26 ver. 13.0.0

+
+ +
+

2024/1/5 ver. 12.9.5

+
+
    +
  • プール情報(pool.cert)の更新 メタデータファイルにnonce値を追加
    +プール情報更新時においてメタデータURLのみの変更で、同一ファイル(ハッシュ値)を使用した場合、SMASHサーバーのキャッシュ読み込みにおいて参照データの整合性が取れず、KoiosAPIでもデータ参照出来ないためメタデータにnonce値を設定し異なるハッシュ値でチェーンに登録する仕様へ変更。
  • +
+
+

2023/12/30 ver. 12.9.4

+ +

2023/12/20 ver. 12.9.3

+
+
    +
  • 8.1.2用設定ファイルダウンロード元変更
  • +
+
+

2023/11/29 ver. 12.9.2

+
+
    +
  • SJG TOOL v3.6.4リリース
  • +
  • プールIDファイル名変更
    + stakepoolid_hex → pool.id
    + stakepoolid_bech32 → pool.id-bech32
  • +
+
+

2023/11/25 ver. 12.9.1

+
+ +
+

2023/11/20 ver. 12.9.0

+
+
    +
  • R-Login使用時の推奨設定を掲載 Ubuntu初期設定
  • +
  • Tracemempool初期値変更対応
  • +
  • SPOミーティング議事録リンク掲載 SJGラーニング
  • +
  • 軽微な修正
  • +
+
+

2023/10/28 ver. 12.8.9

+
+
    +
  • minPoolCost変更に伴う表記およびコマンド修正
  • +
  • Grafanaアラート設定にKES残日数とディスク容量アラート設定を追加
  • +
  • 軽微な修正
  • +
+
+

2023/09/27 ver. 12.8.8

+
+ +
+

2023/09/19 ver. 12.8.7

+
+ +
+

2023/08/11 ver. 12.8.6

+
+ +
+

2023/07/25 ver. 12.8.5

+
+ +
+

2023/07/18 ver. 12.8.4

+
+
    +
  • SJG TOOL v3.6.0リリース(Catalyst有権者登録機能実装)
  • +
  • Catalyst有権者登録 Catalyst有権者登録を追加
  • +
+
+

2023/07/18 ver. 12.8.3

+
+ +
+

2023/06/27 ver. 12.8.2

+
+ +
+

2023/06/20 ver. 12.8.1

+ +

2023/06/20 ver. 12.8.0

+
+ +
+

2023/05/18 ver. 12.7.1

+
+
    +
  • SJG TOOL v3.5リリース(SPO投票機能実装)
  • +
  • SPO投票メインネット手順追加
  • +
+
+

2023/05/13 ver. 12.7.0

+
+ +
+

2023/05/04 ver. 12.6.3

+
+
    +
  • SPO投票(テストネット)手順追加
  • +
+
+

2023/04/13 ver. 12.6.2

+
+
    +
  • CNCLI 5.3.2 muslビルド対応
  • +
+
+

2023/04/04 ver. 12.6.1

+
+
    +
  • CNCLI 5.3.2対応
  • +
  • P2P設定トポロジーファイルフォーマット追加
  • +
+
+

2023/04/04 ver. 12.6.0

+
+ +
+

2023/03/07 ver. 12.5.1

+
+ +
+

2023/03/07 ver. 12.5.0

+
+
    +
  • Grafanaセキュリティ強化設定追加
  • +
  • Grafanaアラート設定追加
  • +
  • ブロック生成ステーテス通知 v1.8.9 + 通知設定有無検知、起動時通知機能追加
  • +
  • CNCLI5.3.1対応
  • +
  • 軽微な修正
  • +
+
+

2023/02/10 ver. 12.4.8

+
+
    +
  • ブロック生成ステーテス通知 v1.8.6
    + スケジュール取得自動化機能追加
  • +
+
+

2023/02/08 ver. 12.4.7

+
+
    +
  • ブロック生成ステーテス通知 v1.8
    + スケジュール取得自動化機能追加
  • +
+
+

2023/02/04 ver. 12.4.6

+
+
    +
  • CNCLI5.3.0対応
  • +
  • 軽微な修正
  • +
+
+

2023/01/29 ver. 12.4.5

+
+ +
+

2023/01/23 ver. 12.4.4

+
+ +
+

2023/01/05 ver. 12.4.3

+
+ +
+

2022/12/20 ver. 12.4.2

+
+
    +
  • 最新リリース1.35.4ビルド失敗の回避コマンドを追記
  • +
  • 軽微な修正
  • +
+
+

2022/12/03 ver. 12.4.1

+
+
    +
  • 軽微な修正
  • +
+
+

2022/12/02 ver. 12.4.0

+
+ +
+

2022/10/17 ver. 12.3.6

+
+
    +
  • 2. ノードインストール ノード設定ファイルダウンロード元URLを変更
  • +
  • configファイル修正内容コマンド化
  • +
  • リレーノードでもログ出力するよう手順修正
  • +
  • 接続するネットワーク(メインネット/テストネット)を選択可能にするコマンドを追加
  • +
  • 軽微な修正
  • +
+
+

2022/09/10 ver. 12.3.5

+
+ +
+

2022/08/28 ver. 12.3.4

+
+ +
+

2022/08/27 ver. 12.3.3

+
+
    +
  • logMonitor.sh取得先を変更
  • +
+
+

2022/08/27 ver. 12.3.2

+ +

2022/08/25 ver. 12.3.1

+ +

2022/08/25 ver. 12.3.0

+
+ +
+

2022/07/24 ver. 12.2.0

+ +

2022/06/06 ver. 12.1.1

+
+
    +
  • envファイルのCCLI行にRTSフラグを追加
  • +
  • 軽微な修正
  • +
+
+

2022/05/30 ver. 12.1

+
+
    +
  • ノード起動スクリプトコードを修正
    + ノード起動コマンドにガベージコレクション問題に対応したRTSオプションを追加
  • +
+
+

2022/05/10 ver. 12.0

+
+ +
+

2022/04/20 ver. 11.4

+
+ +
+

2022/04/14 ver. 11.3

+
+ +
+

2022/04/07 ver. 11.2

+
+ +
+

2022/03/11 ver. 11.1

+
+ +
+

2022/03/07 ver. 11.0

+
+
    +
  • cardano-node v1.34.1 に対応
  • +
+
+

2022/03/01 ver. 10.0

+
+
    +
  • カルダノステークプール構築手順日本語翻訳を刷新し、「SPO JAPAN GUILD DOCS」として生まれ変わりました!
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/contributors/index.html b/contributors/index.html new file mode 100644 index 00000000..96f4ef3b --- /dev/null +++ b/contributors/index.html @@ -0,0 +1,2740 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 貢献者 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + +
+ + + + + + + + +

SJG貢献者

+

創設・運営者

+BTBF | Pool: [XSP]X-StakePool / [XSP2]X-StakePool
+コミュニティ運営/技術サポート/ツール開発/ドキュメント整備 担当

+

主な貢献者

+

ディスコード内サポート ドキュメント寄稿・修正 技術検証作業などにご協力頂いた皆様です。

+

SAKAKIBARA | Pool: [1JPN] 日本壱プール
+・Akyo | Pool:[AKYO] AKYO🥁
+・SMAN | Pool:[SA8] SMAN8
+・AICHI | Pool:[AICHI] Aichi Stake Pool / [TOKAI] Tokai Stake Pool
+・Nori | Pool:[1STEP] 1STEP
+・SUGAR | Pool:[SUGAR] Sugar Stake Pool
+・MOBC | Pool: [MOBC] MOBC StakePoolServer
+And More...

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/faq/blocklog/index.html b/faq/blocklog/index.html new file mode 100644 index 00000000..dec60730 --- /dev/null +++ b/faq/blocklog/index.html @@ -0,0 +1,3027 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ブロックログ関連 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

ブロックログ関連のよくある質問

+

Q1.スケジュールが取得できません

+
+A.cncliサービスを確認します +

** 1. サービスの起動状態を確認する ** +

tmux a -t cncli
+

+

** 戻り値を確認する **

+
+
+
+

ファイルアップデートを促すメッセージが表示されている

+
+

戻り値

+

Script update(s) detected, do you want to download the latest version? (yes/no):

+
+

yes を入力。ファイルがアップデートされたらEnterを押し、デタッチ[Ctrl+b d]して戻る

+

cncliサービスを再起動する +

sudo systemctl reload-or-restart cnode-cncli-sync.service
+

+

「1. サービスの起動状態を確認する」に戻って再度戻り値を確認する

+
+
+
+

戻り値

+

Looks like cardano-node is running with socket-path as~~

+
+

赤文字で大量にログが表示されている。⇒ノード起動待ち状態
+(デタッチ[Ctrl+B D]して戻る)

+

ノードログを確認する +

journalctl --unit=cardano-node --follow
+

+
+

戻り値

+

Started opening Ledger DB

+
+

この表示が出てくればOK。ログが流れるまで待機

+

ノード同期後、leaderlogサービスを確認する +

tmux a -t leaderlog
+

+
+

戻り値

+

~ CNCLI Leaderlog started ~
+Node in sync, sleeping for 60s before running leaderlogs for current epoch

+
+

この表示が出てくればOK(デタッチ[Ctrl+B D]して戻る)
+スケジュールが計算されるまで数十分かかります。

+
+
+
+

戻り値

+

INFO cardano_ouroboros_network::protocols::~~~ 100.00% synced

+
+

この表示が出てくればOK(デタッチ[Ctrl+B D]して戻る)

+

leaderlogサービスを確認する +

tmux a -t leaderlog
+

+
+

戻り値

+

~ CNCLI Leaderlog started ~
+Node in sync, sleeping for 60s before running leaderlogs for current epoch

+
+

この表示が出てくればOK(デタッチ[Ctrl+B D]して戻る)

+
+
+
+
+

Q2.ブロック生成に失敗しました。原因は何でしょうか?

+
+A.ステータスを確認します +
+
+
+

通称:SlotBattle
+VRF値が小さいほうのブロックが採用されるため運次第となっており解決方法はありません。

+

1エポック = 432000slotのうちブロック生成可能スロットは5%(21600slot)になっておりますが、割り当てられるスケジュールはプール間同士では調整されない仕様になっているため、複数のプールに同一スロットにスケジュールが割り当てられることがあります。

+

しかしブロックチェーンに採用されるブロックは1スロット1ブロックなので、どのプールのブロックを採用するかを決定する際、ブロック生成時にプールがランダムに排出するVRF値が小さい方のブロックを採用する仕様となっております。

+
+
+

原因1:VRF値による判定のため運次第
+通称:HeightBattle
+ブロック伝播の影響を受けています。

+

現在のカルダノブロックチェーンは5秒以内に伝播できればセキュリティ上問題ないとされています。しかしスケーラビリティとのトレードオフで、トランザクション処理速度をあげるためにブロックサイズやスマートコントラクトスクリプトメモリサイズなどを増やしていくとその分伝播速度も遅くなります。

+

このことから、1秒~3秒前後に複数のプールで割り当てられたスケジュールで発生しやすく、分散化の観点からプール間の地理的優位性を無くすためにVRF値による判定で採用ブロックが決定されます。

+

原因2:サーバー時間のズレから発生
+カルダノブロックチェーンはリアルタイム要件が必要なため、サーバー内部時計とインターネット時間(NTPサーバー)が同期している必要があります。 +予定スケジュールで連続して発生している場合は、リレーおよびBPにてChrony設定を確認してください。 +

chronyc tracking
+
+→ 「Leap status」が「Normal」ならOK。「Not synchronized」ならNG

+
+
+

ミスしたスロット番号を用いて、ログを確認します

+
+

55901248をミスしたスロット番号に直してコマンドを実行してください

+
+
cd $NODE_HOME/logs
+cat node*.json | grep 55901248
+
+

該当スロットのログが表示される場合
+ブロック伝播の影響を受けている可能性があります。
+1秒~3秒前後に複数のプールで割り当てられたスケジュールで発生しやすく、自プールのブロック生成予定までに最新ブロックを受け取れない場合があります。 +地理的に分散したリレーノードを配置するか、リレー/BPのmainnet-config.json"MaxConcurrencyDeadline":4,を設定してノードを起動します。

+

該当スロットのログが表示されない場合
+ノードがシャットダウンしていたか、slotsMissedになった可能性があります。
+リレー1台の場合、リレーノードがシャットダウンするとBPでブロック生成することができません。 +かたやリレーノードが稼働していても、BPノードがシャットアウトしていた場合も生成することができません。 +Grafanaなどでノード稼働状態を監視し、シャットダウンした場合にスマホなどへ通知するように設定しましょう。 +missになったスロット番号の、前後のスロット番号20~30ぐらいをログ検索して出てくれば、ノードは動いていた可能性が高いです。

+

slotsMissedとは?
+[gLiveViewに表示されるMissed slot leader checks]
+BPノードは毎秒ごとに自分がスロットリーダーなのかをチェックしていますが、ノードの状態やサーバー負荷によってスロットリーダーチェックに失敗します。 +このタイミングにスケジュールが重なるとブロック生成できません。

+

現在わかっていることは、ノード起動スクリプトにRTSオプションを設定することで軽減できます。また契約サーバーの内部仕様によっても変わってくるようなので +slotsMissedの発生が多い場合は、サーバー乗り換えも検討することをお勧めします。(サーバー内部設定はオペレーター側では変更できません)

+
+
+

KES更新・運用証明書の発行に失敗している可能性があります

+

logmonitorに表示される、base64コードをデコードして原因を探ります。

+

tmux a -t logmonitor
+
+ログモニターに表示される、echo ~ jq -rまでをコピーする
+以下のコードは例です。

+
+

echo eyJ0aHJlYWQiOiIxMzUiLCJzZXYiOiJFcnJvciIsImRhdGEiOnsidmFsIjp7ImtpbmQiOiJUcmFjZUZvcmdlZEludmFsaWRCbG9jayIsInNsb3QiOjQ5MTY1ODc5LCJyZWFzb24iOnsia2luZCI6IlZhbGlkYXRpb25FcnJvciIsImVycm9yIjp7ImtpbmQiOiJIZWFkZXJQcm90b2NvbEVycm9yIiwiZXJyb3IiOnsiZmFpbHVyZXMiOlt7Im9wQ2VydEV4cGVjdGVkS0VTRXZvbHV0aW9ucyI6IjI1Iiwia2luZCI6IkludmFsaWRLZXNTaWduYXR1cmVPQ0VSVCIsIm9wQ2VydEtFU1N0YXJ0UGVyaW9kIjoiMzU0Iiwib3BDZXJ0S0VTQ3VycmVudFBlcmlvZCI6IjM3OSIsImVycm9yIjoiUmVqZWN0In1dLCJraW5kIjoiQ2hhaW5UcmFuc2l0aW9uRXJyb3IifX19fSwiY3JlZGVudGlhbHMiOiJDYXJkYW5vIn0sImxvYyI6bnVsbCwiZW52IjoiMS4zMi4xOjRmNjVmIiwibXNnIjoiIiwiYXBwIjpbXSwiaG9zdCI6ImlwLTE3Mi0yIiwiYXQiOiIyMDIxLTEyLTI4VDIyOjU2OjEwLjQzWiIsIm5zIjpbImNhcmRhbm8ubm9kZS5Gb3JnZSJdLCJwaWQiOiIzODY1MzAifQ== | base64 -d | jq -r

+
+

Ctrl+b dでデタッチして、上記でコピーしたコマンドを実行する。
+"error":"failures":"kind":の値が失敗した理由になっています。 +

{
+    "thread": "135",
+    "sev": "Error",
+    "data": {
+        "val": {
+        "kind": "TraceForgedInvalidBlock",
+        "slot": 49165879,
+        "reason": {
+            "kind": "ValidationError",
+            "error": {
+            "kind": "HeaderProtocolError",
+            "error": {
+                "failures": [
+                {
+                    "opCertExpectedKESEvolutions": "25",
+                    "kind": "InvalidKesSignatureOCERT",
+                    "opCertKESStartPeriod": "354",
+                    "opCertKESCurrentPeriod": "379",
+                    "error": "Reject"
+                }
+                ],
+                "kind": "ChainTransitionError"
+            }
+            }
+        }
+        },
+        "credentials": "Cardano"
+    },
+    "loc": null,
+    "env": "1.32.1:4f65f",
+    "msg": "",
+    "app": [],
+    "host": "ip-172-2",
+    "at": "2021-12-28T22:56:10.43Z",
+    "ns": [
+        "cardano.node.Forge"
+    ],
+    "pid": "386530"
+}
+

+
+
+
+
+

Q3.割り当てられたスケジュールをSNSで公開してもいいですか?

+
+A.NGです +

未来の生成予定スケジュールを公開すると、その時間を狙って悪意のある者から攻撃を受ける可能性があるため、 +予定スケジュールを公開することはカルダノネットワークのセキュリティを損なう重大な問題となります。

+
+

Q4.スケジュール取得時「Error: database is locked」が表示される

+
+A.スケジュールを再取得してください +

tmux a -t leaderlogで取得されたスケジュールを確認すると「Error: database is locked」が表示される時があります。

+

スケジュール取得時のblocklogデータベース書き込みエラーによるもので、スケジュールはあるもののデータベースに格納されません。
+直近1時間以内にブロック生成が無いことを確認し、tmux a -t leaderlogを開き$NODE_HOME/scripts/cncli.sh leaderlog forceコマンドを実行して、スケジュールを再取得してください。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/faq/monitoring/index.html b/faq/monitoring/index.html new file mode 100644 index 00000000..9b3633ff --- /dev/null +++ b/faq/monitoring/index.html @@ -0,0 +1,2773 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + ノード監視関連 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

ノード監視に関するよくある質問

+

Q1.Grafanaのログインパスワードを忘れました

+
+A.ログインに必要な情報を初期化します +

リレー1にて以下を実施します。 +

sudo sqlite3 /var/lib/grafana/grafana.db
+
+
update user set password = '59acf18b94d7eb0694c61e60ce44c110c7a683ac6a8f09580d626f90f4a242000746579358d77dd9e570e83fa24faa88a8a6', salt = 'F3FAxVm33R' where login = 'admin';
+
+
.quit
+
+以下の情報でログインし、パスワードを再設定してください

+

Username:admin
+password:admin

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/faq/node/index.html b/faq/node/index.html new file mode 100644 index 00000000..f037a3ee --- /dev/null +++ b/faq/node/index.html @@ -0,0 +1,2845 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ノード関連 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

ノードに関するよくある質問

+

Q1.ノードが起動・同期しません

+
+A.起動ログを確認してください +

ノード起動ログを確認してエラー表示を確認してください +

journalctl --unit=cardano-node --follow
+

+

「InvalidYaml (Just (YamlParseException」が表示される場合

+
    +
  • mainnet-config.json 構文エラーのためファイル内を見直してください。
    +

    , {} ()などが抜けていたり、多かったりします。

    +
    +
  • +
+

ファイルを修正したらノードを再起動します +

sudo systemctl reload-or-restart cardano-node
+

+

JSON構文チェックツール(ラッコツールズ)

+

「Is your topology file formatted correctly?」 が表示される場合

+
    +
  • mainnet-topology.json 構文エラーのため、トポロジーファイルを見直してください
  • +
+

ファイルを確認したらノードを再起動します +

sudo systemctl reload-or-restart cardano-node
+

+

Progress: xx.xx%の表示がある場合
+前回ノード終了時にメモリ不足などで強制終了したため、DB再チェックが行われています。同期までに約20分以上かかりますのでそのままお待ちください。

+
+

注意

+

ノードが完全同期しないうちにノード起動・再起動コマンドを実行すると、DB再チェックが行われるため同期がさらに遅くなりますのでご注意ください

+
+

BPが同期しない場合
+リレーとの接続を確認してください。

+
    +
  • BPのmainnet-topology.json
  • +
  • BPのファイアウォール設定
  • +
  • リレーのファイアウォール設定
  • +
  • 契約サーバー独自の仕様
  • +
+
+

Q2.ノードが再起動を繰り返します

+
+A.ディスク空き容量を確認してください +

df -h /usr
+
+戻り値のUse%が100%に近いとノードDBを更新する空き容量が足りないため、再起動を繰り返します。契約VPSのサーバースペックを変更してください。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/1.35.3-update.png b/images/1.35.3-update.png new file mode 100644 index 00000000..35fd3155 Binary files /dev/null and b/images/1.35.3-update.png differ diff --git a/images/1.35.3node-syncing.png b/images/1.35.3node-syncing.png new file mode 100644 index 00000000..9b95fd0e Binary files /dev/null and b/images/1.35.3node-syncing.png differ diff --git a/images/1.35.4-update.png b/images/1.35.4-update.png new file mode 100644 index 00000000..45dc312f Binary files /dev/null and b/images/1.35.4-update.png differ diff --git a/images/1.35.5-update.png b/images/1.35.5-update.png new file mode 100644 index 00000000..c115077d Binary files /dev/null and b/images/1.35.5-update.png differ diff --git a/images/8.7.2-update.png b/images/8.7.2-update.png new file mode 100644 index 00000000..3d922814 Binary files /dev/null and b/images/8.7.2-update.png differ diff --git a/images/airgap/airgap0.png b/images/airgap/airgap0.png new file mode 100644 index 00000000..7123e754 Binary files /dev/null and b/images/airgap/airgap0.png differ diff --git a/images/airgap/airgap1.png b/images/airgap/airgap1.png new file mode 100644 index 00000000..3bdf4d28 Binary files /dev/null and b/images/airgap/airgap1.png differ diff --git a/images/airgap/airgap10.png b/images/airgap/airgap10.png new file mode 100644 index 00000000..d339caa6 Binary files /dev/null and b/images/airgap/airgap10.png differ diff --git a/images/airgap/airgap11.png b/images/airgap/airgap11.png new file mode 100644 index 00000000..c95d449e Binary files /dev/null and b/images/airgap/airgap11.png differ diff --git a/images/airgap/airgap12.png b/images/airgap/airgap12.png new file mode 100644 index 00000000..2faea504 Binary files /dev/null and b/images/airgap/airgap12.png differ diff --git a/images/airgap/airgap13.png b/images/airgap/airgap13.png new file mode 100644 index 00000000..e537c11c Binary files /dev/null and b/images/airgap/airgap13.png differ diff --git a/images/airgap/airgap2.png b/images/airgap/airgap2.png new file mode 100644 index 00000000..509fb846 Binary files /dev/null and b/images/airgap/airgap2.png differ diff --git a/images/airgap/airgap3.png b/images/airgap/airgap3.png new file mode 100644 index 00000000..ce6974ed Binary files /dev/null and b/images/airgap/airgap3.png differ diff --git a/images/airgap/airgap4.png b/images/airgap/airgap4.png new file mode 100644 index 00000000..c130cda9 Binary files /dev/null and b/images/airgap/airgap4.png differ diff --git a/images/airgap/airgap5.png b/images/airgap/airgap5.png new file mode 100644 index 00000000..9eddf1a0 Binary files /dev/null and b/images/airgap/airgap5.png differ diff --git a/images/airgap/airgap6.png b/images/airgap/airgap6.png new file mode 100644 index 00000000..d9424bb1 Binary files /dev/null and b/images/airgap/airgap6.png differ diff --git a/images/airgap/airgap7.png b/images/airgap/airgap7.png new file mode 100644 index 00000000..4098adce Binary files /dev/null and b/images/airgap/airgap7.png differ diff --git a/images/airgap/airgap8.png b/images/airgap/airgap8.png new file mode 100644 index 00000000..dcb33698 Binary files /dev/null and b/images/airgap/airgap8.png differ diff --git a/images/airgap/airgap9.png b/images/airgap/airgap9.png new file mode 100644 index 00000000..cdab3b7e Binary files /dev/null and b/images/airgap/airgap9.png differ diff --git a/images/block_notify/2-1-1-1.png b/images/block_notify/2-1-1-1.png new file mode 100644 index 00000000..e863cf1b Binary files /dev/null and b/images/block_notify/2-1-1-1.png differ diff --git a/images/block_notify/2-1-1-2.png b/images/block_notify/2-1-1-2.png new file mode 100644 index 00000000..83c9aba8 Binary files /dev/null and b/images/block_notify/2-1-1-2.png differ diff --git a/images/block_notify/2-1-1-3.png b/images/block_notify/2-1-1-3.png new file mode 100644 index 00000000..2cac529e Binary files /dev/null and b/images/block_notify/2-1-1-3.png differ diff --git a/images/block_notify/2-1-1.jpg b/images/block_notify/2-1-1.jpg new file mode 100644 index 00000000..f93eeb45 Binary files /dev/null and b/images/block_notify/2-1-1.jpg differ diff --git a/images/block_notify/2-1-2.JPG b/images/block_notify/2-1-2.JPG new file mode 100644 index 00000000..0d867a3f Binary files /dev/null and b/images/block_notify/2-1-2.JPG differ diff --git a/images/block_notify/2-1-2.png b/images/block_notify/2-1-2.png new file mode 100644 index 00000000..f2d7d419 Binary files /dev/null and b/images/block_notify/2-1-2.png differ diff --git a/images/block_notify/2-1-3.jpg b/images/block_notify/2-1-3.jpg new file mode 100644 index 00000000..6692457f Binary files /dev/null and b/images/block_notify/2-1-3.jpg differ diff --git a/images/block_notify/3-1-1.jpg b/images/block_notify/3-1-1.jpg new file mode 100644 index 00000000..78b8812a Binary files /dev/null and b/images/block_notify/3-1-1.jpg differ diff --git a/images/block_notify/3-1-2.jpg b/images/block_notify/3-1-2.jpg new file mode 100644 index 00000000..958822a1 Binary files /dev/null and b/images/block_notify/3-1-2.jpg differ diff --git a/images/block_notify/3-1-3.jpg b/images/block_notify/3-1-3.jpg new file mode 100644 index 00000000..0149eec1 Binary files /dev/null and b/images/block_notify/3-1-3.jpg differ diff --git a/images/block_notify/3-1-4.jpg b/images/block_notify/3-1-4.jpg new file mode 100644 index 00000000..d02f5211 Binary files /dev/null and b/images/block_notify/3-1-4.jpg differ diff --git a/images/block_notify/3-1-5.jpg b/images/block_notify/3-1-5.jpg new file mode 100644 index 00000000..0e6fa3d7 Binary files /dev/null and b/images/block_notify/3-1-5.jpg differ diff --git a/images/block_notify/3-1-6.jpg b/images/block_notify/3-1-6.jpg new file mode 100644 index 00000000..ac5897dd Binary files /dev/null and b/images/block_notify/3-1-6.jpg differ diff --git a/images/block_notify/3-1-7.jpg b/images/block_notify/3-1-7.jpg new file mode 100644 index 00000000..e2a2d62c Binary files /dev/null and b/images/block_notify/3-1-7.jpg differ diff --git a/images/block_notify/4-1-1.jpg b/images/block_notify/4-1-1.jpg new file mode 100644 index 00000000..9b99bca2 Binary files /dev/null and b/images/block_notify/4-1-1.jpg differ diff --git a/images/block_notify/4-1-2.jpg b/images/block_notify/4-1-2.jpg new file mode 100644 index 00000000..92ee1e6f Binary files /dev/null and b/images/block_notify/4-1-2.jpg differ diff --git a/images/block_notify/4-1-3.jpg b/images/block_notify/4-1-3.jpg new file mode 100644 index 00000000..b6e8e6cb Binary files /dev/null and b/images/block_notify/4-1-3.jpg differ diff --git a/images/block_notify/4-1-4-1.jpg b/images/block_notify/4-1-4-1.jpg new file mode 100644 index 00000000..58faa438 Binary files /dev/null and b/images/block_notify/4-1-4-1.jpg differ diff --git a/images/block_notify/4-1-4.jpg b/images/block_notify/4-1-4.jpg new file mode 100644 index 00000000..a24672ff Binary files /dev/null and b/images/block_notify/4-1-4.jpg differ diff --git a/images/block_notify/4-1-5.jpg b/images/block_notify/4-1-5.jpg new file mode 100644 index 00000000..e18f65be Binary files /dev/null and b/images/block_notify/4-1-5.jpg differ diff --git a/images/block_notify/4-1-6.jpg b/images/block_notify/4-1-6.jpg new file mode 100644 index 00000000..5d29ef58 Binary files /dev/null and b/images/block_notify/4-1-6.jpg differ diff --git a/images/block_notify/4-1-7.jpg b/images/block_notify/4-1-7.jpg new file mode 100644 index 00000000..19c2ee9a Binary files /dev/null and b/images/block_notify/4-1-7.jpg differ diff --git a/images/block_notify/5-1-1.jpg b/images/block_notify/5-1-1.jpg new file mode 100644 index 00000000..382db7dc Binary files /dev/null and b/images/block_notify/5-1-1.jpg differ diff --git a/images/block_notify/5-1-2.jpg b/images/block_notify/5-1-2.jpg new file mode 100644 index 00000000..422ef540 Binary files /dev/null and b/images/block_notify/5-1-2.jpg differ diff --git a/images/block_notify/5-1-3.jpg b/images/block_notify/5-1-3.jpg new file mode 100644 index 00000000..99d9894a Binary files /dev/null and b/images/block_notify/5-1-3.jpg differ diff --git a/images/block_notify/auto_leader.png b/images/block_notify/auto_leader.png new file mode 100644 index 00000000..3f606cec Binary files /dev/null and b/images/block_notify/auto_leader.png differ diff --git a/images/block_notify/image.png b/images/block_notify/image.png new file mode 100644 index 00000000..71615f31 Binary files /dev/null and b/images/block_notify/image.png differ diff --git a/images/blocklog.JPG b/images/blocklog.JPG new file mode 100644 index 00000000..5ec1787e Binary files /dev/null and b/images/blocklog.JPG differ diff --git a/images/blocks1.JPG b/images/blocks1.JPG new file mode 100644 index 00000000..3d568446 Binary files /dev/null and b/images/blocks1.JPG differ diff --git a/images/catalyst_vote/catalyst1.jpg b/images/catalyst_vote/catalyst1.jpg new file mode 100644 index 00000000..9d56a629 Binary files /dev/null and b/images/catalyst_vote/catalyst1.jpg differ diff --git a/images/favicon.png b/images/favicon.png new file mode 100644 index 00000000..3370cf9a Binary files /dev/null and b/images/favicon.png differ diff --git a/images/git1.png b/images/git1.png new file mode 100644 index 00000000..5f87d193 Binary files /dev/null and b/images/git1.png differ diff --git a/images/git2.png b/images/git2.png new file mode 100644 index 00000000..857c8925 Binary files /dev/null and b/images/git2.png differ diff --git a/images/git3.png b/images/git3.png new file mode 100644 index 00000000..037faaad Binary files /dev/null and b/images/git3.png differ diff --git a/images/github-pages/github-page0.png b/images/github-pages/github-page0.png new file mode 100644 index 00000000..0cc48f14 Binary files /dev/null and b/images/github-pages/github-page0.png differ diff --git a/images/github-pages/github-page1.png b/images/github-pages/github-page1.png new file mode 100644 index 00000000..d5adbc0d Binary files /dev/null and b/images/github-pages/github-page1.png differ diff --git a/images/github-pages/github-page2.png b/images/github-pages/github-page2.png new file mode 100644 index 00000000..79172714 Binary files /dev/null and b/images/github-pages/github-page2.png differ diff --git a/images/github-pages/github-page3.png b/images/github-pages/github-page3.png new file mode 100644 index 00000000..010e99a2 Binary files /dev/null and b/images/github-pages/github-page3.png differ diff --git a/images/github-pages/github-page4.png b/images/github-pages/github-page4.png new file mode 100644 index 00000000..f065035c Binary files /dev/null and b/images/github-pages/github-page4.png differ diff --git a/images/github-pages/github-page5.png b/images/github-pages/github-page5.png new file mode 100644 index 00000000..976cde99 Binary files /dev/null and b/images/github-pages/github-page5.png differ diff --git a/images/github-pages/github-page6.png b/images/github-pages/github-page6.png new file mode 100644 index 00000000..80ea3c29 Binary files /dev/null and b/images/github-pages/github-page6.png differ diff --git a/images/glive-p2p-1.png b/images/glive-p2p-1.png new file mode 100644 index 00000000..e21b2482 Binary files /dev/null and b/images/glive-p2p-1.png differ diff --git a/images/glive-p2p-2.png b/images/glive-p2p-2.png new file mode 100644 index 00000000..4260b3ee Binary files /dev/null and b/images/glive-p2p-2.png differ diff --git a/images/glive-tx.png b/images/glive-tx.png new file mode 100644 index 00000000..a6177c30 Binary files /dev/null and b/images/glive-tx.png differ diff --git a/images/glive.PNG b/images/glive.PNG new file mode 100644 index 00000000..5950deba Binary files /dev/null and b/images/glive.PNG differ diff --git a/images/grafana-alert/1-0.png b/images/grafana-alert/1-0.png new file mode 100644 index 00000000..fba77d8a Binary files /dev/null and b/images/grafana-alert/1-0.png differ diff --git a/images/grafana-alert/1-1.png b/images/grafana-alert/1-1.png new file mode 100644 index 00000000..743f3ef9 Binary files /dev/null and b/images/grafana-alert/1-1.png differ diff --git a/images/grafana-alert/1-10.png b/images/grafana-alert/1-10.png new file mode 100644 index 00000000..555a8852 Binary files /dev/null and b/images/grafana-alert/1-10.png differ diff --git a/images/grafana-alert/1-11.png b/images/grafana-alert/1-11.png new file mode 100644 index 00000000..60a9f144 Binary files /dev/null and b/images/grafana-alert/1-11.png differ diff --git a/images/grafana-alert/1-2.png b/images/grafana-alert/1-2.png new file mode 100644 index 00000000..566afae3 Binary files /dev/null and b/images/grafana-alert/1-2.png differ diff --git a/images/grafana-alert/1-3.png b/images/grafana-alert/1-3.png new file mode 100644 index 00000000..6056f77e Binary files /dev/null and b/images/grafana-alert/1-3.png differ diff --git a/images/grafana-alert/1-4.png b/images/grafana-alert/1-4.png new file mode 100644 index 00000000..9ec002a3 Binary files /dev/null and b/images/grafana-alert/1-4.png differ diff --git a/images/grafana-alert/1-5.png b/images/grafana-alert/1-5.png new file mode 100644 index 00000000..284ad681 Binary files /dev/null and b/images/grafana-alert/1-5.png differ diff --git a/images/grafana-alert/1-6.png b/images/grafana-alert/1-6.png new file mode 100644 index 00000000..0f501161 Binary files /dev/null and b/images/grafana-alert/1-6.png differ diff --git a/images/grafana-alert/1-7.png b/images/grafana-alert/1-7.png new file mode 100644 index 00000000..4406755d Binary files /dev/null and b/images/grafana-alert/1-7.png differ diff --git a/images/grafana-alert/1-8.png b/images/grafana-alert/1-8.png new file mode 100644 index 00000000..6b9ad712 Binary files /dev/null and b/images/grafana-alert/1-8.png differ diff --git a/images/grafana-alert/1-9.png b/images/grafana-alert/1-9.png new file mode 100644 index 00000000..921dba50 Binary files /dev/null and b/images/grafana-alert/1-9.png differ diff --git a/images/grafana-dashboard-sample.png b/images/grafana-dashboard-sample.png new file mode 100644 index 00000000..07da83d7 Binary files /dev/null and b/images/grafana-dashboard-sample.png differ diff --git a/images/grafana-security/1-1.png b/images/grafana-security/1-1.png new file mode 100644 index 00000000..bfff1210 Binary files /dev/null and b/images/grafana-security/1-1.png differ diff --git a/images/grafana-security/1-10.png b/images/grafana-security/1-10.png new file mode 100644 index 00000000..4b4699c4 Binary files /dev/null and b/images/grafana-security/1-10.png differ diff --git a/images/grafana-security/1-11.png b/images/grafana-security/1-11.png new file mode 100644 index 00000000..e42bc42a Binary files /dev/null and b/images/grafana-security/1-11.png differ diff --git a/images/grafana-security/1-12.png b/images/grafana-security/1-12.png new file mode 100644 index 00000000..074d69e5 Binary files /dev/null and b/images/grafana-security/1-12.png differ diff --git a/images/grafana-security/1-13.png b/images/grafana-security/1-13.png new file mode 100644 index 00000000..89fceb44 Binary files /dev/null and b/images/grafana-security/1-13.png differ diff --git a/images/grafana-security/1-14.png b/images/grafana-security/1-14.png new file mode 100644 index 00000000..96f5cd8e Binary files /dev/null and b/images/grafana-security/1-14.png differ diff --git a/images/grafana-security/1-2.png b/images/grafana-security/1-2.png new file mode 100644 index 00000000..4ce05f97 Binary files /dev/null and b/images/grafana-security/1-2.png differ diff --git a/images/grafana-security/1-3.png b/images/grafana-security/1-3.png new file mode 100644 index 00000000..53081c3f Binary files /dev/null and b/images/grafana-security/1-3.png differ diff --git a/images/grafana-security/1-4.png b/images/grafana-security/1-4.png new file mode 100644 index 00000000..3e5367ae Binary files /dev/null and b/images/grafana-security/1-4.png differ diff --git a/images/grafana-security/1-5.png b/images/grafana-security/1-5.png new file mode 100644 index 00000000..5f16a7a9 Binary files /dev/null and b/images/grafana-security/1-5.png differ diff --git a/images/grafana-security/1-6.png b/images/grafana-security/1-6.png new file mode 100644 index 00000000..c82ad4bb Binary files /dev/null and b/images/grafana-security/1-6.png differ diff --git a/images/grafana-security/1-7.png b/images/grafana-security/1-7.png new file mode 100644 index 00000000..377d034f Binary files /dev/null and b/images/grafana-security/1-7.png differ diff --git a/images/grafana-security/1-8.png b/images/grafana-security/1-8.png new file mode 100644 index 00000000..c914d53a Binary files /dev/null and b/images/grafana-security/1-8.png differ diff --git a/images/grafana-security/1-9.png b/images/grafana-security/1-9.png new file mode 100644 index 00000000..65a15469 Binary files /dev/null and b/images/grafana-security/1-9.png differ diff --git a/images/handle.png b/images/handle.png new file mode 100644 index 00000000..4bd1b52a Binary files /dev/null and b/images/handle.png differ diff --git a/images/logo-white.png b/images/logo-white.png new file mode 100644 index 00000000..90191558 Binary files /dev/null and b/images/logo-white.png differ diff --git a/images/mac/159128589-0b0373ac-a342-45d6-b22c-0f14122a5f3d.png b/images/mac/159128589-0b0373ac-a342-45d6-b22c-0f14122a5f3d.png new file mode 100644 index 00000000..b2d6d5ac Binary files /dev/null and b/images/mac/159128589-0b0373ac-a342-45d6-b22c-0f14122a5f3d.png differ diff --git a/images/mac/159128650-7cbc6a86-5fce-465b-b980-95d3f17f7e3e.png b/images/mac/159128650-7cbc6a86-5fce-465b-b980-95d3f17f7e3e.png new file mode 100644 index 00000000..67de5961 Binary files /dev/null and b/images/mac/159128650-7cbc6a86-5fce-465b-b980-95d3f17f7e3e.png differ diff --git a/images/mac/159128953-10f8e1d9-cd04-401e-905c-3b27cbdf89e6.png b/images/mac/159128953-10f8e1d9-cd04-401e-905c-3b27cbdf89e6.png new file mode 100644 index 00000000..0b7f324e Binary files /dev/null and b/images/mac/159128953-10f8e1d9-cd04-401e-905c-3b27cbdf89e6.png differ diff --git a/images/mac/159129325-84554dfb-4062-4c90-ab26-baa3422c2fd5.png b/images/mac/159129325-84554dfb-4062-4c90-ab26-baa3422c2fd5.png new file mode 100644 index 00000000..98567795 Binary files /dev/null and b/images/mac/159129325-84554dfb-4062-4c90-ab26-baa3422c2fd5.png differ diff --git a/images/mac/159153823-eb6c79b5-a6d8-46e8-9ae9-a392ed33de8e.png b/images/mac/159153823-eb6c79b5-a6d8-46e8-9ae9-a392ed33de8e.png new file mode 100644 index 00000000..2e4edf3e Binary files /dev/null and b/images/mac/159153823-eb6c79b5-a6d8-46e8-9ae9-a392ed33de8e.png differ diff --git a/images/mac/199987719-48886644-846b-4748-95a7-65d6d12cf08c.png b/images/mac/199987719-48886644-846b-4748-95a7-65d6d12cf08c.png new file mode 100644 index 00000000..981ef800 Binary files /dev/null and b/images/mac/199987719-48886644-846b-4748-95a7-65d6d12cf08c.png differ diff --git a/images/mac/199995540-8812988e-ae05-4f52-b40c-b1ac255cd6ef.png b/images/mac/199995540-8812988e-ae05-4f52-b40c-b1ac255cd6ef.png new file mode 100644 index 00000000..b28386d7 Binary files /dev/null and b/images/mac/199995540-8812988e-ae05-4f52-b40c-b1ac255cd6ef.png differ diff --git a/images/mac/200000228-a7333064-a9a7-43dd-bc24-91292d2af32a.png b/images/mac/200000228-a7333064-a9a7-43dd-bc24-91292d2af32a.png new file mode 100644 index 00000000..4a29b3e0 Binary files /dev/null and b/images/mac/200000228-a7333064-a9a7-43dd-bc24-91292d2af32a.png differ diff --git a/images/mac/200001693-d02d64e2-a17c-4a35-ab42-3239b6e85ade.png b/images/mac/200001693-d02d64e2-a17c-4a35-ab42-3239b6e85ade.png new file mode 100644 index 00000000..cbdf076f Binary files /dev/null and b/images/mac/200001693-d02d64e2-a17c-4a35-ab42-3239b6e85ade.png differ diff --git a/images/mac/200004570-a7831dd0-971a-4a85-b442-386e9510321f.png b/images/mac/200004570-a7831dd0-971a-4a85-b442-386e9510321f.png new file mode 100644 index 00000000..b17368bf Binary files /dev/null and b/images/mac/200004570-a7831dd0-971a-4a85-b442-386e9510321f.png differ diff --git a/images/mac/200007711-1919c2b1-ca3a-4710-8f95-09506a444881.png b/images/mac/200007711-1919c2b1-ca3a-4710-8f95-09506a444881.png new file mode 100644 index 00000000..7c6b4c2e Binary files /dev/null and b/images/mac/200007711-1919c2b1-ca3a-4710-8f95-09506a444881.png differ diff --git a/images/mac/200102482-958c0ece-9c96-40e7-854c-84eeb172fe39.png b/images/mac/200102482-958c0ece-9c96-40e7-854c-84eeb172fe39.png new file mode 100644 index 00000000..0b981899 Binary files /dev/null and b/images/mac/200102482-958c0ece-9c96-40e7-854c-84eeb172fe39.png differ diff --git a/images/mac/200104121-58558676-f637-494d-897c-f5c6f7e2f905.png b/images/mac/200104121-58558676-f637-494d-897c-f5c6f7e2f905.png new file mode 100644 index 00000000..2762def9 Binary files /dev/null and b/images/mac/200104121-58558676-f637-494d-897c-f5c6f7e2f905.png differ diff --git a/images/mac/200104321-b1805130-d1b9-4e7e-9883-ef9ca583b41c.png b/images/mac/200104321-b1805130-d1b9-4e7e-9883-ef9ca583b41c.png new file mode 100644 index 00000000..9419dcb9 Binary files /dev/null and b/images/mac/200104321-b1805130-d1b9-4e7e-9883-ef9ca583b41c.png differ diff --git a/images/mac/200105091-1ab57c12-26b9-4f1e-92fd-e989ae76a3e1.png b/images/mac/200105091-1ab57c12-26b9-4f1e-92fd-e989ae76a3e1.png new file mode 100644 index 00000000..decc918b Binary files /dev/null and b/images/mac/200105091-1ab57c12-26b9-4f1e-92fd-e989ae76a3e1.png differ diff --git a/images/mac/200105774-017a584c-24ca-471b-8ce3-2c6bce299301.png b/images/mac/200105774-017a584c-24ca-471b-8ce3-2c6bce299301.png new file mode 100644 index 00000000..6af10a42 Binary files /dev/null and b/images/mac/200105774-017a584c-24ca-471b-8ce3-2c6bce299301.png differ diff --git a/images/mac/200107225-fab3855e-ffe1-4291-9337-2d2dd908ba18.png b/images/mac/200107225-fab3855e-ffe1-4291-9337-2d2dd908ba18.png new file mode 100644 index 00000000..8b770805 Binary files /dev/null and b/images/mac/200107225-fab3855e-ffe1-4291-9337-2d2dd908ba18.png differ diff --git a/images/mac/200107672-1be7368a-aa1f-4590-9a36-cf3ad914aa04.png b/images/mac/200107672-1be7368a-aa1f-4590-9a36-cf3ad914aa04.png new file mode 100644 index 00000000..e1430b4e Binary files /dev/null and b/images/mac/200107672-1be7368a-aa1f-4590-9a36-cf3ad914aa04.png differ diff --git a/images/mac/200108019-76aad33a-f170-4538-94fc-e7aabafeb8d8.png b/images/mac/200108019-76aad33a-f170-4538-94fc-e7aabafeb8d8.png new file mode 100644 index 00000000..77ebb701 Binary files /dev/null and b/images/mac/200108019-76aad33a-f170-4538-94fc-e7aabafeb8d8.png differ diff --git a/images/mac/200108172-78dbeb3e-3c06-4c51-84e6-e9ea906f80e1.png b/images/mac/200108172-78dbeb3e-3c06-4c51-84e6-e9ea906f80e1.png new file mode 100644 index 00000000..2ab67a49 Binary files /dev/null and b/images/mac/200108172-78dbeb3e-3c06-4c51-84e6-e9ea906f80e1.png differ diff --git a/images/mac/200108232-edb1f8e4-ae79-4c8b-8245-df9349df33ca.png b/images/mac/200108232-edb1f8e4-ae79-4c8b-8245-df9349df33ca.png new file mode 100644 index 00000000..89e3a05f Binary files /dev/null and b/images/mac/200108232-edb1f8e4-ae79-4c8b-8245-df9349df33ca.png differ diff --git a/images/mac/200108403-e4ce931d-4fac-43da-aca3-5bbadc4947b3.png b/images/mac/200108403-e4ce931d-4fac-43da-aca3-5bbadc4947b3.png new file mode 100644 index 00000000..f6b04ef4 Binary files /dev/null and b/images/mac/200108403-e4ce931d-4fac-43da-aca3-5bbadc4947b3.png differ diff --git a/images/mac/200108468-8109b5b6-1b2e-407e-936d-19703d0f7525.png b/images/mac/200108468-8109b5b6-1b2e-407e-936d-19703d0f7525.png new file mode 100644 index 00000000..c61df1f1 Binary files /dev/null and b/images/mac/200108468-8109b5b6-1b2e-407e-936d-19703d0f7525.png differ diff --git a/images/mac/200108519-0226b6db-95b1-48c0-9bed-b9f746c3c310.png b/images/mac/200108519-0226b6db-95b1-48c0-9bed-b9f746c3c310.png new file mode 100644 index 00000000..b1aa1231 Binary files /dev/null and b/images/mac/200108519-0226b6db-95b1-48c0-9bed-b9f746c3c310.png differ diff --git a/images/mac/200109416-73ade24b-33bf-4a74-aa6a-2f032254f8cd.png b/images/mac/200109416-73ade24b-33bf-4a74-aa6a-2f032254f8cd.png new file mode 100644 index 00000000..cfab2ad5 Binary files /dev/null and b/images/mac/200109416-73ade24b-33bf-4a74-aa6a-2f032254f8cd.png differ diff --git a/images/mac/200109672-4e4d6dde-23d9-408d-96ff-a9ab28c2039f.png b/images/mac/200109672-4e4d6dde-23d9-408d-96ff-a9ab28c2039f.png new file mode 100644 index 00000000..06daadce Binary files /dev/null and b/images/mac/200109672-4e4d6dde-23d9-408d-96ff-a9ab28c2039f.png differ diff --git a/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f (1).png b/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f (1).png new file mode 100644 index 00000000..e2e1661c Binary files /dev/null and b/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f (1).png differ diff --git a/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f.png b/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f.png new file mode 100644 index 00000000..e2e1661c Binary files /dev/null and b/images/mac/200110310-c3f060e1-0184-4aa5-8bfd-7d7fea5eef3f.png differ diff --git a/images/mac/200110479-30bdd7ea-88b4-41f2-8642-b6653e45762a.png b/images/mac/200110479-30bdd7ea-88b4-41f2-8642-b6653e45762a.png new file mode 100644 index 00000000..98431e16 Binary files /dev/null and b/images/mac/200110479-30bdd7ea-88b4-41f2-8642-b6653e45762a.png differ diff --git a/images/mac/200163806-ebee3d0f-5caa-4b54-b07c-6569e9b8059f.png b/images/mac/200163806-ebee3d0f-5caa-4b54-b07c-6569e9b8059f.png new file mode 100644 index 00000000..59fa2c85 Binary files /dev/null and b/images/mac/200163806-ebee3d0f-5caa-4b54-b07c-6569e9b8059f.png differ diff --git a/images/mac/203983361-de583135-1f98-4578-819e-98ceef0ba661.png b/images/mac/203983361-de583135-1f98-4578-819e-98ceef0ba661.png new file mode 100644 index 00000000..0af0f539 Binary files /dev/null and b/images/mac/203983361-de583135-1f98-4578-819e-98ceef0ba661.png differ diff --git a/images/mac/203985883-cd707677-fdf5-44a5-9571-1f32197d7292.png b/images/mac/203985883-cd707677-fdf5-44a5-9571-1f32197d7292.png new file mode 100644 index 00000000..4663d928 Binary files /dev/null and b/images/mac/203985883-cd707677-fdf5-44a5-9571-1f32197d7292.png differ diff --git a/images/mac/203997822-2d823615-395b-49e4-be07-aa36fa2153a3.png b/images/mac/203997822-2d823615-395b-49e4-be07-aa36fa2153a3.png new file mode 100644 index 00000000..498b0077 Binary files /dev/null and b/images/mac/203997822-2d823615-395b-49e4-be07-aa36fa2153a3.png differ diff --git a/images/mac/204000214-49e1af9b-780f-4cea-a90d-6dfc33c00f75.png b/images/mac/204000214-49e1af9b-780f-4cea-a90d-6dfc33c00f75.png new file mode 100644 index 00000000..71630f39 Binary files /dev/null and b/images/mac/204000214-49e1af9b-780f-4cea-a90d-6dfc33c00f75.png differ diff --git a/images/ogp-image.png b/images/ogp-image.png new file mode 100644 index 00000000..c8aebab4 Binary files /dev/null and b/images/ogp-image.png differ diff --git a/images/producer-relay-diagram.png b/images/producer-relay-diagram.png new file mode 100644 index 00000000..0cb8072e Binary files /dev/null and b/images/producer-relay-diagram.png differ diff --git a/images/r-login-setting.jpg b/images/r-login-setting.jpg new file mode 100644 index 00000000..7cb82ae2 Binary files /dev/null and b/images/r-login-setting.jpg differ diff --git a/images/sjg-docs-card.png b/images/sjg-docs-card.png new file mode 100644 index 00000000..f545f24e Binary files /dev/null and b/images/sjg-docs-card.png differ diff --git a/images/sjg-tool-start.png b/images/sjg-tool-start.png new file mode 100644 index 00000000..91326bd4 Binary files /dev/null and b/images/sjg-tool-start.png differ diff --git a/images/top_illust.png b/images/top_illust.png new file mode 100644 index 00000000..630ecc58 Binary files /dev/null and b/images/top_illust.png differ diff --git a/images/ubuntu22-chrony.png b/images/ubuntu22-chrony.png new file mode 100644 index 00000000..6cfb7dea Binary files /dev/null and b/images/ubuntu22-chrony.png differ diff --git a/images/ubuntu22-libc6.png b/images/ubuntu22-libc6.png new file mode 100644 index 00000000..8c3bba56 Binary files /dev/null and b/images/ubuntu22-libc6.png differ diff --git a/images/win/VirtualBoxubuntu-1.jpg b/images/win/VirtualBoxubuntu-1.jpg new file mode 100644 index 00000000..b41d2f22 Binary files /dev/null and b/images/win/VirtualBoxubuntu-1.jpg differ diff --git a/images/win/VirtualBoxubuntu-10.jpg b/images/win/VirtualBoxubuntu-10.jpg new file mode 100644 index 00000000..0ee44710 Binary files /dev/null and b/images/win/VirtualBoxubuntu-10.jpg differ diff --git a/images/win/VirtualBoxubuntu-11.jpg b/images/win/VirtualBoxubuntu-11.jpg new file mode 100644 index 00000000..e514926c Binary files /dev/null and b/images/win/VirtualBoxubuntu-11.jpg differ diff --git a/images/win/VirtualBoxubuntu-12.jpg b/images/win/VirtualBoxubuntu-12.jpg new file mode 100644 index 00000000..8b3cd4a9 Binary files /dev/null and b/images/win/VirtualBoxubuntu-12.jpg differ diff --git a/images/win/VirtualBoxubuntu-13.jpg b/images/win/VirtualBoxubuntu-13.jpg new file mode 100644 index 00000000..61fee82a Binary files /dev/null and b/images/win/VirtualBoxubuntu-13.jpg differ diff --git a/images/win/VirtualBoxubuntu-14.jpg b/images/win/VirtualBoxubuntu-14.jpg new file mode 100644 index 00000000..0778b11e Binary files /dev/null and b/images/win/VirtualBoxubuntu-14.jpg differ diff --git a/images/win/VirtualBoxubuntu-15.jpg b/images/win/VirtualBoxubuntu-15.jpg new file mode 100644 index 00000000..b4924b4f Binary files /dev/null and b/images/win/VirtualBoxubuntu-15.jpg differ diff --git a/images/win/VirtualBoxubuntu-16.jpg b/images/win/VirtualBoxubuntu-16.jpg new file mode 100644 index 00000000..e3315827 Binary files /dev/null and b/images/win/VirtualBoxubuntu-16.jpg differ diff --git a/images/win/VirtualBoxubuntu-17.jpg b/images/win/VirtualBoxubuntu-17.jpg new file mode 100644 index 00000000..1d198995 Binary files /dev/null and b/images/win/VirtualBoxubuntu-17.jpg differ diff --git a/images/win/VirtualBoxubuntu-18.jpg b/images/win/VirtualBoxubuntu-18.jpg new file mode 100644 index 00000000..f758f62c Binary files /dev/null and b/images/win/VirtualBoxubuntu-18.jpg differ diff --git a/images/win/VirtualBoxubuntu-19.jpg b/images/win/VirtualBoxubuntu-19.jpg new file mode 100644 index 00000000..774c2723 Binary files /dev/null and b/images/win/VirtualBoxubuntu-19.jpg differ diff --git a/images/win/VirtualBoxubuntu-2.jpg b/images/win/VirtualBoxubuntu-2.jpg new file mode 100644 index 00000000..f4d07b2a Binary files /dev/null and b/images/win/VirtualBoxubuntu-2.jpg differ diff --git a/images/win/VirtualBoxubuntu-20.jpg b/images/win/VirtualBoxubuntu-20.jpg new file mode 100644 index 00000000..ad051c49 Binary files /dev/null and b/images/win/VirtualBoxubuntu-20.jpg differ diff --git a/images/win/VirtualBoxubuntu-21.jpg b/images/win/VirtualBoxubuntu-21.jpg new file mode 100644 index 00000000..94a955e8 Binary files /dev/null and b/images/win/VirtualBoxubuntu-21.jpg differ diff --git a/images/win/VirtualBoxubuntu-22.jpg b/images/win/VirtualBoxubuntu-22.jpg new file mode 100644 index 00000000..11518c8c Binary files /dev/null and b/images/win/VirtualBoxubuntu-22.jpg differ diff --git a/images/win/VirtualBoxubuntu-23.jpg b/images/win/VirtualBoxubuntu-23.jpg new file mode 100644 index 00000000..70977f7e Binary files /dev/null and b/images/win/VirtualBoxubuntu-23.jpg differ diff --git a/images/win/VirtualBoxubuntu-24.jpg b/images/win/VirtualBoxubuntu-24.jpg new file mode 100644 index 00000000..32fbc91b Binary files /dev/null and b/images/win/VirtualBoxubuntu-24.jpg differ diff --git a/images/win/VirtualBoxubuntu-25.jpg b/images/win/VirtualBoxubuntu-25.jpg new file mode 100644 index 00000000..1b114039 Binary files /dev/null and b/images/win/VirtualBoxubuntu-25.jpg differ diff --git a/images/win/VirtualBoxubuntu-26.jpg b/images/win/VirtualBoxubuntu-26.jpg new file mode 100644 index 00000000..d74c2187 Binary files /dev/null and b/images/win/VirtualBoxubuntu-26.jpg differ diff --git a/images/win/VirtualBoxubuntu-27.jpg b/images/win/VirtualBoxubuntu-27.jpg new file mode 100644 index 00000000..318500aa Binary files /dev/null and b/images/win/VirtualBoxubuntu-27.jpg differ diff --git a/images/win/VirtualBoxubuntu-28.jpg b/images/win/VirtualBoxubuntu-28.jpg new file mode 100644 index 00000000..1b0b9a34 Binary files /dev/null and b/images/win/VirtualBoxubuntu-28.jpg differ diff --git a/images/win/VirtualBoxubuntu-29.jpg b/images/win/VirtualBoxubuntu-29.jpg new file mode 100644 index 00000000..c079d7af Binary files /dev/null and b/images/win/VirtualBoxubuntu-29.jpg differ diff --git a/images/win/VirtualBoxubuntu-3.jpg b/images/win/VirtualBoxubuntu-3.jpg new file mode 100644 index 00000000..5f49dc6a Binary files /dev/null and b/images/win/VirtualBoxubuntu-3.jpg differ diff --git a/images/win/VirtualBoxubuntu-30.jpg b/images/win/VirtualBoxubuntu-30.jpg new file mode 100644 index 00000000..0349d42e Binary files /dev/null and b/images/win/VirtualBoxubuntu-30.jpg differ diff --git a/images/win/VirtualBoxubuntu-31.jpg b/images/win/VirtualBoxubuntu-31.jpg new file mode 100644 index 00000000..ec68e7d8 Binary files /dev/null and b/images/win/VirtualBoxubuntu-31.jpg differ diff --git a/images/win/VirtualBoxubuntu-32.jpg b/images/win/VirtualBoxubuntu-32.jpg new file mode 100644 index 00000000..4e2abaca Binary files /dev/null and b/images/win/VirtualBoxubuntu-32.jpg differ diff --git a/images/win/VirtualBoxubuntu-33.jpg b/images/win/VirtualBoxubuntu-33.jpg new file mode 100644 index 00000000..7f1b22a7 Binary files /dev/null and b/images/win/VirtualBoxubuntu-33.jpg differ diff --git a/images/win/VirtualBoxubuntu-34.jpg b/images/win/VirtualBoxubuntu-34.jpg new file mode 100644 index 00000000..7651d6fb Binary files /dev/null and b/images/win/VirtualBoxubuntu-34.jpg differ diff --git a/images/win/VirtualBoxubuntu-35.jpg b/images/win/VirtualBoxubuntu-35.jpg new file mode 100644 index 00000000..72ced607 Binary files /dev/null and b/images/win/VirtualBoxubuntu-35.jpg differ diff --git a/images/win/VirtualBoxubuntu-36.jpg b/images/win/VirtualBoxubuntu-36.jpg new file mode 100644 index 00000000..8a33add0 Binary files /dev/null and b/images/win/VirtualBoxubuntu-36.jpg differ diff --git a/images/win/VirtualBoxubuntu-37.jpg b/images/win/VirtualBoxubuntu-37.jpg new file mode 100644 index 00000000..f6690d1f Binary files /dev/null and b/images/win/VirtualBoxubuntu-37.jpg differ diff --git a/images/win/VirtualBoxubuntu-38.jpg b/images/win/VirtualBoxubuntu-38.jpg new file mode 100644 index 00000000..7af40f37 Binary files /dev/null and b/images/win/VirtualBoxubuntu-38.jpg differ diff --git a/images/win/VirtualBoxubuntu-39.jpg b/images/win/VirtualBoxubuntu-39.jpg new file mode 100644 index 00000000..7e2a171b Binary files /dev/null and b/images/win/VirtualBoxubuntu-39.jpg differ diff --git a/images/win/VirtualBoxubuntu-4.jpg b/images/win/VirtualBoxubuntu-4.jpg new file mode 100644 index 00000000..435dc5c7 Binary files /dev/null and b/images/win/VirtualBoxubuntu-4.jpg differ diff --git a/images/win/VirtualBoxubuntu-40.jpg b/images/win/VirtualBoxubuntu-40.jpg new file mode 100644 index 00000000..fb521d06 Binary files /dev/null and b/images/win/VirtualBoxubuntu-40.jpg differ diff --git a/images/win/VirtualBoxubuntu-41.jpg b/images/win/VirtualBoxubuntu-41.jpg new file mode 100644 index 00000000..24f8877c Binary files /dev/null and b/images/win/VirtualBoxubuntu-41.jpg differ diff --git a/images/win/VirtualBoxubuntu-42.jpg b/images/win/VirtualBoxubuntu-42.jpg new file mode 100644 index 00000000..a40306d6 Binary files /dev/null and b/images/win/VirtualBoxubuntu-42.jpg differ diff --git a/images/win/VirtualBoxubuntu-43.jpg b/images/win/VirtualBoxubuntu-43.jpg new file mode 100644 index 00000000..1cc2a4e2 Binary files /dev/null and b/images/win/VirtualBoxubuntu-43.jpg differ diff --git a/images/win/VirtualBoxubuntu-44.jpg b/images/win/VirtualBoxubuntu-44.jpg new file mode 100644 index 00000000..8f967a4d Binary files /dev/null and b/images/win/VirtualBoxubuntu-44.jpg differ diff --git a/images/win/VirtualBoxubuntu-45.jpg b/images/win/VirtualBoxubuntu-45.jpg new file mode 100644 index 00000000..88c853f3 Binary files /dev/null and b/images/win/VirtualBoxubuntu-45.jpg differ diff --git a/images/win/VirtualBoxubuntu-46.jpg b/images/win/VirtualBoxubuntu-46.jpg new file mode 100644 index 00000000..d5c8ec83 Binary files /dev/null and b/images/win/VirtualBoxubuntu-46.jpg differ diff --git a/images/win/VirtualBoxubuntu-47.jpg b/images/win/VirtualBoxubuntu-47.jpg new file mode 100644 index 00000000..2da005d2 Binary files /dev/null and b/images/win/VirtualBoxubuntu-47.jpg differ diff --git a/images/win/VirtualBoxubuntu-48.jpg b/images/win/VirtualBoxubuntu-48.jpg new file mode 100644 index 00000000..f6ded6fb Binary files /dev/null and b/images/win/VirtualBoxubuntu-48.jpg differ diff --git a/images/win/VirtualBoxubuntu-5.jpg b/images/win/VirtualBoxubuntu-5.jpg new file mode 100644 index 00000000..a954b9d7 Binary files /dev/null and b/images/win/VirtualBoxubuntu-5.jpg differ diff --git a/images/win/VirtualBoxubuntu-6.jpg b/images/win/VirtualBoxubuntu-6.jpg new file mode 100644 index 00000000..40fb6ec0 Binary files /dev/null and b/images/win/VirtualBoxubuntu-6.jpg differ diff --git a/images/win/VirtualBoxubuntu-7.jpg b/images/win/VirtualBoxubuntu-7.jpg new file mode 100644 index 00000000..b424a40b Binary files /dev/null and b/images/win/VirtualBoxubuntu-7.jpg differ diff --git a/images/win/VirtualBoxubuntu-8.jpg b/images/win/VirtualBoxubuntu-8.jpg new file mode 100644 index 00000000..8bce7d68 Binary files /dev/null and b/images/win/VirtualBoxubuntu-8.jpg differ diff --git a/images/win/VirtualBoxubuntu-9.jpg b/images/win/VirtualBoxubuntu-9.jpg new file mode 100644 index 00000000..f7929d8c Binary files /dev/null and b/images/win/VirtualBoxubuntu-9.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..c71b8acc --- /dev/null +++ b/index.html @@ -0,0 +1,3132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + カルダノステークプール構築ガイド - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

カルダノステークプール構築ガイド

+

SPO JAPAN GUILDでは、カルダノネットワーク分散化促進活動の一環で、日本人向けにSPO構築・運用マニュアル・サポートコミュニティを整備しており、カルダノステークプールオペレーターに必要な知識を習得することができます。

+
+

情報

+

このマニュアルは、カルダノノードv8.7.3に対応しています。
+最終更新日:2024年1月27日 guide version 13.0.1

+
+
+

サポート

+

サポートが必要な場合は、ディスコードSPO JAPAN GUILDコミュニティで現役のSPOに質問できます

+
+

ステークプールとは?

+

カルダノネットワークのコンセンサスアルゴリズムはPoSを採用し、Cardanoノードを運用するステークプールによってトランザクション処理とブロック生成を担当します。

+

SPOとは?

+

SPO=Stake Pool Operator
+ステークプールを運用するオペレーターを指します。カルダノノードを適切に運用・監視しカルダノネットワークのセキュリティを維持します。

+

SPOの必須スキル

+

カルダノステークプールを運営するには、以下のスキルを必要とします。

+
    +
  • カルダノノードを継続的にセットアップ、実行、維持する運用スキル
  • +
  • ノードを24時間年中無休で維持するコミット
  • +
  • システム運用スキル
  • +
  • サーバ管理スキル (運用および保守)
  • +
  • 開発と運用経験 (DevOps)
  • +
  • サーバ強化とセキュリティに関するスキル
  • +
+

SPOは何をするのか?

+
    +
  • ステークプール構築
  • +
  • サーバー(ノード)監視
  • +
  • 割り当てブロック生成 ※ノード設定が正しければ自動生成されます
  • +
  • マーケティング・コミュニティ貢献活動
  • +
+

運用コスト

+ + + + + + + + + + + + + + + + + + + + + + + + + +
項目コスト
プール登録料(初回のみ)500ADA
ステークアドレス発行料(初回のみ)2ADA
トランザクション手数料数ADA
サーバー代(最小構成2台)/月16000円~32000円
+

オペレーター報酬

+ +

①+( プール総報酬 - ① )* ②=オペレーター報酬

+
+ + + + + + + + + + + + + + + + + +
項目報酬
①固定報酬最低170ADAから設定可能
②変動報酬0%~100%まで設定可能
+
+

注意

+

※オペレーター報酬設定値が大きくなればなるほど委任者の報酬が減少します

+
+

サーバースペック要件

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目要件
サーバーBP用1台 リレー用1台 エアギャップマシン1台
OS64-bit Linux (Ubuntu 20.04 LTS)
CPU2Ghz以上 2コアのIntelまたはAMD x86プロセッサー
メモリ24GB
ストレージ300GB
ネットワーク10Mbps
帯域1時間あたり1GBの帯域
電力24時間365日安定供給
ADA600ADA
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目要件
サーバーBP用1台 リレー用2台 エアギャップマシン1台
OS64-bit Linux (Ubuntu 20.04 LTS)
CPU2Ghz以上 4コアのIntelまたはAMD x86プロセッサー
メモリ24GB over
ストレージ300GB以上
ネットワーク100Mbps
帯域無制限
電力24時間365日安定供給
ADA無制限
+
+
+
+

サーバー構成イメージ

+

最小構成 +

    flowchart BT
+        a2[リレー1] <-- 開放FW --> a4[カルダノネットワーク]
+        subgraph ide1[プール]
+            subgraph リレーIP指定FW
+                a1[BP]
+            end
+        a1[BP] <--> a2[リレー1]
+        end
+        c1[PC] --> ide1
+        c1[PC] --> エアギャップ

+

推奨構成 +

    flowchart BT
+        a2[リレー1] & a3[リレー2] <-- 開放FW --> a4[カルダノネットワーク]
+        subgraph ide1[プール]
+            subgraph リレーIP指定FW
+                a1[BP]
+            end
+                a1[BP] <--> a2[リレー1] & a3[リレー2]
+        end
+        c1[PC] --> ide1
+        c1[PC] --> エアギャップ

+
+

サポート

+

サポートが必要な場合は、SPO JAPAN GUILDコミュニティで現役のSPOに質問できます

+
+

サーバー選定について

+
+

カルダノは最も分散化されたネットワークでセキュリティ向上を目指しており、世界中に分散されたノードネットワークの形成が、カルダノにとって最も重要になります。
+このことから、当ギルド内では「おすすめのサーバー(VPS)業者」の情報共有は行っておりませんので、各自で選定をお願い致します。

+
+

お試しノード起動

+
+
    +
  • Linuxサーバのコマンドや、ノード起動などお試しテストでやってみたい方は、手元のパソコンでエアギャップ環境を構築後、プール構築マニュアルの2. ノードインストールをやってみましょう!
  • +
  • この項目はブロックチェーンには直接的に影響がないので、たとえ間違ったコマンドを送信してもネットワークには問題ございません。
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/learning/index.html b/learning/index.html new file mode 100644 index 00000000..997a6abc --- /dev/null +++ b/learning/index.html @@ -0,0 +1,3026 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SJGラーニング - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

SJGラーニング

+
+

SJGラーニングとは?

+

こちらの内容はSJGディスコードで毎週土曜日21時から開催のSPOミーティング内で不定期に実施しているSJGラーニング教材です。プールオペレーションにおける基礎知識を共有しSPOのレベルアップを図ります。

+

SPOミーティング議事録はこちら

+
+

第1回 ファイアウォールとポートの基礎知識

+

第2回 カルダノ・プロトコルパラメータ

+

第3回 ブロックログサービスの関係性

+

第4回 リレーネットワークトポロジー

+

第5回 監視メトリクス

+

第6回 cardano-cliの使い方

+

第7回 ダイナミックP2P

+

第8回 ノードトラブルシューティング

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/add-relay/index.html b/operation/add-relay/index.html new file mode 100644 index 00000000..70c32aa2 --- /dev/null +++ b/operation/add-relay/index.html @@ -0,0 +1,2952 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2-3.リレーノード増設 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

リレーノード増設マニュアル

+

1.Ubuntu初期設定

+

https://docs.spojapanguild.net/setup/1-ubuntu-setup/

+

2.ノードインストール

+

https://docs.spojapanguild.net/setup/2-node-setup/

+

3.リレーサーバーの設定変更

+

https://docs.spojapanguild.net/setup/3-relay-bp-setup/#3-1

+

4.BPのFWと設定ファイル変更

+
+
+
+
PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+
+

<増設リレーノードのIP><>を除いてIPのみ入力してください。 +

sudo ufw allow from <増設リレーノードのIP> to any port ${b_PORT}
+sudo ufw reload
+

+
+

ヒント

+

自身のBPノードから接続するリレーノードのIPとポート番号を指定します。 +あらかじめ、「xxx.xxx.xxx.xxx」はご自身のリレーサーバーパブリックIP(静的)アドレスとポート番号 に置き換えてからコマンドを実行して下さい。リレー台数分記載します。

+
+

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
+{
+    "Producers": [
+    {
+        "addr": "aa.xxx.xxx.xxx",
+        "port": 6000,
+        "valency": 1
+    },
+    {
+        "addr": "bb.xxx.xxx.xxx",
+        "port": 6000,
+        "valency": 1
+    }
+    ]
+}
+EOF
+
+
sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

5.P2Pトポロジー設定

+ +

6.監視ツールセットアップ

+
+
+
+

9-1.インストール
+「BPまたはリレー2以降」タブと「全サーバー」タブを増設リレーで実施
+https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/#1

+

9-3.ノード設定ファイルの更新
+https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/#3

+
+
+
+

9-2.設定ファイルの作成 +グラファナがインストールされているサーバーで 「リレーノード1(リレー2台の場合)」タブを実施

+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/bp-move/index.html b/operation/bp-move/index.html new file mode 100644 index 00000000..b3db133a --- /dev/null +++ b/operation/bp-move/index.html @@ -0,0 +1,3718 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BPサーバー - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

BPサーバーの引越し手順(旧VPS会社→新VPS会社)

+
+

前提注意事項

+
    +
  • 本まとめは現VPS会社→新VPS会社へと BPのみ を移行するまとめです。
  • +
  • 実際に行う際には手順をよく読みながら進めてください。
  • +
  • ブロック生成予定まで余裕がある時に実施してください。
  • +
  • 旧BPは3-3.旧BPシャットダウンまで、起動状態 にしておいてください。
  • +
+
+

1.新BPセットアップ

+
+

留意事項

+
    +
  1. サーバ独自機能に留意する
      +
    • さくらのパケットフィルタや、AWSのFW設定などのサーバー独自の機能に気を付けてください。
    • +
    +
  2. +
  3. 新BPのファイヤーウォール設定は、旧BPと同じ設定にしてください。
  4. +
  5. 旧BPのユーザー名(例:ubuntu)と新BPのユーザー名は変更しないでください。
      +
    • もし変更する場合は、以下のファイル内のパス名を手動で変更してください。
    • +
    • startBlockProducingNode.sh DIRECTORY=/home/ユーザー名/cnode
    • +
    +
  6. +
+
+

1-1.Ubuntu初期設定

+

新サーバーでUbuntu初期設定を実施します。

+

1-2.ノードセットアップ

+

依存関係インストール 〜 +gLiveViewのインストールまで実施します。

+

2.既存リレー作業

+

リレートポロジー情報変更

+
+
+
+
+
+
+
+
+
+

nano $NODE_HOME/relay-topology_pull.sh
+
+旧BPのIPとポートを新BPのIPとポートに変更する

+
    +
  • BLOCKPRODUCING_IP=xxx.xxx.xxx
  • +
  • BLOCKPRODUCING_PORT=xxxx
  • +
+
+

relay-topology_pull.shを実行し、リレーノードを再起動します。

+

cd $NODE_HOME
+./relay-topology_pull.sh
+
+ノード再起動 +
sudo systemctl reload-or-restart cardano-node
+

+
+

gLiveviewでリレーが最新ブロックと同期することをご確認ください

+
+
+
+
nano $NODE_HOME/${NODE_CONFIG}-topology.json
+
+
+

旧BPのIPとポートを新BPのIPとポートに変更する

+
+

トポロジーファイルの再読み込み +

kill -SIGHUP $(pidof cardano-node)
+

+
+

ダイナミックP2P有効時、トポロジーファイル変更による再起動は不要です。

+
+
+
+
+

3.旧BP移行処理

+

3-1.旧BPノード停止

+
+
+
+

sudo systemctl stop cardano-node
+
+
sudo systemctl disable cardano-node
+

+
+
+
+

3-2.旧BPファイル移動

+
+参考)移行ファイル一覧 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル名用途
vrf.skeyブロック生成に必須
vrf.vkeyブロック生成に必須
kes.skeyブロック生成に必須
kes.vkeyKES公開鍵
node.certブロック生成に必須
payment.addr残高確認で必要
stake.addr残高確認で必要
mainnet-topology.jsonトポロジーファイル
poolMetaData.jsonpool.cert作成時に必要
poolMetaDataHash.txtpool.cert作成時に必要
startBlockProducingNode.shノード起動スクリプト
pool.id-bech32stakepoolid(bech32形式)
pool.idstakepoolid(hex形式)
guild-dbブロックログ関連フォルダ(cncli.db以外)
+
+
+
+
+

Zstandardインストール +

sudo apt install zstd
+

+

上記の移行ファイルを一つのファイルに圧縮する +

cd $NODE_HOME
+tar --exclude "guild-db/cncli/cncli.db" -acvf bp-move.zst guild-db/ vrf.skey vrf.vkey kes.skey kes.vkey node.cert payment.addr stake.addr mainnet-topology.json poolMetaData.json poolMetaDataHash.txt startBlockProducingNode.sh pool.id-bech32 pool.id
+

+
+
+
+

旧BPのcnodeにあるbp-move.zstを新BPのcnodeディレクトリにコピーする +

graph LR
+    A[旧BP] -->|bp-move.zst| B[新BP];

+

3-3.旧BPシャットダウン

+
sudo shutdown -h now
+
+

4.新BP再設定

+

4-1.移行ファイル復元

+
+
+
+

ノード停止 +

sudo systemctl stop cardano-node
+

+

ファイル確認 +

ls $NODE_HOME/bp-move.zst
+

+
+

ファイルパスが表示されることを確認する。
+例)/home/cardano/cnode/bp-move.zst

+
+

ファイル展開 +

cd $NODE_HOME
+tar -xvf bp-move.zst
+

+
+

戻り値に移行ファイル一覧のファイル名が表示されることを確認する

+
+

圧縮ファイルを削除する +

rm bp-move.zst
+

+
+
+
+

4-2. パーミッション変更

+
+
+
+
cd $NODE_HOME
+chmod 400 vrf.skey
+chmod 400 vrf.vkey
+chmod +x startBlockProducingNode.sh
+
+

ノードを起動します。 +

sudo systemctl start cardano-node
+
+ノードログ確認 +
journalctl --unit=cardano-node --follow
+

+
+
+
+

4-3. 新BP接続確認

+

gLiveViewで新BPが最新ブロックと同期後、リレーと疎通(I/O)ができているかを確認します。

+
+
+
+

gLiveView確認 +

cd $NODE_HOME/scripts
+./gLiveView.sh
+

+
+

InとOutにリレーのIPがあることを確認してください。

+
+
+
+
+

4-4. params.json再作成

+
+
+
+
+
+
cd $NODE_HOME
+cardano-cli query protocol-parameters \
+    --mainnet \
+    --out-file params.json
+
+

4-5. ブロックログ設定

+ +
+

注意

+

「10-6. 過去のブロック生成実績取得」は実施しないでください。

+
+

4-6. SJGツール導入

+ +

4-7. ブロック生成状態チェック

+

SJGツールを起動し、「[2] ブロック生成状態チェック」ですべての項目がOKになることを確認する

+

4-8. ブロック生成ステータス通知設定

+
+
+
+

依存環境インストール

+
+
+
+
+
+

sudo apt install -y python3-watchdog python3-tz python3-dateutil python3-requests build-essential libssl-dev libffi-dev python3-dev python3-pip
+
+
pip install discordwebhook python-dotenv slackweb
+
+パーミッション変更 +
chmod +x $NODE_HOME/guild-db/blocklog/block_check.py
+
+サービスファイル作成 +
cat > $NODE_HOME/service/cnode-blockcheck.service << EOF 
+# file: /etc/systemd/system/cnode-blockcheck.service
+
+[Unit]
+Description=Cardano Node - CNCLI blockcheck
+BindsTo=cnode-cncli-sync.service
+After=cnode-cncli-sync.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME
+ExecStart=/usr/bin/tmux new -d -s blockcheck
+ExecStartPost=/usr/bin/tmux send-keys -t blockcheck 'cd $NODE_HOME/guild-db/blocklog' Enter
+ExecStartPost=/usr/bin/tmux send-keys -t blockcheck python3 Space block_check.py Enter
+ExecStop=/usr/bin/tmux kill-session -t blockcheck
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-blockcheck
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cnode-cncli-sync.service
+EOF
+
+
sudo cp $NODE_HOME/service/cnode-blockcheck.service /etc/systemd/system/cnode-blockcheck.service
+sudo chmod 644 /etc/systemd/system/cnode-blockcheck.service
+
+
sudo systemctl daemon-reload
+sudo systemctl enable cnode-blockcheck.service
+

+
+ +
+
+

5. Prometheus設定

+

5-1.新BPnode exporterインストール

+
+
+
+
sudo apt install -y prometheus-node-exporter
+
+

サービスを有効にして、自動的に開始されるように設定します。 +

sudo systemctl enable prometheus-node-exporter.service
+

+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

5-2.Grafanaサーバーprometheus.ymlの修正

+
+
+
+

prometheus.ymlに記載されてる旧BPのIPを新BPのIPへ変更してください +

sudo nano /etc/prometheus/prometheus.yml
+

+

サービス再起動 +

sudo systemctl restart grafana-server.service
+sudo systemctl restart prometheus.service
+sudo systemctl restart prometheus-node-exporter.service
+

+

サービスが正しく実行されていることを確認します。 +

sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service
+

+

GrafanaにBPのメトリクス(KESなど)が表示されているか確認する。

+
+
+
+
+

6.補足

+

Tracemempool無効化

+

Txの増加が確認できたらTracemempoolを無効にします。

+
+
+
+
+
+
sed -i $NODE_HOME/${NODE_CONFIG}-config.json \
+    -e "s/TraceMempool\": true/TraceMempool\": false/g"
+
+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+

Mithril-Signer再セットアップ

+

旧サーバーでMithril-Signer-Nodeを実行していた場合は、新サーバーでも再セットアップしてください。不明点がある場合はBTBF SPO LAB.でご質問ください。

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/bpport/index.html b/operation/bpport/index.html new file mode 100644 index 00000000..552448fb --- /dev/null +++ b/operation/bpport/index.html @@ -0,0 +1,2997 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2-5.BPポート変更 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

BPノードポート番号変更手順

+

BPノードポートを6000番で運用されてる方向けの変更マニュアルです。

+
+

BPノードポート番号を変更する理由

+

CNTOOLでは参考として6000ポートが割り当てられており、こちらに合わせる形で当マニュアルも6000を採用しておりましたが、6000ポートは「x window system」に割り当てられてるポートで、使わなければ使っても大丈夫となっています。ただし、BPポート=6000という認識が広まっていくと、セキュリティ上好ましくなく各プールで独自ポートを採用したほうが良いため。

+
+

変更点

+
    +
  1. ダイナミックポート(49513~65535までの番号)を使います。
  2. +
  3. $NODE_HOME/startBlockProducingNode.shのPORT=6000を変更するポート番号へと書き換えます。
  4. +
  5. $NODE_HOME/scripts/envのCNODE_PORT=6000を変更するポート番号へと書き換えます。
  6. +
+

BPにて実施

+

新しいBPノードポート番号を決める為、xxxxxを(49513~65535)の範囲内で決めて入力します。

+
PORT=xxxxx
+
+

スクリプトのポートを新しいポートに書き換える(このままコピーして実行) +

sed -i $NODE_HOME/startBlockProducingNode.sh \
+    -e '1,73s!PORT=6000!PORT='${PORT}'!'
+sed -i $NODE_HOME/scripts/env \
+    -e '1,73s!CNODE_PORT=6000!CNODE_PORT='${PORT}'!'
+

+

BPサーバーufw設定変更

+
+

ufwを使わないケース

+

AWSやVSPによっては管理画面でセキュリティ設定(ファイアウォール)を行う場合がありますので、その場合は、管理画面から設定を変更してください。

+
+

新しいポート番号取得 +

PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+
+ファイアウォール旧BPポート許可を削除

+
+

山かっこ<>は不要です +

sudo ufw status numbered
+sudo ufw delete <削除したい番号>
+

+
+

新しいBPポート番号の許可を設定(リレーが2台ある想定) +

sudo ufw allow from <リレー1> to any port ${b_PORT}
+sudo ufw allow from <リレー2> to any port ${b_PORT}
+sudo ufw reload
+

+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+

変更確認

+
    +
  • BPポートがきちんと変更されたかを確認します。
  • +
+
ps aux | grep cardano-node
+
+
+

戻り値の --port を確認します。

+
+
    +
  • BPノードを再起動後、各サービスが正常稼働していることも併せて確認しておきます。
  • +
+
tmux a -t cncli
+tmux a -t leaderlog
+tmux a -t logmonitor
+tmux a -t validate
+tmux a -t blockcheck
+
+
+

blockcheckサービスを導入している場合のコマンドも併せて記載してます。

+
+
+補足 + +
+ +サービス再起動コマンド +
sudo systemctl reload-or-restart cnode-cncli-sync.service
+
+ブロックチェック再起動コマンド +
sudo systemctl reload-or-restart cnode-blockcheck.service
+
+ +デタッチ方法 +
Ctrl + b → d
+
+ +
+ +
+ +

リレーにて実施

+

疎通確認

+
+

0.0.0.0をBPIPに書き換えて、 +xxxxxをBPノードポート番号を入力し実行。 +

nc -vz 0.0.0.0 xxxxx
+

+

port [tcp/*] succeeded! であればOKです。

+
+

トポロジーファイル生成用スクリプト書き換え

+
+

トポロジー共有のため別ファイルを自身で作成している場合は、そちらでも忘れずにポート番号を変更しておいてください。
+xxxxxは、BPノードポート番号を入力します。

+
+

PORT=xxxxx
+
+
sed -i $NODE_HOME/relay-topology_pull.sh \
+    -e '1,10s!BLOCKPRODUCING_PORT=6000!BLOCKPRODUCING_PORT='${PORT}'!'
+

+

トポロジーファイルを再作成します。 +

cd $NODE_HOME
+./relay-topology_pull.sh
+

+

ノード再起動します。 +

sudo systemctl reload-or-restart cardano-node
+

+

BPポートを確認します。 +

cat $NODE_HOME/mainnet-topology.json
+

+

最終確認

+

BPのGliveViewを起動し、[p] Peer Analysisを表示。
+リレーノードのIPがio両方で表示されていることを確認する。

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/catalyst-voting/index.html b/operation/catalyst-voting/index.html new file mode 100644 index 00000000..9c07d3cd --- /dev/null +++ b/operation/catalyst-voting/index.html @@ -0,0 +1,3206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1-4.カタリスト有権者登録 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

1-4.カタリスト有権者登録

+ +
+

概要

+
    +
  • +

    このマニュアルは、プールのpayment.addrを有権者登録する方法です。
    + payment.addrの資金をVotingパワーに使用でき、Catalyst投票が可能になります。

    +
  • +
  • +

    依存関係はBPにインストールしてください。

    +
  • +
  • 有権者登録作業はSJG TOOLで行います。
  • +
+
+

1. 事前準備インストール

+

以下の依存関係はBPサーバーにインストールしてください

+

必要なバイナリ

+ + + + + + + + + + + + + + + +
bech32cardano-signercatalyst-toolbox
v1.1.3v1.13.0v0.5.0
+

Bech32インストール

+

ダウンロード

+
+
+
+
cd $HOME/git
+wget https://github.com/input-output-hk/bech32/archive/refs/tags/$(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz
+tar -xf $(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz
+mv bech32-$(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name | tr -d v) bech32
+rm $(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz
+
+
+
+
+

ビルド

+
+
+
+
cd bech32
+cabal update
+cabal build bech32
+
+
+
+
+

binディレクトリへコピー

+
+
+
+
sudo cp $(find $HOME/git/bech32/dist-newstyle/build -type f -name "bech32") /usr/local/bin/bech32
+
+
+
+
+

バージョン確認

+
+
+
+
bech32 -v
+
+
+
+
+
+

戻り値 1.1.3

+
+

cardano-signerインストール

+
+
+
+
cd $HOME/git
+wget https://github.com/gitmachtl/cardano-signer/releases/download/$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name)/cardano-signer-$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name | tr -d v)_linux-x64.tar.gz
+tar -xf cardano-signer-$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name | tr -d v)_linux-x64.tar.gz
+
+
+
+
+

binディレクトリへコピー

+
+
+
+
sudo cp $HOME/git/cardano-signer /usr/local/bin/cardano-signer
+
+
+
+
+

バージョン確認

+
+
+
+
cardano-signer help | grep -m 1 "cardano-signer"
+
+
+
+
+
+

cardano-signer 1.13.0

+
+

エアギャップへコピー

+

BPの$HOME/git/直下にあるcardano-signerをダウンロードし、エアギャップの$HOME/git/直下にコピーする

+
+

ファイル転送

+

BPにあるcardano-signerをエアギャップオフラインマシンの$HOME/git/ディレクトリにコピーします。 +

graph LR
+    A[BP] -->|cardano-signer| B[エアギャップ];

+
+

binディレクトリへコピー

+
+
+
+
sudo cp $HOME/git/cardano-signer /usr/local/bin/cardano-signer
+
+
+
+
+

パーミッション設定

+
+
+
+
sudo chmod 755 /usr/local/bin/cardano-signer
+
+
+
+
+

バージョン確認

+
+
+
+
cardano-signer help | grep -m 1 "cardano-signer"
+
+
+

cardano-signer 1.13.0

+
+
+
+
+

catalyst-toolboxインストール

+
+
+
+
cd $HOME/git
+git clone https://github.com/input-output-hk/catalyst-toolbox.git
+cd catalyst-toolbox
+git checkout 6c3ebb7
+
+
+
+
+

Rustパッケージアップデート

+
+
+
+
rustup update
+
+
+
+
+

インストール

+
+
+
+
cd catalyst-toolbox
+cargo install --path . --force
+
+
+
+
+

バージョン確認

+
+
+
+
catalyst-toolbox --version
+
+
+

catalyst-toolbox 0.5.0

+
+
+
+
+

2. 有権者登録作業

+

SJGTOOL起動

+

+

有権者登録の流れ

+
    graph LR
+        A[依存関係チェック] --> B[投票用キー作成] --> C[メタデータ作成] --> D[Tx作成/送信] --> E[QRコード作成];
+
+

作成ファイルについて

+

XXX_voting.skey / XXX_voting.vkey / XXX_voting.json (XXXはティッカー名)

+
    +
  • 上記の3ファイルはダウンロードして、USBなどへバックアップしてください。
  • +
  • XXX_voting.jsonには、復元フレーズが含まれています。
    +Fund11から開始予定のWeb版Catalyst投票センターを使用する際に必要になりますので、厳重に保管して下さい。
  • +
+
+
+

中断した場合

+

処理が途中で中断した場合でも、SJGTOOLを起動し[5]Catalyst有権者登録を選択すれば途中から再開できます。

+
+

QRコード作成後

+

QRコードが発行できたら$HOME/CatalystVotingディレクトリ内ファイルの整理をお願いします。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル名サーバー内処理バックアップ
XXX_voting.skey削除必須
XXX_voting.vkey削除必須
XXX_voting.json削除必須
vote-registration.cbor削除任意
XXX_vote_qrcode.png保管必須
txhash.log保管任意
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/cert-update/index.html b/operation/cert-update/index.html new file mode 100644 index 00000000..c86a21f5 --- /dev/null +++ b/operation/cert-update/index.html @@ -0,0 +1,3025 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1-2.プール情報更新 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

プール情報(pool.cert)の更新

+
+

概要

+
    +
  • 誓約、固定手数料、変動手数料、リレー情報、メタデータを変更する場合に実施します。
  • +
  • メタデータURLのみ変更になる場合でも「メタデータ更新を含む場合」を実施しメタデータファイルを再作成してください。
  • +
+
+
+

注意

+

誓約・固定手数料・変動手数料の反映は提出エポック+3エポック後からになります。
+例)
+320エポックに変更申請
+321エポックで有効化
+322エポックで待機
+323エポックで反映

+
+
+
+
+
+
+
+

変数にプールメタデータ値を設定し実行してください

+
+

文字列は''で囲ってください
+extendedを設定していない場合は ''のままで大丈夫です +

name=''
+description=''
+ticker=''
+homepage=''
+extended=''
+

+
+

メタデータファイルを作成する

+
+

全選択コピーしてそのまま実行してください +

cat > $NODE_HOME/poolMetaData.json << EOF
+{
+    "name": "$name",
+    "description": "$description",
+    "ticker": "$ticker",
+    "homepage": "$homepage",
+    "extended": "$extended",
+    "nonce":"$(date +%s)"
+}
+EOF
+

+
+
+
+
+
+

poolMetaData.jsonを各ホストサーバーへアップロードする

+

poolMetaData.jsonをローカルマシンにダウンロードし、Githubまたはご自身のサーバーの所定の位置にアップロードしてください

+
+

ハッシュ値確認

+
+
+
+
cd $NODE_HOME
+cardano-cli stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt
+
+

オンラインファイルハッシュ値確認

+
+

https:****.**.**をメタデータファイルのURLに置き換えてから実行してください

+
+
cd $NODE_HOME
+wget -O onlineMetaData.json https:****.**.**
+
+

オンラインメタデータハッシュ値 +

cardano-cli stake-pool metadata-hash --pool-metadata-file onlineMetaData.json > onlineMetaDataHash.txt
+

+

ハッシュ値 +

printf "\n サーバー:$(cat poolMetaDataHash.txt)\nオンライン:$(cat onlineMetaDataHash.txt)\n\n"
+

+
+

ハッシュ値が一致する必要があります。異なる場合はホストサーバーへ正しくアップロードされているかご確認ください。

+
+

ハッシュ値が一致したら、確認用ファイルを削除する。 +

rm onlineMetaDataHash.txt
+rm onlineMetaData.json
+

+
+
+
+
+

ファイル転送

+

BPのpoolMetaDataHash.txt をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|poolMetaDataHash.txt| B[エアギャップ];

+
+

BPとエアギャップハッシュ値確認

+
+
+
+
+
+
cd $NODE_HOME
+$(cat poolMetaDataHash.txt)
+
+
+
+
+
+
+
cd $NODE_HOME
+$(cat poolMetaDataHash.txt)
+
+
+

ハッシュ値が異なっている場合は、BPのpoolMetaDataHash.txtがエアギャップに正しくコピーされていません。

+
+
+
+
+
+

登録証明書トランザクションを作成する

+

複数のリレーノードを設定する場合は 複数のリレーノードを構成する記述方法 を参考にパラメーターを指定して下さい。

+
+

注意

+

以下は参考コードです。ご自身のプール設定値に変更してください
+例)

+
    +
  • 固定費・・・170ADA
  • +
  • Margin・・・5%
  • +
  • 誓約・・・1000ADA
  • +
+
+
+
+
+
cd $NODE_HOME
+
+
chmod u+rwx $HOME/cold-keys
+cardano-cli stake-pool registration-certificate \
+    --cold-verification-key-file $HOME/cold-keys/node.vkey \
+    --vrf-verification-key-file vrf.vkey \
+    --pool-pledge 1000000000 \
+    --pool-cost 170000000 \
+    --pool-margin 0.05 \
+    --pool-reward-account-verification-key-file stake.vkey \
+    --pool-owner-stake-verification-key-file stake.vkey \
+    $NODE_NETWORK \
+    --pool-relay-ipv4 ***.***.***.*** \
+    --pool-relay-port 6000 \
+    --metadata-url https://xxx.xxx.xxx/poolMetaData.json \
+    --metadata-hash $(cat poolMetaDataHash.txt) \
+    --out-file pool.cert
+
+
+
+
+
+

ヒント

+

上記のコードを自プール用の設定に修正したら、次回も使用できるようテキストファイルとして保存しておいてください。

+
+

ステークプールに誓約します。

+
+
+
+
cardano-cli stake-address delegation-certificate \
+    --stake-verification-key-file stake.vkey \
+    --cold-verification-key-file $HOME/cold-keys/node.vkey \
+    --out-file deleg.cert
+
+
+
+
+
+

ファイル転送

+

エアギャップのpool.certdeleg.certをブロックプロデューサーのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|pool.cert / deleg.cert| B[BP];

+
+

最新のスロット番号を取得します

+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

payment.addrの残高を出力します。

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

build-rawトランザクションコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${total_balance} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --certificate-file pool.cert \
+    --certificate-file deleg.cert \
+    --out-file tx.tmp
+
+
+
+
+

最低手数料を計算します。

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 3 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

計算結果を出力します。

+
+
+
+
txOut=$((${total_balance}-${fee}))
+echo txOut: ${txOut}
+
+
+
+
+

トランザクションファイルを構築します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --certificate-file pool.cert \
+    --certificate-file deleg.cert \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

トランザクションに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file $HOME/cold-keys/node.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+chmod a-rwx $HOME/cold-keys
+
+
+
+
+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+

トランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/command/index.html b/operation/command/index.html new file mode 100644 index 00000000..c27975ca --- /dev/null +++ b/operation/command/index.html @@ -0,0 +1,3207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5.Linuxコマンド集 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

5.Linuxコマンド集

+ +
+

[AKYO] AKYO🥁 Akyoさんからご提供いただきました。ありがとうございます!

+
+

ノード停止

+
sudo systemctl stop cardano-node
+
+

エイリアス設定済みの場合 +

cnstop
+

+

ノード起動

+
sudo systemctl start cardano-node
+
+

エイリアス設定済みの場合 +

cnstart
+

+

ノード再起動

+
sudo systemctl reload-or-restart cardano-node
+
+

エイリアス設定済みの場合 +

cnrestart
+

+

サーバ再起動

+

補足 +- ノード停止してから実施しましょう。 +

sudo reboot
+

+

プロセス確認

+

補足 +- カルダノノードサービス +

ps aux | grep cardano-node
+

+

ネットワーク確認

+
networkctl status -a
+
+

ネットワーク疎通確認

+
nc -vz <IP> <Port>
+
+

ブロックログ各サービス再起動

+

補足 +- (cncli / leaderlog / validate / logmonitor) +

sudo systemctl reload-or-restart cnode-cncli-sync.service
+

+

ブロックチェックサービス再起動

+
sudo systemctl reload-or-restart cnode-blockcheck.service
+
+

パラメータファイル更新

+

補足 +- バックアップ及び更新、確認 +

cd $NODE_HOME
+date=`date +\%Y\%m\%d`
+mv params.json params-$date.json
+cardano-cli query protocol-parameters \
+    --mainnet \
+    --out-file params.json
+
+
nano params.json
+

+

TraceMempoolをTrueからFalseにする

+

cd $NODE_HOME
+sed -i ${NODE_CONFIG}-config.json \
+    -e "s/TraceMempool\": true/TraceMempool\": false/g"
+
+- ノード再起動し設定を反映する +
sudo systemctl reload-or-restart cardano-node
+

+

TraceMempoolをFalseからTrueにする

+

cd $NODE_HOME
+sed -i ${NODE_CONFIG}-config.json \
+    -e "s/TraceMempool\": false/TraceMempool\": true/g"
+
+- ノード再起動し設定を反映する +
sudo systemctl reload-or-restart cardano-node
+

+

既存のスワップファイル削除

+
cd $HOME
+sudo swapoff /swapfile
+sudo rm /swapfile
+
+

スワップファイル作成

+

補足 +- 8GBのスワップを設定するコマンド +

sudo systemctl stop cardano-node
+
+
cd $HOME
+sudo fallocate -l 8G /swapfile
+sudo chmod 600 /swapfile
+sudo mkswap /swapfile
+sudo swapon /swapfile
+sudo swapon --show
+sudo cp /etc/fstab /etc/fstab.bak
+echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
+echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
+echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf
+cat /proc/sys/vm/vfs_cache_pressure
+cat /proc/sys/vm/swappiness
+
+
sudo reboot
+

+

SSH接続

+
ssh -i /Users/ローカルユーザ名/ローカル格納先/id_rsa 接続先ユーザ名@接続先IP -p ポート番号
+
+

systemd活用コマンド

+

🗄 ログのフィルタリング

+

昨日のログ +

journalctl --unit=cardano-node --since=yesterday
+

+
+

コマンド入力に戻る場合は「Ctrl+C」(ノードは終了しません)

+
+

今日のログ +

journalctl --unit=cardano-node --since=today
+

+
+

コマンド入力に戻る場合は「Ctrl+C」(ノードは終了しません)

+
+

期間指定 +

journalctl --unit=cardano-node --since='2020-07-29 00:00:00' --until='2020-07-29 12:00:00'
+

+
+

コマンド入力に戻る場合は「Ctrl+C」(ノードは終了しません)

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/grafana-alert/index.html b/operation/grafana-alert/index.html new file mode 100644 index 00000000..ad763ab2 --- /dev/null +++ b/operation/grafana-alert/index.html @@ -0,0 +1,3365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Grafanaアラート設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

Grafanaアラート設定

+
+

概要

+

サーバー異常状態発生時に任意のアプリへ通知を送信する設定です。
+サーバー監視には必須設定となります。

+
+

1.事前確認

+ +

Grafanaバージョン確認

+
grafana-cli -v
+
+

Grafanaアップデート

+
sudo apt update -y && sudo apt upgrade -y
+
+

2.アラートルールの作成

+

通知の基準となるアラートルールを作成します。

+

1.「左サイドメニュー」→「Alerting」の右の矢印→「Alert rules」→「New alert rule」の順にクリックする +

+

2-1.ノードスロット監視

+
    +
  • ①:Relay1-スロット監視など任意のルール名
  • +
  • ②:Metrics Browserをクリック
  • +
  • ③:cardano_node_metrics_slotInEpoch_intを選択
  • +
  • ④:aliasが選択されていることを確認
  • +
  • ⑤:監視するノード名を選択
  • +
  • +

    ⑥:Use queryをクリック +

    +
  • +
  • +

    ⑦:Bのゴミ箱マークをクリック

    +
  • +
  • ⑧:Cのゴミ箱マークをクリック
  • +
  • +

    ⑨:Add expressionをクリックし、Classic_conditionを選択 +

    +
  • +
  • +

    ⑩:last() / A / HAS NO VALUE選択

    +
  • +
  • ⑪:Set as alert conditionをクリックし、Alert conditionの表示に変える
  • +
  • ⑫:New folderを選択し、SJGを入力してCreate
  • +
  • ⑬:New evaluation groupを選択し、Evaluation group nameノード監視Evaluation interval10sを入力してCreate
  • +
  • ⑭:20sを入力
  • +
  • ⑮:Alertingを選択
  • +
  • +

    ⑯:Alertingを選択 +

    +
  • +
  • +

    ⑰:Add custom annotaionを選択

    +
  • +
  • ⑱:検知内容を入力
  • +
  • ⑲:フィールドに検知メッセージを入力 +例)Relay1のスロットを取得出来ませんでした。ノード起動状態を確認してください
  • +
  • ⑳:ページ上部のSave rule and exitを選択 +
  • +
+

残りの全てのノードのスロット監視を設定する

+

上記で作成したルールをコピーする +

+
    +
  • ①を書き換える
  • +
  • +

    ②:Metrics Browserを書き換える
    +例)
    +cardano_node_metrics_slotInEpoch_int{alias="block-producing-node"}
    +cardano_node_metrics_slotInEpoch_int{alias="relaynode2"}

    +
  • +
  • +

    「4 Add annotations」の検知内容のメッセージ内容を書き換える

    +
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

2-2.BP→リレー接続監視

+

上記で作成したルールをコピーする +

+
    +
  • ①:BPリレー接続監視など任意のルール名に書き換える
  • +
  • ②:Metrics Browsercardano_node_metrics_peers_connectedPeers_int{alias="block-producing-node"}に置き換える
  • +
  • ⑩:last() / A / IS BELOWに切り替え1を入力
  • +
  • ⑮:Alertingを選択
  • +
  • ⑯:Alertingを選択
  • +
  • 「4 Add annotation」の検知内容のメッセージ内容を書き換える
    +例)BPからリレーへの接続が確認できません。接続状況を確認してください
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

2-3.チェーン密度監視

+

上記で作成したルールをコピーする +

+
    +
  • ①:チェーン密度監視など任意のルール名に書き換える
  • +
  • ②:Metrics Browsercardano_node_metrics_density_real{alias="relaynode1"} * 100に置き換える
  • +
  • ⑩:last() / A / IS BELOWに切り替え4.5を入力
  • +
  • ⑮:OKを選択
  • +
  • ⑯:OKを選択
  • +
  • 「4 Add annotation」の検知内容のメッセージ内容を書き換える
    +例)チェーン密度が4.5%を下回っています。これはカルダノチェーン全体の問題です
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

2-4.ノードタイム監視

+

上記で作成したルールをコピーする +

+
    +
  • ①:Relay1-ノードタイム監視など任意のルール名に書き換える
  • +
  • ②:Metrics Browsernode_timex_maxerror_seconds{alias="relaynode1"} * 1000に置き換える
  • +
  • ⑩:last() / A / IS ABOVEに切り替え100を入力
  • +
  • ⑮:OKを選択
  • +
  • ⑯:OKを選択
  • +
  • 「4 Add annotation」の検知内容のメッセージ内容を書き換える
    +例)Relay1のノードタイムが100msを超えています。chronyを再起動してください
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

残り全てのノードのノードタイム監視を設定する

+

上記で作成したルールをコピーする +

+
    +
  • ①を書き換える
  • +
  • +

    ②:Metrics Browserを書き換える
    +例)
    +node_timex_maxerror_seconds{alias="block-producing-node"} * 1000
    +node_timex_maxerror_seconds{alias="relaynode2"} * 1000

    +
  • +
  • +

    「4 Add annotation」の検知内容のメッセージ内容を書き換える

    +
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

2-5.KES残り日数監視

+

上記で作成したルールをコピーする +

+
    +
  • ①:BP-KES残り日数監視など任意のルール名に書き換える
  • +
  • ②:Metrics Browser(cardano_node_metrics_remainingKESPeriods_int * 1.5)に置き換える
  • +
  • ⑩:last() / A / IS BELOWに切り替え10を入力
  • +
  • ⑮:OKを選択
  • +
  • ⑯:OKを選択
  • +
  • 「4 Add annotation」の検知内容のメッセージ内容を書き換える
    +例)KESキーの期限が迫っています。ブロック生成予定のないタイミングでKESキーを更新してください
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

2-6.ディスク使用率監視

+

上記で作成したルールをコピーする +

+
    +
  • ①:Relay1-ディスク使用率監視など任意のルール名に書き換える
  • +
  • ②:Metrics Browser1 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias="relaynode1",mountpoint="/"}に置き換える
  • +
  • ⑩:last() / A / IS ABOVEに切り替え0.9を入力
  • +
  • ⑮:OKを選択
  • +
  • ⑯:OKを選択
  • +
  • 「4 Add annotation」の検知内容のメッセージ内容を書き換える
    +例)Relay1のディスク使用率が90%を超えています。100%に達する前に契約サーバーのアップグレードなどを行う必要があります
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

残り全てのノードのディスク使用率監視を設定する

+

上記で作成したルールをコピーする +

+
    +
  • ①を書き換える
  • +
  • +

    ②:Metrics Browserを書き換える
    +例)
    +1 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias="block-producing-node",mountpoint="/"}
    +1 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias="relaynode2",mountpoint="/"}

    +
  • +
  • +

    「4 Add annotation」の検知内容のメッセージ内容を書き換える

    +
  • +
  • ⑳:ページ上部のSave rule and exitを選択
  • +
+

3.通知先アプリの設定

+
+

通知先アプリの設定

+

アラートの通知先はLINE/Discord/Telegram/Slackを複数指定することが可能です。
+ブロック生成ステータス通知の通知アプリ設定で設定した手順と同様に、通知先名などを変えてトークンを発行してください。

+
+

4.通知テンプレート設定

+
    +
  • +

    「Contact points」をクリックし「Add template」をクリック +

    +
  • +
  • +

    任意のテンプレート名SJGを入力し、以下のテンプレートデータを入力 +

    {{ define "myalert" }}
    +{{ if gt (len .Annotations) 0 }}{{ range .Annotations.SortedPairs }}{{ .Name }}: {{ .Value }}{{ end }}
    +{{ end }}{{ end }}
    +
    +
    +{{ define "mymessage" }}
    +{{ if gt (len .Alerts.Firing) 0 }} 【 ❌障害発生❌ 】{{len .Alerts.Firing}}件 {{ range .Alerts.Firing }}
    +{{ template "myalert" .}} {{ end }}{{ end }}
    +{{ if gt (len .Alerts.Resolved) 0 }}✅以下の障害は復旧しました✅{{len .Alerts.Resolved}}件{{ range .Alerts.Resolved }}
    +{{ template "myalert" .}} {{ end }}{{ end }}
    +{{ end }}
    +
    +

    +
  • +
  • +

    「Save tempelate」をクリック

    +
  • +
+

5.通知先設定

+
    +
  • 「Add contact point」をクリック +
  • +
+

通知先を指定する

+
    +
  • 任意の通知名Self-Alertを入力
  • +
  • 通知先を選択し情報を入力
  • +
  • [3.通知先アプリの設定]で取得した通知アプリごとのトークンIDやWebhookURLを入力する
  • +
  • Option *** SettingsをクリックしDiscriptionに以下のタグを入力 +
    {{ template "mymessage" . }}
    +
  • +
+
+

通知先ごとのタグ入力欄表記違い

+
    +
  • LINE→Description
  • +
  • Discord→Message Content
  • +
  • Slack→Text Body
  • +
  • Telegram→Message
  • +
+
+

+
    +
  • 「Save contact point」をクリック
  • +
+
+

複数の通知先を設定可能

+

「Add contact point integration」をクリックすれば、複数の通知先を設定可能

+
+
    +
  • +

    「Notification policies」→「Edit」をクリック +

    +
  • +
  • +

    Self-Alertを選択

    +
  • +
  • Group bygrafana_folderalertnameを指定
  • +
  • Group interval1 Minutesに設定
  • +
  • Repeat interval10 Minutesに設定
  • +
  • 「Update default policy」をクリック +
  • +
+

6.通知内容URLカスタマイズ

+
+

注意

+ +
+

xxxx.bbb.com[Grafanaセキュリティ設定]で取得したドメイン(サブドメイン)に置き換えて実行する
+https://は不要 +

domain=xxxx.bbb.com
+

+

以下コマンドをすべてコピーして実行する +

sudo sed -i /etc/grafana/grafana.ini \
+    -e 's!;domain = localhost!domain = '${domain}'!' \
+    -e 's!;root_url = %(protocol)s://%(domain)s:%(http_port)s/!root_url = https://%(domain)s/!'
+

+

Grafanaを再起動する +

sudo systemctl restart grafana-server.service
+

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/grafana-repo/index.html b/operation/grafana-repo/index.html new file mode 100644 index 00000000..02d1c915 --- /dev/null +++ b/operation/grafana-repo/index.html @@ -0,0 +1,2899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Grafanaリポジトリ変更 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

Grafanaリポジトリ設定変更手順

+
+

概要

+
    +
  • このマニュアルでは旧式のGrafana更新用APTリポジトリを更新します。
  • +
  • +

    Grafanaがインストールされているサーバー(Relay1)のみ対象です。

    +
  • +
  • +

    設定済みのAPTリポジトリを確認する +

    cat /etc/apt/sources.list.d/grafana.list | grep "https://packages.grafana.com/oss/deb"
    +

    +
    +

    deb https://packages.grafana.com/oss/deb stable mainの戻り値がある場合、以下の作業対象です。

    +
    +
  • +
+
+

1.GPGキーの確認

+

インストール済みのGPG署名キーを確認する

+
sudo apt-key list | grep -B 1 Grafana
+
+
+

Ubuntu22.04の場合は「Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).」という文字が出ますが無視で大丈夫です。

+
+

戻り値 例) +

       4E40 DDF6 D76E 284A 4A67  80E4 8C8C 34C5 2409 8CB6
+ uid           [ unknown] Grafana <info@grafana.com>
+

+

2.旧GPG署名キー削除

+

キーをコピーして削除コマンドを作成して実行する。

+

削除コマンド 例) +

sudo apt-key del "4E40 DDF6 D76E 284A 4A67  80E4 8C8C 34C5 2409 8CB6"
+

+
+

確認

+
    +
  • ""内のキーは、サーバーに表示されているものに変更してください。
  • +
  • 戻り値にキーが複数ある場合は、全てのキーを削除してください。
  • +
  • Ubuntu22.04の場合は「Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).」という文字が出ますが無視で大丈夫です。
  • +
+
+

3.新リポジトリ追加

+
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee -i /etc/apt/sources.list.d/grafana.list
+
+
+

Ubuntu22.04の場合はこちらも実行

+

sudo apt update -y && sudo apt install -y needrestart
+
+
echo "\$nrconf{restart} = 'a';" | sudo tee /etc/needrestart/conf.d/50local.conf
+
+
echo "\$nrconf{blacklist_rc} = [qr(^cardano-node\\.service$) => 0,];" | sudo tee -a /etc/needrestart/conf.d/50local.conf
+

+
+

依存関係インストール +

sudo apt install -y apt-transport-https software-properties-common
+

+

新GPGキーインストール +

sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
+

+

システムアップデート +

sudo apt update -y && sudo apt upgrade -y
+

+

Grafanaバージョン確認 +

grafana-server -v
+

+
+

Version 10.1.2 (commit: 8e428858dd, branch: HEAD)
+バージョンは実施時期によって変動します。

+
+

以上です。

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/grafana-security/index.html b/operation/grafana-security/index.html new file mode 100644 index 00000000..be4c303a --- /dev/null +++ b/operation/grafana-security/index.html @@ -0,0 +1,3223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Grafanaセキュリティ強化 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

Grafanaセキュリティ強化設定

+
+

概要

+

このマニュアルではGrafanaのリモートアクセスセキュリティを強化するためHTTPS化とリバースプロキシの導入設定を行います。

+
+

■事前確認

+

以下の手順は、9.監視ツールセットアップでGrafanaを導入した既存のリレーサーバーで実施可能です。

+

~作業の流れ~

+
    +
  1. 独自ドメイン(サブドメイン)を取得
    +  ※無料ドメイン取得手順も掲載
  2. +
  3. WEBサーバーnginxのインストール・リバースプロキシ設定
  4. +
  5. certbotをインストール
  6. +
  7. 無料SSL証明書(Let’s Encrypt)を取得
  8. +
  9. nginx設定変更
  10. +
  11. SSL証明書自動更新を設定
  12. +
+
+

作業前の注意事項

+

以下の文章をよく読みながら進めてください。コマンドの実行忘れ・コマンドコピーミスなどに十分注意してください。

+
+

1.ドメイン(サブドメイン)を取得する

+
+

確認

+

ホームページなどの運用ですでに独自ドメインを取得済みの場合はそちらを使用出来ます。独自ドメインをお持ちでない方は無料ダイナミックDNSでドメインを取得できます。

+
+
+
+
+

独自ドメインをお持ちの方は、登録レジストラのDNS設定でGrafana用サブドメインを設定してください。

+

参考)
+ホスト名:任意のサブドメイン名
+TYPE:A
+VALUE(値):リレーサーバーIPアドレス
+

+
+
+

DDNS Nowで無料のドメインを取得します。 +DDNS Nowは完全無料・定期通知不要・サービス保障稼働率100%など、使いやすいDDNSサービスです。ただしサブドメインなどは設定できません。1アカウント1ドメイン

+

ドメイン(アカウント)を取得する
+ここで取得したサブドメインがGrafanaのURLになります。

+

例)grafana-abc.f5.si
+

+

詳細設定からDNSのAレコードを設定する
+「Aレコード(IPv4アドレス)」欄にGrafanaを導入しているサーバーのIPアドレスを入力して「設定を変更する」をクリックしてください +

+

登録情報確認
+

+
+
+
+

2.nginxをインストールする

+

sudo apt install nginx -y
+
+ステータス確認 +
sudo systemctl --no-pager status nginx
+

+
+

緑色で「active (running)」になっていることを確認する。

+
+

HTTP/HTTPS用ポートを開放する +

sudo ufw allow 80/tcp
+sudo ufw allow 443/tcp
+

+

開放中のGrafana用3000ポートを削除する
+numbered で表示された3000ポートの番号を指定して削除してください。 +

sudo ufw status numbered
+sudo ufw delete 番号
+

+

ufwをリロードする +

sudo ufw reload
+

+
+

確認

+

ローカルブラウザから http://リレーIPアドレス にアクセスして
+Nginx Welcomeページが表示されればOK!
+

+
+

xxxx.bbb.com[1.ドメイン(サブドメイン)を取得する]で取得したドメイン(サブドメイン)に置き換えて実行する

+
domain=xxxx.bbb.com
+
+

仮想ホストファイルを作成する +

sudo cat > $HOME/$domain.conf << EOF
+server { 
+    listen 80;
+    server_name $domain;
+
+    location / {
+    proxy_set_header Host \$http_host;
+    proxy_pass http://localhost:3000;
+    } 
+}
+EOF
+

+

仮想ホストファイルをnginxフォルダへ移動する +

sudo mv $HOME/$domain.conf /etc/nginx/sites-enabled/
+

+

nginxを再起動する +

sudo systemctl restart nginx
+

+
+

確認

+

ローカルブラウザからhttp://ドメイン名でアクセスし、Grafanaログイン画面が表示されればリバースプロキシ設定に成功しました!

+
+

デフォルトのホストファイルを削除する +

sudo rm /etc/nginx/sites-enabled/default
+

+

3.certbotをインストールする

+
sudo snap install core; sudo snap refresh core
+
+
+

「Download snap "core" (14784) from channel "stable"」と表示され、ダウンロードに数分かかります。

+
+
+戻り値メッセージが異なる場合(クリックして開く) +
+
+
+
snap "core" is already installed, see 'snap help refresh'
+snap "core" has no updates available
+
+

このメッセージはインストール済みです。次に進んでください。

+
+
+

sudo: snap: command not found 
+sudo: snap: command not found
+
+このメッセージはsnapがインストールされていません。
+以下のコマンドでインストールしてください。

+
sudo apt update -y
+sudo apt install snapd -y
+
+

snapのインストールが完了したら以下を実行してください。

+
sudo snap install core; sudo snap refresh core
+
+

<戻り値> +

「Download snap "core" (14784) from channel "stable"」 
+
+2023-02-24T10:18:49+01:00 INFO Waiting for automatic snapd restart...
+core 16-2.58.2 from Canonical✓ installed
+snap "core" has no updates available
+

+

と表示されたら次に進んでください。

+
+
+
+
+
sudo snap install --classic certbot
+
+
+

「Download snap "core20" (1822) from channel "stable」と表示され、ダウンロードに数分かかります

+
+

certbotをシステムフォルダへコピーする +

sudo ln -s /snap/bin/certbot /usr/bin/certbot
+

+

4.無料SSL証明書(Let’s Encrypt)を取得する

+
sudo certbot --nginx
+
+

画面上の質問に回答します。

+
    +
  1. +

    任意のメールアドレスの登録
    +ここで登録したメールアドレスにSSL証明書更新前・期限切れ情報の通知が届きます。
    +

    +
  2. +
  3. +

    Let's Encryptサービス利用規約への同意確認
    +

    +
  4. +
  5. +

    キャンペーンメール登録確認(不要ならN)
    +

    +
  6. +
  7. +

    SSL証明書登録ドメインの確認
    +1:にご自身のドメインが表示されていることを確認し、1を入力
    +

    +
  8. +
  9. +

    SSL証明書取得確認
    +This certificate expires onは取得したSSL証明書の有効期限なので覚えておきましょう!
    +
    +Congratulations!が表示されていれば署名書取得成功です!

    +
  10. +
+
+

確認

+

ローカルブラウザからhttps://ドメイン名でアクセスし、Grafanaログイン画面が表示されればHTTPS化に成功しました!
+ドメインでアクセスした際のURL欄において、httpの後にsがついているかどうかをチェックしてください。

+
+

5.nginx設定変更

+

1.websocketを有効にする
+xxxx.bbb.com[1.ドメイン(サブドメイン)を取得する]で取得したドメイン(サブドメイン)に置き換えて実行する +

domain=xxxx.bbb.com
+

+

仮想ホストファイルを開く +

sudo nano /etc/nginx/sites-enabled/$domain.conf
+

+

location /ブロックを以下の内容に書き換える +

    location / {
+    proxy_set_header Host $http_host;
+    proxy_pass http://localhost:3000;
+    }
+
+    location /api/live {
+    proxy_http_version 1.1;
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection $connection_upgrade;
+    proxy_set_header Host $http_host;
+    proxy_pass http://localhost:3000;
+    }
+

+

編集後参考)
+

+

追記したら保存して閉じる

+

2.nginx 構成ファイルの強化 +設定ファイルを開く +

sudo nano /etc/nginx/nginx.conf
+

+

SSL SettingsTLSv1TLSv1.1を削除する
+編集後参考)
+

+

続けて、以下の文を全てコピーしてinclude /etc/nginx/site-enabled/*;の後に追記する
+

        ## Start: Size Limits & Buffer Overflows ##
+        client_body_buffer_size  3K;
+        client_header_buffer_size 3k;
+        client_max_body_size 80k;
+        large_client_header_buffers 2 10k;
+        ## END: Size Limits & Buffer Overflows ##
+
+        ### Directive describes the zone, in which the session states are stored i.e. store in slimits. ###
+        ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ###
+        limit_conn_zone $binary_remote_addr zone=addr:5m;
+
+        ### Control maximum number of simultaneous connections for one session i.e. ###
+        ### restricts the amount of connections from a single ip address ###
+        limit_conn addr 10;
+
+        map $http_upgrade $connection_upgrade {
+            default upgrade;
+            ''      close;
+        }
+

+

赤枠の } の位置に注意してください。
+編集後参考) +

+

追記したら保存して閉じる

+

nginxエラーチェック +

sudo nginx -t
+

+
+

戻り値

+
+
+
+
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
+nginx: configuration file /etc/nginx/nginx.conf test is successful
+
+
+
+

nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/******.conf:8
+nginx: configuration file /etc/nginx/nginx.conf test failed
+
+エラー箇所を修正してください。

+
+
+
+
+

nginxを再起動する +

sudo systemctl restart nginx
+

+

6.SSL証明書自動更新

+

1.SSL証明書自動更新タイマー確認
+このプログラムでSSL証明書が自動更新されます。 +

systemctl status snap.certbot.renew.timer
+

+
+

緑色で「active(wating)」になっていることを確認する。

+
+

2.nginx自動起動スクリプト +自動更新されたSSL証明書を有効にするため、nginx再起動スクリプトを設定します。 +

cat > $HOME/nginx-reload.sh << EOF
+#!/bin/bash 
+sudo systemctl reload nginx
+EOF
+
+
sudo mv $HOME/nginx-reload.sh /etc/letsencrypt/renewal-hooks/deploy/
+
+
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/nginx-reload.sh
+

+

3.指定ユーザーと指定コマンドでsudoパスワード要求を無効にする
+シェルスクリプト内でsudoコマンドを使用しているため、スクリプト自動実行にパスワード要求をスルー出来るように設定します。

+

ログインユーザー名を確認する(控える) +

whoami
+
+sudo設定ファイルを開く +
sudo visudo
+
+以下コマンドのxxxxを、上記で調べたログインユーザー名に書き換えて追記する +
xxxx ALL=NOPASSWD: /bin/systemctl
+

+
+

このまま追記しないでください。xxxxをユーザー名に書き換えてください

+
+

編集後参考) +

+

追記したら保存して閉じる

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/kes-update/index.html b/operation/kes-update/index.html new file mode 100644 index 00000000..5cbc3f08 --- /dev/null +++ b/operation/kes-update/index.html @@ -0,0 +1,3302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1-1.KESの更新 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

KESの更新

+
+

概要

+

(KES=Key Evolving Signature)の略
+キーを悪用するハッカーからステークプールを保護するために作成され、90日ごとに再生成する必要があります。有効期限が切れる前に更新してください。期限内ならいつ更新しても問題ありません。

+

以下の手順は、全て手作業で更新する方法です。

+

KES更新は、半自動更新が可能なSJG TOOLを推奨します。

+
+
+

注意

+
    +
  • KESの有効期限が切れると、ブロック生成が出来なくなりますので期限が切れる前に以下の手順で更新してください。
  • +
  • 1.35.xからカウンター番号更新のレギュレーションが変更になりました。
    + --必ず自プールのオンチェーンカウンター番号+1 で更新する必要があります。
    + --オンチェーンにまだ自プールが生成したブロックがない場合は毎回0で更新します。
  • +
+
+

■KES更新の流れ
+0.BP:KES更新タイミングを確認する
+1.BP:新しいKESファイルを生成する
+2.BP:KESファイル(kes.skey/kes.vkey)をエアギャップのcnodeディレクトリへコピーする
+3.BPとエアギャップでkes.vkeyファイルハッシュを比較する
+4.BP:オンチェーンカウンター番号を算出する。
+5.エアギャップ: node.counterを生成する
+6.BP:現在のKesPeriodを算出する +7.エアギャップ:node.certを生成する (1で算出したKesPeriodを使うこと)
+8.エアギャップ:node.certファイルをBPのcnodeディレクトリへコピーする
+9.BPとエアギャップでnode.certファイルハッシュを比較する
+10.BP:ノードを再起動する

+

0.KES更新タイミングチェック

+
+
+
+
slotNumInt=`curl -s http://localhost:12798/metrics | grep cardano_node_metrics_slotNum_int | awk '{ print $2 }'`
+echo "scale=6; ${slotNumInt} / 129600" | bc | awk '{printf "%.5f\n", $0}'
+
+
+

戻り値の小数点以下が.99800付近の場合、startKesPeriodの切り替わりが近いため、切り替わってから以下の作業を進めてください。

+
+
+
+
+

1.KESファイル作成

+

既存ファイルバックアップ

+
+
+
+
cp $NODE_HOME/kes.vkey $NODE_HOME/kes-bk.vkey
+cp $NODE_HOME/kes.skey $NODE_HOME/kes-bk.skey
+cp $NODE_HOME/node.cert $NODE_HOME/node-bk.cert
+
+

KESファイル新規作成 +

cardano-cli node key-gen-KES \
+    --verification-key-file $NODE_HOME/kes.vkey \
+    --signing-key-file $NODE_HOME/kes.skey
+

+
+
+
+

2.KESファイルをAGにコピー

+

KESファイル(kes.skey/kes.vkey)をエアギャップのcnodeディレクトリへコピーする

+
+

ファイル転送

+

BPにあるkes.skey/kes.vkeyをエアギャップオフラインマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|kes.skey / kes.vkey| B[エアギャップ];

+
+

3.ハッシュ値確認

+

BPとエアギャップでkes.vkeyファイルハッシュを比較する

+
+
+
+
+
+
cd $NODE_HOME
+sha256sum kes.vkey
+
+
+
+
+
+
+
cd $NODE_HOME
+sha256sum kes.vkey
+
+
+

確認

+

BPとエアギャップで表示された戻り値を比較して、ハッシュ値が一致していればOK

+
+

4.オンチェーンカウンター取得

+
+
+
+
kesperiodinfo=$(cardano-cli query kes-period-info $NODE_NETWORK --op-cert-file $NODE_HOME/node.cert --out-file kesperiod.json)
+lastBlockCnt=`cat kesperiod.json | jq -r '.qKesNodeStateOperationalCertificateNumber'`
+
+if expr "$lastBlockCnt" : "[0-9]*$" >&/dev/null; then
+echo '----------------------------------------------'
+echo オンチェーンカウンター番号は: $lastBlockCnt です。
+echo 更新カウンター番号は $(($lastBlockCnt+1)) です。
+echo '---------------------------------------------'
+else
+echo '----------------------------'
+echo まだブロックを生成していません。
+echo 更新カウンター番号は: "0" です。
+echo '----------------------------'
+fi
+rm kesperiod.json
+
+
+

↑このままコピーしてコマンドに入力してください

+
+
+
+
+

5.カウンターファイル生成

+
+
+
+
cd $NODE_HOME
+read -p "BPで算出した更新カウンター番号を入力してください:" cnt_No
+
+
+

↑このままコピーしてコマンドに入力してください
+コマンド実行後に、数字入力モードになりますので
+項目5で確認した、更新カウンター番号を入力します

+
+
chmod u+rwx $HOME/cold-keys
+cardano-cli node new-counter \
+  --cold-verification-key-file $HOME/cold-keys/node.vkey \
+  --counter-value $cnt_No \
+  --operational-certificate-issue-counter-file $HOME/cold-keys/node.counter
+
+

カウンター番号が正しく生成されているか確認する +

cardano-cli text-view decode-cbor \
+ --in-file  $HOME/cold-keys/node.counter \
+  | grep int | head -1 | cut -d"(" -f2 | cut -d")" -f1
+

+
+

上記コマンド実行の戻り値が「入力した更新カウンター番号」であることを確認してください

+
+
+
+
+

6.BPで現在のKesPeriod算出

+
+
+
+
cd $NODE_HOME
+slotNo=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+slotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')
+kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))
+startKesPeriod=${kesPeriod}
+echo startKesPeriod: ${startKesPeriod}
+
+
+
+
+

7.node.cert生成

+

次のコマンドで、新しい node.certファイルを作成します。

+
+
+
+
cd $NODE_HOME
+read -p "BPで算出したstartKesPeriodを入力してください:" kes
+
+
+

↑このままコピーしてコマンドに入力してください
+コマンド実行後に、数字入力モードになりますので
+そこで1で算出したstartKesPeriodの数字を入力します

+
+
+
+
+
echo "入力した数字は$kesです"
+
+
+

入力した数字が戻り値に表示されているかご確認ください

+
+
chmod u+rwx $HOME/cold-keys
+cardano-cli node issue-op-cert \
+    --kes-verification-key-file $NODE_HOME/kes.vkey \
+    --cold-signing-key-file $HOME/cold-keys/node.skey \
+    --operational-certificate-issue-counter $HOME/cold-keys/node.counter \
+    --kes-period $kes \
+    --out-file $NODE_HOME/node.cert
+chmod a-rwx $HOME/cold-keys
+
+
+

ヒント

+

コールドキーへのアクセス権限を変更しセキュリティを向上させることができます。これによって誤削除、誤った編集などから保護できます。

+

ロックするには

+
chmod a-rwx $HOME/cold-keys
+
+

ロックを解除するには

+

chmod u+rwx $HOME/cold-keys
+

+
+

8.node.certをBPへコピー

+

エアギャップ:node.certファイルをBPのcnodeディレクトリへコピーする

+
+

ファイル転送

+

エアギャップにあるnode.certをBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|node.cert| B[BP];

+
+

9.ハッシュ値確認

+

BPとエアギャップでnode.certファイルハッシュを比較する

+
+
+
+
cd $NODE_HOME
+sha256sum node.cert
+
+
+
+
cd $NODE_HOME
+sha256sum node.cert
+
+
+
+
+
+

ノード

+

BPとエアギャップで表示された戻り値を比較して、ハッシュ値が一致していればOK

+
+

10.ノード再起動

+

この手順を完了するには、ブロックプロデューサーノードを停止して再起動します。

+
+
+
+
sudo systemctl reload-or-restart cardano-node
+
+

gLiveviewでノード同期を確認する +

glive
+

+
+10分以上経過しても同期しない場合はこちら +

KES更新に失敗している可能性があるため、バックアップファイルから復元してください。 +ノード停止 +

sudo systemctl stop cardano-node
+
+ファイル復元 +
mv $NODE_HOME/kes-bk.vkey $NODE_HOME/kes.vkey
+mv $NODE_HOME/kes-bk.skey $NODE_HOME/kes.skey
+mv $NODE_HOME/node-bk.cert $NODE_HOME/node.cert
+
+ノード起動 +
sudo systemctl start cardano-node
+
+同期状況確認 +
glive
+

+
+
+
+
+

11.チェックプログラム実行

+

SPO JAPAN GUILD TOOLを実行する

+
gtool
+
+
+

[2] ブロック生成状態チェック を選択する

+
+

SPO JAPAN GUILD TOOLの導入はこちらをご参照ください

+

12.バックアップファイル削除

+

上記でブロック生成状態の確認がすべてOKだった場合、KESバックアップファイルを削除してください

+
rm $NODE_HOME/kes-bk.vkey
+rm $NODE_HOME/kes-bk.skey
+rm $NODE_HOME/node-bk.cert
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/mithril-client/index.html b/operation/mithril-client/index.html new file mode 100644 index 00000000..ffccb027 --- /dev/null +++ b/operation/mithril-client/index.html @@ -0,0 +1,3105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2-2.DB同期(Mithril) - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

DB同期ブートストラップ(Mithrilベータ版)

+
+

概要

+
    +
  • このマニュアルではMithril-Clientを使用したcardano-node DB同期ブートストラップを実行します。
  • +
  • ノード初回起動時のDB同期時間を約2日から約30分以内にまで短縮できます。
  • +
  • Mithrilプロトコルはまだベータバージョンのため、ご自身の責任で実施してください。
  • +
  • この作業は 2.ノードインストールの2-1~2-7まで実施してから行って下さい。
  • +
  • スナップショットノードバージョンとサーバーノードバージョンが異なる場合、DB再構築処理が入る場合がありDB同期までに数時間かかります。
  • +
+
+

1.依存環境インストール

+

1-1. システムアップデート

+

ノード停止 +

sudo systemctl stop cardano-node
+
+システムアップデート +
sudo apt update -y && sudo apt upgrade -y
+
+依存環境インストール +
sudo apt install -y libssl-dev build-essential m4 jq
+

+

1-2. Rustインストール

+
+

確認

+

Rustがインストールされている場合、この項目は実施不要です。 +

rustc -V
+

+
+

Command 'rustc' not found, but can be installed with:の戻り値がある場合は、以下の作業を実施して下さい。

+
+
+

RUST環境を準備します +

mkdir $HOME/.cargo && mkdir $HOME/.cargo/bin
+chown -R $USER $HOME/.cargo
+touch $HOME/.profile
+chown $USER $HOME/.profile
+

+

rustupインストール +

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+

+
+

1) Proceed with installation (default) 1を入力してEnter

+
+
source $HOME/.cargo/env
+
+
rustup install stable
+rustup default stable
+rustup update
+rustup component add clippy rustfmt
+rustup target add x86_64-unknown-linux-musl
+
+

2.Mithril-Clientインストール

+
cd $HOME/git
+git clone https://github.com/input-output-hk/mithril.git
+
+
cd mithril
+git fetch --all --prune
+git checkout tags/2347.0
+
+

ビルド +

cd mithril-client-cli
+make build
+

+

バージョン確認 +

./mithril-client -V
+

+
+

mithril-client 0.5.5

+
+

システムフォルダへコピー +

sudo mv mithril-client /usr/local/bin/mithril-client
+

+

バージョン確認 +

mithril-client -V
+

+
+

mithril-client 0.5.5

+
+

3.DBブートストラップ

+

3-1.変数セット

+
export NETWORK=mainnet
+export AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator
+export GENESIS_VERIFICATION_KEY=$(wget -q -O - https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/release-mainnet/genesis.vkey)
+export SNAPSHOT_DIGEST=latest
+
+

3-2.最新スナップショットDL

+

既存DBフォルダ削除 +

rm -rf $NODE_HOME/db
+

+

tmux作業ウィンドウを作成する +

tmux new -s mithril
+

+

最新スナップショットダウンロード及び解凍 +

mithril-client snapshot download --download-dir $NODE_HOME latest
+

+
+

スナップショットダウンロード~解凍まで自動的に行われます。1/6~6/6が終了するまで待ちましょう

+
+

tmux作業ウィンドウを終了する +

exit
+

+
+その他のmithril-clientコマンド +

Cardanoノードをブートストラップできる利用可能なスナップショットを一覧表示 +

mithril-client snapshot list
+

+

戻り値 +

+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| Epoch | Immutable | Network | Digest                                                           | Size        | Locations | Created                           |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4822      | mainnet | dfc05780e0aaefc0e0466cbf69f3c82561e99f8b208626b9870a2e69344199dc | 40337208527 |         1 | 2023-09-27 05:21:39.339429454 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4821      | mainnet | bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3 | 40328088621 |         1 | 2023-09-26 23:13:39.908538941 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4820      | mainnet | d993a6267fefa1c34c0f270337dc3fa5324bc399f908e4a38ec80bb3348e8fe1 | 40320340866 |         1 | 2023-09-26 17:31:56.927673920 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4819      | mainnet | f8dd9c7ee08c6dffebe851a19af44bcb82990d4c174dc366dfaa18e40c20b842 | 40316728370 |         1 | 2023-09-26 11:50:50.123658352 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4818      | mainnet | 70c5c6847116d0a4ca93f81ac193db9d2a17084065963ae298646a157825ab7e | 40314024073 |         1 | 2023-09-26 05:44:57.236767751 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4817      | mainnet | 0597ca3e7d699155ce73aaae53805ea32a981ff213f772dd70e9dbead626acf2 | 40299093577 |         1 | 2023-09-25 23:13:32.500760943 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+| 438   | 4816      | mainnet | 074a576bce34006369837899ecdaaac69f18e31dd193aaa5527d32a7c36fb10e | 40285275527 |         1 | 2023-09-25 17:33:02.562751472 UTC |
++-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+
+

+

スナップショット詳細表示 +

mithril-client snapshot show (Digestハッシュ値指定)
+
+戻り値 +
+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Info                  | Value                                                                                                                                                                         |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Epoch                 | 438                                                                                                                                                                           |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Immutable File Number | 4821                                                                                                                                                                          |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Network               | mainnet                                                                                                                                                                       |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Digest                | bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3                                                                                                              |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Size                  | 40328088621                                                                                                                                                                   |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Cardano node version  | 8.1.2                                                                                                                                                                         |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Location 1            | https://storage.googleapis.com/cdn.aggregator.release-mainnet.api.mithril.network/mainnet-e438-i4821.bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3.tar.zst |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Created               | 2023-09-26 23:13:39.908538941 UTC                                                                                                                                             |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Compression Algorithm | Zstandard                                                                                                                                                                     |
++-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+

+
+

4.ノード起動

+
sudo systemctl start cardano-node
+
+

ノード同期確認

+

gliveviewを起動し、最新ブロックと同期していることを確認する +

glive
+

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/node-update/index.html b/operation/node-update/index.html new file mode 100644 index 00000000..dc7227d0 --- /dev/null +++ b/operation/node-update/index.html @@ -0,0 +1,4147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2-1.ノードアップデート - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

ノードアップデートマニュアル

+
+

概要

+

このガイドは ノードバージョン8.7.3に対応しています。最終更新日:2024年1月26日

+ + + + + + + + + + + + + + + + + + + +
NodeCLIGHCCabalCNCLI
8.7.38.17.0.08.10.73.8.1.06.0.1
+
    +
  • よくお読みになって進めてください
  • +
  • 複数行のコードをコードボックスのコピーボタンを使用してコマンドラインに貼り付ける場合は、最後の行が自動実行されないため確認の上Enterを押してコードを実行してください。
  • +
+
+
+

主な変更点と新機能

+

■cardano-node v8.7.3

+
    +
  • 8.1.2以前からのダイナミックP2Pの潜在的なバグが解消されています。
  • +
  • RAM 24GB以上必須
  • +
+

■ビルド済みバイナリの使用

+
    +
  • SJGではこれまでソースコードからビルドしてきましたが、検証体制が整ったことで安全性・安定性を十分に確認できるためビルド時間工数削減を目的にIntersectMBO(旧IOG)発行のビルド済みバイナリを使用したインストールを採用を採用します。 +これにより、これまで約30分前後かかっていたバイナリファイル作成のビルド時間を省略できます。
  • +
+

■Mithrilブートストラップの導入

+
    +
  • +

    Mithrilクライアントを用いてDBスナップショットからブートストラップします。
    +8.1.2以前のバージョンから8.7.3へのバージョンアップはDB再構築処理が入るため、ノード同期までに6時間~7時間かかりますがこのブートストラップを導入することで約20分で同期することが可能になります。

    +
  • +
  • +

    ビルド済みバイナリの使用+Mithrilブートストラップを使用した場合、アップデート全工程所要時間は1サーバーにつき約30分~40分ですべて完了します。

    +
  • +
+
+ + +

1.依存環境アップデート

+

1-1. システムアップデート

+

システムアップデート +

sudo apt update -y && sudo apt upgrade -y
+

+

1-2. cabal/GHCバージョン確認

+

cabalパス確認 +

which cabal
+

+
+

/home/user/.ghcup/bin/cabal なら正常

+
+

cabalバージョン確認 +

cabal --version
+

+
+

以下の戻り値ならOK
+cabal-install version 3.8.1.0
+compiled using version 3.8.1.0 of the Cabal library

+
+

GHCバージョン確認 +

ghc --version
+

+
+

現在のGHCのバージョンは「8.10.7」
+GHC9はベンチマークテストが終わってないため今ノードバージョンでは非推奨

+
+

libsodiumコミット確認 +

cd $HOME/git/libsodium
+git branch --contains | grep -m1 HEAD | cut -c 21-28
+

+
+

戻り値が dbb48cce ならOK

+
+
+各アプリのバージョンが異なる場合 +
+戻り値が[/home/user/.local/bin/cabal]だった場合 +

戻り値が[/home/user/.local/bin/cabal]だった場合のみ以下を実行

+

パスを追加する +

echo PATH=$PATH:$HOME/.ghcup/bin >> $HOME/.bashrc
+source $HOME/.bashrc
+

+

旧cabalリネーム +

cd $HOME/.local/bin/
+mv cabal cabal_bk
+

+
+
+cabal 3.6.2.0以下だった場合 +

cabal 3.6.2.0以下だった場合のみ実行 +cabalバージョンアップ +

ghcup upgrade
+ghcup install cabal 3.8.1.0
+ghcup set cabal 3.8.1.0
+
+cabalバージョン確認 +
cabal --version
+

+
+

以下の戻り値ならOK
+cabal-install version 3.8.1.0
+compiled using version 3.8.1.0 of the Cabal library

+
+
+
+GHC 8.10.4以下だった場合 +

GHC 8.10.4以下だった場合のみ実行 +

ghcup upgrade
+ghcup install ghc 8.10.7
+ghcup set ghc 8.10.7
+
+
ghc --version
+

+
+

GHCのバージョンは「8.10.7」であればOK

+
+
+
+libsodiumコミット値が違う場合 +
cd ~/git/libsodium
+git fetch --all --prune
+git checkout dbb48cc
+./autogen.sh
+./configure
+make
+make check
+sudo make install
+
+
+

makeコマンド実行後半に出現する warning は無視して大丈夫です。

+
+
+
+ + + + +

1-3.blstインストール

+

blstダウンロード +

cd $HOME/git
+git clone https://github.com/supranational/blst
+cd blst
+git checkout v0.3.10
+./build.sh
+

+

設定ファイル作成

+
+

このボックスはすべてコピーして実行してください

+
+
cat > libblst.pc << EOF
+prefix=/usr/local
+exec_prefix=\${prefix}
+libdir=\${exec_prefix}/lib
+includedir=\${prefix}/include
+
+Name: libblst
+Description: Multilingual BLS12-381 signature library
+URL: https://github.com/supranational/blst
+Version: 0.3.10
+Cflags: -I\${includedir}
+Libs: -L\${libdir} -lblst
+EOF
+
+

設定ファイルコピー

+
+

このボックスは1行ずつコピーして実行してください

+
+
sudo cp libblst.pc /usr/local/lib/pkgconfig/
+sudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp  /usr/local/include/
+sudo cp libblst.a /usr/local/lib
+sudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}
+
+

1-4.CNCLIバージョン確認(BPのみ)

+

CNCLIバージョン確認 +

cncli --version
+

+
+

以下の戻り値ならOK
+cncli 6.0.1

+
+
+cncli v6.0.0以下だった場合(クリックして開く) +

CNCLIをアップデートする

+
rustup update
+cd $HOME/git/cncli
+git fetch --all --prune
+git checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)
+cargo install --path . --force
+
+

バージョン確認 +

cncli --version
+

+
+

cncli 6.0.1になったことを確認する

+
+
+

2.ノードアップデート

+
+

バイナリファイルインストール方法の違いについて

+
    +
  • ビルド済みバイナリ・・・IntersectMBO(旧IOG)リポジトリソースコードからビルドされたバイナリファイルをダウンロードします。ビルド不要のためビルド時間を短縮できます。
  • +
  • ソースコードからビルド・・・ご自身のサーバーでソースコードからビルドしてバイナリファイルを作成します。検証目的やソースコードからビルドしたい場合に利用できます。ビルドに30分前後かかります。
  • +
+

どちらも同じソースコードからビルドされたバイナリファイルなので安定性・安全面に差異はございません。お好みの方法でインストールして頂けます。

+
+
+
+
+

2-1.バイナリダウンロード

+

旧バイナリを削除する +

rm -rf $HOME/git/cardano-node-old/
+

+

バイナリファイルをダウンロードする +

mkdir $HOME/git/cardano-node2
+cd $HOME/git/cardano-node2
+wget https://github.com/IntersectMBO/cardano-node/releases/download/8.7.3/cardano-node-8.7.3-linux.tar.gz
+

+

解凍する +

tar zxvf cardano-node-8.7.3-linux.tar.gz ./cardano-node ./cardano-cli
+

+

バージョン確認

+

$(find $HOME/git/cardano-node2 -type f -name "cardano-cli") version  
+$(find $HOME/git/cardano-node2 -type f -name "cardano-node") version  
+
+以下の戻り値を確認する

+
+

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+
+

ノードをストップする +

sudo systemctl stop cardano-node
+

+

2-2.バイナリインストール

+

バイナリーファイルをシステムフォルダーへコピーする

+
sudo cp $(find $HOME/git/cardano-node2 -type f -name "cardano-cli") /usr/local/bin/cardano-cli
+
+
sudo cp $(find $HOME/git/cardano-node2 -type f -name "cardano-node") /usr/local/bin/cardano-node
+
+
+
+

2-1.ソースコードダウンロード

+

新しいTMUXセッションを開く

+
tmux new -s build
+
+
+

アップデート作業中にSSHが中断した場合は、tmux a -t buildで再開できます。

+
+

旧ビルドを削除する +

rm -rf $HOME/git/cardano-node-old/
+

+

ソースコードをダウンロードする +

cd $HOME/git
+git clone https://github.com/IntersectMBO/cardano-node.git cardano-node2
+cd cardano-node2/
+

+

2-2.ソースコードからビルド

+
cabal clean
+cabal update
+
+
git fetch --all --recurse-submodules --tags
+git checkout tags/8.7.3
+cabal configure --with-compiler=ghc-8.10.7
+
+ + +
cabal build cardano-node cardano-cli
+
+
+

ヒント

+
    +
  • ビルド完了までに数十分ほどかかります。
  • +
  • SSH接続が途中で切断された場合、再度接続してtmux a -t buildで再開してください。
  • +
  • ビルド中にデタッチ(Ctrl+B D)してバックグラウンド処理へ切り替えられます。
  • +
+
+

バージョン確認

+

$(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name "cardano-cli") version  
+$(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name "cardano-node") version  
+
+以下の戻り値を確認する

+
+

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+
+

ビルド用TMUXセッションを終了する +

exit
+

+

ノードをストップする +

sudo systemctl stop cardano-node
+

+

バイナリーファイルをシステムフォルダーへコピーする

+
sudo cp $(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name "cardano-cli") /usr/local/bin/cardano-cli
+
+
sudo cp $(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name "cardano-node") /usr/local/bin/cardano-node
+
+
+
+
+

システムに反映されたノードバージョンを確認する

+
cardano-cli version
+cardano-node version
+
+

以下の戻り値を確認する

+
+

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+
+

2-3.設定ファイルの追加と更新

+

既存ファイルバックアップ +

mkdir $NODE_HOME/backup
+cp $NODE_HOME/${NODE_CONFIG}-config.json $NODE_HOME/backup/${NODE_CONFIG}-config.json
+cp $NODE_HOME/${NODE_CONFIG}-conway-genesis.json $NODE_HOME/backup/${NODE_CONFIG}-conway-genesis.json\n
+

+

新ファイルダウンロード +

cd $NODE_HOME
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/conway-genesis.json -O ${NODE_CONFIG}-conway-genesis.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/config.json -O ${NODE_CONFIG}-config.json
+

+

設定ファイルを書き換える

+
+

運用中のP2P形式を調べる方法

+
cat mainnet-topology.json | grep localRoots
+
+
    +
  • 戻り値がない場合・・・手動P2P運用
  • +
  • "localRoots": [の戻り値がある場合・・・ダイナミックP2P
  • +
+
+
+
+
+
sed -i ${NODE_CONFIG}-config.json \
+    -e '2i \  "SnapshotInterval": 86400,' \
+    -e 's!"EnableP2P": true!"EnableP2P": false!' \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e 's!"rpKeepFilesNum": 10!"rpKeepFilesNum": 30!' \
+    -e 's!"rpMaxAgeHours": 24!"rpMaxAgeHours": 48!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+
+
sed -i ${NODE_CONFIG}-config.json \
+    -e '2i \  "SnapshotInterval": 86400,' \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e 's!"rpKeepFilesNum": 10!"rpKeepFilesNum": 30!' \
+    -e 's!"rpMaxAgeHours": 24!"rpMaxAgeHours": 48!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+
+
+
+テストネットの場合はこちら +
+
+
+
sed -i ${NODE_CONFIG}-config.json \
+    -e 's!"EnableP2P": true!"EnableP2P": false!' \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+
+
sed -i ${NODE_CONFIG}-config.json \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+
+
+
+

3.Mithrilクライアント設定

+

3-1. インストール

+
cd $HOME/git
+mithril_release="$(curl -s https://api.github.com/repos/input-output-hk/mithril/releases/latest | jq -r '.tag_name')"
+wget https://github.com/input-output-hk/mithril/releases/download/${mithril_release}/mithril-${mithril_release}-linux-x64.tar.gz -O mithril.tar.gz
+
+

設定 +

tar zxvf mithril.tar.gz mithril-client
+sudo cp mithril-client /usr/local/bin/mithril-client
+
+パーミッション設定 +
sudo chmod +x /usr/local/bin/mithril-client
+

+

DLファイル削除 +

rm mithril.tar.gz mithril-client
+

+

バージョン確認 +

mithril-client -V
+

+
+

mithril-client 0.5.17+254d266

+
+

3-2.スナップショット復元

+

作業用TMUX起動 +

tmux new -s mithril
+

+

変数セット +

export NETWORK=mainnet
+export AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator
+export GENESIS_VERIFICATION_KEY=$(wget -q -O - https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/release-mainnet/genesis.vkey)
+export SNAPSHOT_DIGEST=latest
+

+
+旧dbをバックアップしたい方はこちら +
+

空き容量に関しての注意事項

+

DBをバックアップする場合、サーバーディスクの空き容量をご確認ください。 +安定稼働のためには250GB以上の空き容量が必要です。 +

df -h /usr | awk '{print $4}'
+
+Availが250GB以上あることを確認してください。

+
+

dbをリネームする +

mv $NODE_HOME/db/ $NODE_HOME/backup/db8-1-2/
+

+

ノードバージョンアップ後、稼働に問題がないことが確認できれば削除することをお勧めます +

rm -rf $NODE_HOME/backup/db8-1-2/
+

+
+

既存DB削除 +

rm -rf $NODE_HOME/db
+

+

最新スナップショットDL +

mithril-client snapshot download --download-dir $NODE_HOME latest
+

+
+

スナップショットダウンロード~解凍まで自動的に行われます。1/5~5/5が終了するまで待ちましょう
+5/5 - Verifying the snapshotsignature…
+Snapshot 'xxxxx' has been unpacked and successfully checked against Mithril multi-signature contained in the certificate. +('xxxxx'は作業時期によって変わります。下の文字列は無視して大丈夫です)

+
+

tmux作業ウィンドウを終了する +

exit
+

+

3-3.サーバー再起動

+

作業フォルダリネーム

+

前バージョンで使用していたバイナリフォルダをリネームし、バックアップとして保持します。最新バージョンを構築したフォルダをcardano-nodeとして使用します。

+
cd $HOME/git
+mv cardano-node/ cardano-node-old/
+mv cardano-node2/ cardano-node/
+
+

サーバーを再起動する +

sudo reboot
+

+

SSH接続してDB再構築進捗を確認する +

journalctl --unit=cardano-node --follow
+

+
+

数分経過してもProgress: xx.xx%が表示されない場合、何かが不備でエラーになっています。

+
+

4. サービス起動確認(BPのみ)

+

BPノードが完全に同期した後、サービスを再起動し起動状態を確認する +

sudo systemctl restart cnode-cncli-sync.service
+

+
+

ヒント

+

ノードを再起動してから、約20秒後に5プログラムがバックグラウンドで起動中であればOKです

+
tmux ls
+
+
    +
  • cncli
  • +
  • leaderlog
  • +
  • validate
  • +
  • logmonitor
  • +
  • blockcheck(ブロック生成ステータス通知を導入している場合)
  • +
+
+
tmux a -t cncli
+
+
+

「100.00% synced」になっていることを確認します +100%になったら、Ctrl+bを押した後に d を押し元の画面に戻ります +(バックグラウンド実行に切り替え)

+
+
+Missing eta_v for block xxxxxx エラーが出る場合の対処法 +

cncliを再同期してください

+

rm $NODE_HOME/guild-db/cncli/*
+
+
sudo systemctl restart cnode-cncli-sync.service
+
+
tmux a -t cncli
+
+100% sync'dになるまでお待ち下さい

+
+

5. エアギャップアップデート

+
+

SFTP機能ソフト導入

+

R-loginの転送機能が遅いので、大容量ファイルをダウン・アップロードする場合は、SFTP接続可能なソフトを使用すると効率的です。(FileZilaなど)
+ファイル転送に便利なSFTP機能ソフトの導入手順はこちら

+
+

5-1.バイナリファイルコピー

+
+
+
+

リレーサーバーで以下を実行する

+
sudo cp $(find $HOME/git/cardano-node -type f -name "cardano-cli") ~/cardano-cli
+
+
+
+

リレーサーバーで以下を実行する

+
sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-cli") ~/cardano-cli
+
+
+
+
+

SFTP機能ソフト(Filezillaなど)で転送元サーバーに接続し、以下をダウンロードする

+
    +
  • /home/usr/cardano-cli
  • +
+

をローカルパソコンにダウンロードします
+(エアギャップUbuntuとの共有フォルダ)

+


+

エアギャップマシンにファイルを入れる

+
+
+
+
    +
  • $HOME/git/cardano-node2/ にcardano-cliを入れる
    + (cardano-node2が無ければ作成する)
  • +
+
+
+
+

5-2.インストール

+

エアギャップマシンで以下を実行する

+
+
+
+

cardano-cliをシステムフォルダへコピーする +

sudo cp $(find $HOME/git/cardano-node2 -type f -name "cardano-cli") /usr/local/bin/cardano-cli
+
+ + + + + +

+
+
+
+

5-3.バージョン確認

+
cardano-cli version
+
+

以下の戻り値を確認する

+
+

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+
+
+

確認

+

エアギャップではcardano-nodeは使用しないため転送してもしなくてもOKです。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/p2p-settings/index.html b/operation/p2p-settings/index.html new file mode 100644 index 00000000..4b791fc2 --- /dev/null +++ b/operation/p2p-settings/index.html @@ -0,0 +1,3227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2-4.ダイナミックP2P設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

ダイナミックP2P設定マニュアル

+
+

事前学習のススメ

+

ダイナミックP2P(以下、P2P)はノード同士の接続方式が大きく変更になります。
+変更点をまとめた資料を作成しましたので事前学習をオススメします。資料はこちら

+
    +
  • P2Pはカルダノネットワークチェーン密度の維持と安全性を担保するため、少しずつ切り替えていく方針となります。そのため2023年4月3日時点では複数リレーのうち単一のリレーで実行し非P2Pリレーと一緒に稼働させる必要があります。
  • +
  • BPへの適用は非推奨となっております。
  • +
+
+
+

注意事項

+
    +
  • P2Pへの切り替えは設定ファイルを変更するため、ノードを停止してから作業します。
  • +
  • 以下の手順はリレーノード用です。BPには適用しないでください。
  • +
+
+

1.ノードバージョン確認

+
cardano-node version
+
+
+

ノードバージョン

+

P2Pは1.35.7以上で利用可能です。
+1.35.6以下の場合はノードアップデートマニュアルに添ってバージョンアップをお願いします。

+
+

ノードを停止する +

sudo systemctl stop cardano-node
+

+

2.設定ファイル変更

+

mainnet-config.jsonにP2Pフラグを追記する

+
+
+
+
sed -i -e '2i \  "EnableP2P": true,' $NODE_HOME/mainnet-config.json
+
+
+
+
sed -i -e 's!"EnableP2P": false!"EnableP2P": true!' $NODE_HOME/mainnet-config.json
+
+
+
+
+

トポロジーファイルのバックアップを作成する +

mv $NODE_HOME/mainnet-topology.json $NODE_HOME/mainnet-topology-non2p2.json
+

+

3.新トポロジーファイル作成

+

実行前に +をクリックして注釈を確認してください。
+localRootsには常にHot接続にしたい接続先を記入します。

+
+
+
+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF
+{
+"localRoots": [
+    { "accessPoints": [
+        {
+        "address": "xxx.xxx.xxx.xx", #(1)!
+        "port": yyyy #(2)!
+        }
+        ],
+        "advertise": false,
+        "valency": 1
+    }
+],
+"publicRoots": [
+  { "accessPoints": [
+    {
+      "address": "backbone.cardano-mainnet.iohk.io",
+      "port": 3001
+    },
+    {
+      "address": "backbone.cardano.iog.io",
+      "port": 3001
+    },
+    {
+      "address": "backbone.mainnet.emurgornd.com",
+      "port": 3001
+    }
+    ],
+    "advertise": false
+    }
+],
+"useLedgerAfterSlot": 87200000
+}
+EOF
+
+
    +
  1. BPのIPまたはDNSアドレスに置き換えてください
  2. +
  3. BPのポートに置き換えてください
  4. +
+
+
+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF
+{
+"localRoots": [
+    { "accessPoints": [
+        {
+        "address": "xx.xxx.xx.xxx", #(1)!
+        "port": yyyy #(2)!
+        },
+        {
+        "address": "bb.bbb.bb.bbb", #(3)!
+        "port": aaaa #(4)!
+        }
+        ],
+        "advertise": false,
+        "valency": 2
+    }
+],
+"publicRoots": [
+    { "accessPoints": [
+        {
+        "address": "backbone.cardano-mainnet.iohk.io",
+        "port": 3001
+        },
+        {
+        "address": "backbone.cardano.iog.io",
+        "port": 3001
+        },
+        {
+        "address": "backbone.mainnet.emurgornd.com",
+        "port": 3001
+        }
+    ],
+    "advertise": false
+    }
+],
+"useLedgerAfterSlot": 110332824
+}
+EOF
+
+
    +
  1. BP1のIPアドレスに置き換えてください
  2. +
  3. BP1のポートに置き換えてください
  4. +
  5. BP2または他リレーのIPアドレスに置き換えてください
  6. +
  7. BP2または他リレーのポートに置き換えてください
  8. +
+
+
+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF
+{
+"localRoots": [
+    { "accessPoints": [
+        {
+        "address": "xxx1.xxx.com", #(1)!
+        "port": yyyy #(2)!
+        }
+        ],
+        "advertise": false,
+        "valency": 1
+    },
+    { "accessPoints": [
+        {
+        "address": "bbb2.ccc.com", #(3)!
+        "port": aaaa #(4)!
+        }
+        ],
+        "advertise": false,
+        "valency": 1
+    }
+],
+"publicRoots": [
+    { "accessPoints": [
+    {
+        "address": "relays-new.cardano-mainnet.iohk.io",
+        "port": 3001
+    }
+    ],
+    "advertise": false
+    }
+],
+"useLedgerAfterSlot": 110332824
+}
+EOF
+
+
    +
  1. BP1のDNSアドレスに置き換えてください
  2. +
  3. BP1のポートに置き換えてください
  4. +
  5. BP2または他リレーのDNSアドレスに置き換えてください
  6. +
  7. BP2または他リレーのポートに置き換えてください
  8. +
+
+
+
+

新トポロジーファイル項目解説

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目説明
localRoots常にHotにしたい接続先を記入
accessPoints接続先グループ
advertisePeerSharing実装後に使用するフラグ(今はfalse)
valency接続数(接続先グループ内に記載した数と一致させる必要があります)
publicRootsブートストラップ用バックアップ接続先
seLedgerAfterSlot初期同期の際に台帳Peer検索を有効にするスロット番号
+

mainnet-topology.json構文チェック +

cat $NODE_HOME/mainnet-topology.json | jq .
+

+
+
+
+

mainnet-topology.jsonの中身がそのまま表示されます

+
+
+

以下のエラーが表示されます。mainnet-topology.jsonを開いて適切な記号{} [] , の有無をご確認ください。 +

parse error: Expected another key-value pair at line x, column x
+

+
+
+
+

4. ノード起動

+
sudo systemctl start cardano-node
+
+

5.トポロジーアップデータ修正

+

relay-topology_pull.sh内容変更
+mainnet-topology.json上書き防止のため、生成ファイルをリネームします。 +

sed -i $NODE_HOME/relay-topology_pull.sh \
+    -e "s/mainnet-topology.json/mainnet-topology-nonp2p.json/g"
+

+
+

P2Pモードにしたリレーでは定期的にrelay-topology_pull.shを実行する必要はありません。

+
+
+

生存通知について

+

Cronに設定している、トポロジーアップデータサーバーへの生存通知はしばらく継続して下さい。
+廃止時期は別途ご案内致します。

+
+

6.トポロジーリロード設定

+

リロード用環境変数を追加 +

echo alias cnreload='"kill -SIGHUP $(pidof cardano-node)"' >> $HOME/.bashrc
+source $HOME/.bashrc
+

+
+

P2P有効時の新機能

+

トポロジーファイル更新時のノード再起動が不要になりました!!
+mainnet-topology.jsonファイルを修正した後、cnreloadコマンドを実行することで +ノードを再起動することなく、トポロジーファイルの再読み込みが可能です。

+
+

7. gLiveViewの見方

+

P2P専用項目を解説します。
+

+

Cold Warm Hotが適正値に落ち着くまでに数時間かかる場合があります。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目説明備考
Incoming他リレーからの接続数Outで双方向の場合Inもカウントされる
Outgoing自リレーからの接続数Warm + Hot の合計値
Cold Peers検知済みの予備Peer(未接続ピア バックアップ)デフォルト 50
Warm Peersバックアップ接続Peer数(ミニプロトコル未使用)デフォルト30
Hot Peersアクティブ接続のPeer数(ミニプロトコル使用)20が最適値
Uni-Dir接続先/接続元いずれかが非P2P(UniDirectional 単一方向接続 )
Bi-Dir接続先/接続元が両端でP2P(Bidirectional 双方向接続)
Duplex接続先/接続元がP2Pで両端でHotで接続状態相互アクティブ接続
+

Peerアナリティクスについて
+

+
+

Peerアナリティクスの変更点

+

P2PモードのOutgoingはノードポートを使用するため、コマンドの特性上全てInでカウントされます。

+
+
+

ノード間の距離について

+

P2Pモードで最適な接続先と接続するとは言え、距離の多様性(近・中・遠距離)は維持されます。
+インターネットルーティングの変更、接続性の部分的な喪失、物理的なインフラ障害により接続が失われた場合、ノードの一部または全部が他のより長い距離のウォーム接続を維持していれば、それらをホット接続に迅速に昇格させて回復できます。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/pool-retire/index.html b/operation/pool-retire/index.html new file mode 100644 index 00000000..cdbca4c8 --- /dev/null +++ b/operation/pool-retire/index.html @@ -0,0 +1,3532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1-5.プール廃止処理 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

ステークプールを廃止する

+
+

プール廃止の流れ

+
graph LR
+    A[1-リタイア処理] -->|500ADA返還| B(2-登録料返還確認);
+    C[3-stake.addrから全額引出処理] -->|全額| D(3-payment.addr着金確認);
+    E[4-stake.addr解除処理] -->|2ADA返還| F(4-payment.addr確認);
+    G[5-payment.addr全額引出処理] -->|全額| H(5-任意のアドレス確認);
+    click A "./#1"
+    click B "./#_3"
+    click C "../withdrawal/#2-1-paymentaddr"
+    click E "./#2"
+    click G "./#3paymentaddr"
+
+

1.リタイア処理

+

現在のエポックを計算します。

+
+
+
+
startTimeGenesis=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .systemStart)
+startTimeSec=$(date --date=${startTimeGenesis} +%s)
+currentTimeSec=$(date -u +%s)
+epochLength=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .epochLength)
+epoch=$(( (${currentTimeSec}-${startTimeSec}) / ${epochLength} ))
+echo current epoch: ${epoch}
+
+
+
+
+

プールが最も早く引退できるエポックと最も遅い引退エポックを見つけます。

+
+
+
+
poolRetireMaxEpoch=$(cat $NODE_HOME/params.json | jq -r '.poolRetireMaxEpoch')
+echo poolRetireMaxEpoch: ${poolRetireMaxEpoch}
+
+minRetirementEpoch=$(( ${epoch} + 1 ))
+maxRetirementEpoch=$(( ${epoch} + ${poolRetireMaxEpoch} ))
+
+echo リタイア可能最短エポック: ${minRetirementEpoch}
+echo リタイア可能最長エポック: ${maxRetirementEpoch}
+
+
+
+
+
+

リタイアのタイミングについて

+

: エポック320でeMax18の場合,

+
    +
  • 最も早いポックは 321 ( 現在のエポック + 1)
  • +
  • +

    最も遅いエポックは 338 ( eMax + 現在のエポック)

    +
  • +
  • +

    プールはリタイア指定エポック開始時にリタイア処理されます。

    +
  • +
  • もし心変わりがある場合は、エポック指定エポック開始前に新しい登録証明書を送信することでリタイア手続きを無効にできます。
  • +
  • プール登録料500ADAはリタイア処理エポック開始時にstake.addrに入金されます。
  • +
+
+

登録解除証明書 pool.deregを作成します。
+以下のコマンド内の --epoch *** にリタイアしたいエポックを記入します

+
+
+
+
cd $NODE_HOME
+chmod u+rwx $HOME/cold-keys
+cardano-cli stake-pool deregistration-certificate \
+--cold-verification-key-file $HOME/cold-keys/node.vkey \
+--epoch *** \
+--out-file pool.dereg
+
+
+
+
+
+

ファイル転送

+

エアギャップのpool.deregをBPのcnodeディレクトリにコピーします

+
graph LR
+    A[エアギャップ] -->|pool.dereg| B[BP];
+
+

payment.addrの残高を参照します

+
+
+
+
cd $NODE_HOME
+cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

現在のスロットを算出します。

+
+
+
+
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

build-raw transactionコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${total_balance} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --certificate-file pool.dereg \
+    --out-file tx.tmp
+
+
+
+
+

最低料金を計算します。

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 2 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

変更出力を計算します。

+
+
+
+
txOut=$((${total_balance}-${fee}))
+echo txOut: ${txOut}
+
+
+
+
+

トランザクションをビルドします。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --certificate-file pool.dereg \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.rawをエアギャップオフラインマシンのcnodeディレクトリにコピーします

+
graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];
+
+

トランザクションに署名する

+
+
+
+
cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file $HOME/cold-keys/node.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+

コールドキーをロックする +

chmod a-rwx $HOME/cold-keys
+

+
+

ファイル転送

+

エアギャップtx.signedブロックプロデューサノードのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];
+
+

トランザクションを送信します

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+

リタイア確認

+
    +
  • KOIOS APIを使用してリタイア処理ステータスを確認できます。
  • +
+

pool.id-bech32の作成

+
+
+
+
cd $NODE_HOME
+cardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format bech32 > pool.id-bech32
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのpool.id-bech32をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|pool.id-bech32| B[BP];

+
+
+
+
+
cd $NODE_HOME
+curl -s "https://api.koios.rest/api/v0/pool_updates?_pool_bech32=$(cat pool.id-bech32)" | jq '.[0].pool_status,.[0].retiring_epoch'
+
+
#戻り値サンプル
+"retired" # "retiring"でリタイア処理待ち "retired"でリタイア済み 
+309 #リタイアエポック
+
+
+
+
+

2.登録料返還確認

+
+

注意

+

以降の処理は、プールのリタイア処理が完了してから実施してください

+
+
+

ファイル転送

+

エアギャップstake.addrBPのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|stake.addr| B[BP];
+
+
+
+
+
cd $NODE_HOME
+cardano-cli query stake-address-info \
+--address $(cat stake.addr) \
+$NODE_NETWORK
+
+
+
+
+

戻り値確認

+
+

rewardAccountBalance: の値を確認する

+
+

3.stake.addrから引き出し

+

stake.addrからpayment.addrへ送金する方法

+

4.ステークキー解除手順

+
+

注意

+
    +
  • この手順ではstake.addrの登録を解除し、2ADAの返還手続きを行います。
  • +
  • プール登録料(500ADA)が返還される前に以下の処理を行ってしまうと、500ADAを受け取ることが出来ません。
  • +
  • 以下の手続きは、プール登録料の500ADAを受け取ってから実施してください
  • +
+
+

ステークキー登録解除証明書作成

+
+
+
+
cardano-cli stake-address deregistration-certificate \
+    --stake-verification-key-file stake.vkey \
+    --out-file stake-dereg.cert
+
+
+
+
+
+

ファイル転送

+

エアギャップstake-dereg.certブロックプロデューサノードのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|stake-dereg.cert| B[BP];
+
+

ステークキー登録料算出

+
+
+
+
keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakeAddressDeposit')
+echo keyDeposit: $keyDeposit
+
+
+
+
+

最新スロット算出

+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

payment.addr残高を参照

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

仮トランザクションファイルを作成

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --certificate stake-dereg.cert \
+    --out-file tx.tmp
+
+
+
+
+

最低料金を計算します

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 2 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

変更出力を計算します。

+
+
+
+
txOut=$((total_balance+keyDeposit-fee))
+echo Change Output: ${txOut}
+
+
+
+
+

トランザクションをビルドします。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --certificate-file stake-dereg.cert \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

トランザクションに署名する

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+

5.payment.addrから全額引き出す手順

+

まずは、最新のスロット番号を取得し invalid-hereafter パラメータを正しく設定します。

+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

送金先のアドレスを設定します。

+
+
+
+
destinationAddress=送金先アドレス
+echo destinationAddress: $destinationAddress
+
+
+
+
+

payment.addrの残高を参照します。

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します。

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

build-rawトランザクションコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out ${destinationAddress}+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --out-file tx.tmp
+
+
+
+
+

最低手数料を出力します

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 1 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

計算結果を出力します。

+
+
+
+
txOut=$((${total_balance}-${fee}))
+echo Change Output: ${txOut}
+
+
+
+
+

送金金額を確認します

+
+
+
+
amountToSend=$((${txOut}))
+echo amountToSend: $amountToSend
+
+
+
+
+

トランザクションファイルを構築します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out ${destinationAddress}+${amountToSend} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップオフラインマシンのcnodeディレクトリにコピーします。

+
graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];
+
+

トランザクションに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+

tx.signed をブロックプロデューサーノードのcnodeディレクトリにコピーします。

+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];
+
+

署名されたトランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+

全額出金されているか確認します。

+
+
+
+
cd $NODE_HOME
+cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK
+
+
+
+
+

トランザクションが消えていればOKです

+
                           TxHash                                 TxIx        Lovelace
+----------------------------------------------------------------------------------------
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/relay-move/index.html b/operation/relay-move/index.html new file mode 100644 index 00000000..42298d86 --- /dev/null +++ b/operation/relay-move/index.html @@ -0,0 +1,3498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + リレーサーバー - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

リレーサーバーの引越し手順(旧VPS会社→新VPS会社)

+
+

前提注意事項

+
    +
  • 本まとめは現VPS会社→新VPS会社へと リレーのみ を移行するまとめです。
  • +
  • 実際に行う際には手順をよく読みながら進めてください。
  • +
  • ブロック生成予定まで余裕がある時に実施してください。
  • +
  • リレー1台かつトポロジーアップデータにIPアドレスで登録している場合は、旧リレーと新リレーを一定期間併用運用する必要があります。
  • +
+
+

1.新リレーセットアップ

+
+

留意事項

+
    +
  1. サーバ独自機能に留意する
      +
    • さくらのパケットフィルタや、AWSのFW設定などのサーバー独自の機能に気を付けてください。
    • +
    +
  2. +
  3. 新リレーのファイヤーウォール設定は、旧リレーと同じ設定にしてください。
  4. +
  5. 旧リレーのユーザー名(例:ubuntu)と新リレーのユーザー名は変更しないでください。
      +
    • もし変更する場合は、以下のファイル内のパス名を手動で変更してください。
    • +
    • startRelayNode1.sh DIRECTORY=/home/ユーザー名/cnode
    • +
    • topologyUpdater.sh CNODE_HOME=/home/ユーザー名/cnode
    • +
    • relay-topology_pull.sh curl -4 -s -o /home/ユーザー名/cnode/****
    • +
    +
  6. +
+
+

1-1.Ubuntu初期設定

+

新サーバーでUbuntu初期設定を実施します。

+

1-2.ノードセットアップ

+

依存関係インストール 〜 +gLiveViewのインストールまで実施します。

+

2.旧リレー移行処理

+

旧リレーファイル移動

+

以下のファイルを旧リレーのcnodeディレクトリから新リレーのcnodeディレクトリにコピーします。

+
graph LR
+    A[旧リレー] -->|ファイル/フォルダ| B[新リレー];
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル名用途
mainnet-topology.jsonトポロジーファイル
startRelayNode1.shノード起動スクリプト
topologyUpdater.shトポロジーアップデータスクリプト
relay-topology_pull.shトポロジー生成スクリプト
rsyncd.confRSYNC設定ファイル(設定中の場合)
rsync_ed25519.pubRSYNC鍵ファイル(設定中の場合)
+

3.新リレー再設定

+
+

旧リレーをダイナミックP2Pで運用していた場合

+

新リレーのmainnet-config.jsonのP2P設定をtrueにする

+
+
+
+
+
+
sed -i -e 's!"EnableP2P": false!"EnableP2P": true!' $NODE_HOME/mainnet-config.json
+
+
+

3-1.パーミッション変更

+
+
+
+
cd $NODE_HOME
+chmod +x startRelayNode1.sh
+chmod +x topologyUpdater.sh
+chmod +x relay-topology_pull.sh
+
+

ノードを再起動します。 +

sudo systemctl reload-or-restart cardano-node
+
+ノードログ確認 +
journalctl --unit=cardano-node --follow
+

+
+
+
+
+

DNS運用の場合

+
    +
  • リレーDNSのAレコードを新リレーサーバーのIPアドレスへ変更する
  • +
+
+

3-2. トポロジーアップデータ設定

+
+
+
+
+
+
nano $NODE_HOME/topologyUpdater.sh
+
+
+

旧リレーのIPとポートを新リレーのIPとポートに変更する

+
+
    +
  • CNODE_PORT=xxxx  
  • +
  • CNODE_HOSTNAME="xxx.xxx.xxx.xxx"  
  • +
+
+

DNS運用の場合

+
    +
  • (DNS運用の場合は変更不要)
  • +
+
+

トポロジーアップデータ実行 +

cd $NODE_HOME
+./topologyUpdater.sh
+
+topologyUpdater.shが正常に実行された場合、以下の形式が表示されます。

+
+

{ "resultcode": "201", "datetime":"2020-07-28 01:23:45", "clientIp": "xxx.xxx.xxx.xx", "iptype": 4, "msg": "nice to meet you" }

+
+

3-3.Cron登録

+

1.Cronジョブ設定を実行する

+

2.Cronジョブ設定から4時間後にフェッチリスト登録確認を実行する

+

3.トポロジーファイル再作成

+
+
+
+

relay-topology_pull.shを実行し、トポロジーファイルを再作成する。 +

cd $NODE_HOME
+./relay-topology_pull.sh
+

+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+
+
+

何もせず、relay-topology_pull.shも実行しないでください。

+
+
+
+
+

旧リレー併用目安

+

リレー1台かつトポロジーアップデータにIPアドレスで登録している場合は、新リレーのIncomingの数が安定して10以上に増えるまで旧リレーと新リレーを併用してください。

+
+

4.BP設定修正

+

4-1.ファイアウォール設定変更

+
+

AWSなどufwを使用しない場合

+

VPSの管理画面からファイアウォールの設定を変更してください。

+
+
+
+
+
PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+
+

<新リレーIP> の <>を除いて新リレーIPを入力してください。 +

sudo ufw allow from <新リレーIP> to any port ${b_PORT}
+sudo ufw reload
+

+
+
+
+

4-2.トポロジーファイル修正

+
+
+
+
nano $NODE_HOME/mainnet-topology.json
+
+
    +
  • 旧リレーIPとポートを新リレーのIPとポートに変更する
  • +
  • DNS運用の場合は変更不要
  • +
+

BPノードを再起動する +

sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

チェーンが同期したら新リレーとBPの双方向の疎通(I/O)ができているかを確認します。

+
+
+
+

gLiveView確認 +

cd $NODE_HOME/scripts
+./gLiveView.sh
+

+
+

InとOutに新リレーのIPがあることを確認してください。

+
+
+
+
+

5.Grafana/Prometheus設定

+
+
+
+

監視ツールセットアップのリレーノード1タブと9-3.Grafanaダッシュボード設定を実行する。

+
+

Grafana追加設定

+

Grafanaは追加設定がありますので必要に応じて実施してください。

+ +
+
+
+
    +
  • 新リレーにてprometheus node exporterをインストールします。
  • +
+
+
+
+
sudo apt install -y prometheus-node-exporter
+
+

サービスを有効にして、自動的に開始されるように設定します。 +

sudo systemctl enable prometheus-node-exporter.service
+

+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

prometheus.ymlの修正

+
    +
  • DNSベースで接続している人は、DNSの変更が反映されたら自動的に切り替わるので以下作業は不要です。
  • +
+
+
+
+
sudo nano /etc/prometheus/prometheus.yml
+
+
+
    +
  • 旧リレーのIPを新リレーのIPへ変更してください
  • +
+
+

サービス再起動 +

sudo systemctl restart grafana-server.service
+sudo systemctl restart prometheus.service
+sudo systemctl restart prometheus-node-exporter.service
+

+

サービスが正しく実行されていることを確認します。 +

sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service
+

+

Grafanaに新リレーのメトリクス(Slotなど)が表示されているか確認する。

+
+
+
+
+
+
+

6.プール情報更新

+

プール情報の更新を用いて、チェーン登録中のリレーIPを変更する。
+(DNS運用の場合は不要です)

+
+

7.補足

+

Tracemempool無効化

+

新リレーに十分なInが確認できた場合の処理

+
+
+
+

Txの増加が確認できたらTracemempoolを無効にします。 +

sed -i $NODE_HOME/${NODE_CONFIG}-config.json \
+    -e "s/TraceMempool\": true/TraceMempool\": false/g"
+

+

ノード再起動 +

sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

旧リレーストップ

+
+
+
+

sudo systemctl stop cardano-node
+
+サービス解除 +
sudo systemctl disable cardano-node
+

+
+
+
+

BPファイアウォールから旧リレーIP削除

+
+
+
+

sudo ufw status numbered
+
+
sudo ufw delete <削除したい番号>
+

+
+
+
+
+

ufwを使わないケース

+

AWSやVSPによっては管理画面でセキュリティ設定(ファイアウォール)を行っている場合がありますので、その場合はVPS管理画面から設定を変更してください。

+
+

Mithril-Signer再セットアップ

+

旧サーバーでMithril-Signer-Relayを実行していた場合は、新サーバーでも再セットアップしてください。不明点がある場合はBTBF SPO LAB.でご質問ください。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/rsync-ssh/index.html b/operation/rsync-ssh/index.html new file mode 100644 index 00000000..eec4319b --- /dev/null +++ b/operation/rsync-ssh/index.html @@ -0,0 +1,3173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 事前設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

サーバー間同期設定(RSYNC+SSH)

+
+

概要

+

サーバー間で任意のデータを転送する設定です。
+新ノード更新時に発生するDB再構築時のダウンタイムを抑えたり、ビルドされたバイナリファイル(NODE/CLI)をそのまま任意のサーバーへ転送できます。

+

1.転送元のサーバーを1台決めます。(リレーノードもしくはバックアップノードを推奨)
+2.転送先は複数台のサーバーを事前に設定出来ます。
+3.RSYNC+SSH専用の認証キーを作成し接続します。
+4.転送先サーバーは、指定した転送元IPからのアップロードのみ受け付けます。

+

構成イメージ +

flowchart LR
+    a[転送元リレー1] -->|RSYNC+SSH| b[リレー2] & c[リレー3] & d[BP]

+
+

1.転送元サーバー設定

+

リレーノードもしくはバックアップノード

+

1-1.RSYNC専用SSH認証キーの作成

+
+
+
+
+
+

ed25519暗号で認証キーを作成する +

ssh-keygen -t ed25519 -N '' -C Data_Transfer -f ~/.ssh/rsync_ed25519
+

+
+

生成された認証キーを確認する

+
ls ~/.ssh/
+
+
    +
  • rsync_ed25519・・・秘密鍵
  • +
  • rsync_ed25519.pub・・・公開鍵
  • +
+

この2つのファイルが生成されていることを確認する。USBなどへバックアップ推奨

+
+

1-2.SSH設定ファイル作成

+
+

コマンド内訳

+

必ず自分の環境に合わせてコマンドを完成させてください。

+

Host [転送先サーバーの任意名] ※接続時のエイリアス名になります
+HostName [転送先IPまたはドメイン]
+User [転送先のUser名]
+port [転送先のSSHポート]
+IdentityFile [SSH秘密鍵のパス]

+

転送先が複数台ある場合は上記を1セットとして追加する

+
+

サンプルコード +

cat > ~/.ssh/config << EOF
+Host BP
+    HostName xxx.xxx.xxx.xx
+    User xxxxx
+    Port xx
+    IdentityFile ~/.ssh/rsync_ed25519
+
+Host Relay2
+    HostName xxx.xx.xxx.xx
+    User xxxxx
+    Port xx
+    IdentityFile ~/.ssh/rsync_ed25519
+EOF
+

+

アクセス権を変更する +

chmod 600 ~/.ssh/config
+

+

1-3.SSH公開鍵ファイル転送

+

公開鍵をcnodeへ移動する +

mv ~/.ssh/rsync_ed25519.pub $NODE_HOME/
+

+

1-4.ZStandardインストール

+
sudo apt install zstd
+
+

2.転送先サーバー設定

+

転送元にあるrsync_ed25519.pubを転送先へコピーしてください。

+
+

【重要】ファイル転送

+

転送元サーバーのcnode直下にある公開鍵ファイルrsync_ed25519.pubを、転送先サーバーのcnodeフォルダへコピーする

+
graph LR
+    A[転送元] -->|rsync_ed25519.pub| B[転送先];
+
+

2-1.SSH公開鍵の追記

+

コマンドと公開鍵の組み合わせでファイルを生成する +

echo 'command="rsync --server --daemon --config='$NODE_HOME'/rsyncd.conf .",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding '$(cat $NODE_HOME/rsync_ed25519.pub)'' > $NODE_HOME/rsync.txt
+

+

公開鍵コマンドをauthorized_keysに追記する +

cat $NODE_HOME/rsync.txt >> ~/.ssh/authorized_keys
+

+

2-2.RSYNC設定ファイル作成

+

allowIP変数に転送元IPを代入する。x.x.x.xを転送元のIPに変更して実行する。 +

allowIP=x.x.x.x
+

+

以下コマンドを一括コピーして、実行する。 +

cat > $NODE_HOME/rsyncd.conf << EOF
+# SSHで一般ユーザの場合は使えないのでno
+use chroot = no
+# 書き込む必要があるのでread onlyはno
+read only = no
+# 逆に読み取る必要はないのでwrite onlyをyesに
+write only = yes
+# 一旦すべて拒否
+hosts deny = *
+# 圧縮済みの物は再圧縮しない
+dont compress = *.pdf *.jpg *.jpeg *.gif *.png *.mp3 *.mp4 *.ogg *.avi *.7z *.z *.gz *.tgz *.zip *.lzh *.bz2 *.rar *.xz
+
+[Server]
+  #アクセス許可パス
+  path = $NODE_HOME
+  # 接続元のIPアドレスを設定
+  hosts allow = $allowIP
+EOF
+

+

3.転送テスト

+

転送元から転送先へファイルをアップロードします。

+
+
+
+

転送用ファイルを作成する +

cd $NODE_HOME
+cardano-cli query protocol-parameters \
+    --mainnet \
+    --out-file params-test.json
+

+

転送コマンドを実行する

+
+

コマンド内訳

+

rsync -P --rsh=ssh [転送元転送ファイルパス] [転送先エイリアス名]::Server/[転送ファイル名]

+
    +
  • [転送先エイリアス名]には、1-2で設定した転送先Host名(エイリアス)を指定します。
  • +
+
+

サンプルコマンド +

rsync -P --rsh=ssh $NODE_HOME/params-test.json Relay2::Server/params-test.json
+

+
+
    +
  • 初回接続時のみフィンガープリントの確認が入るのでyesを入力する
  • +
  • Verification code: が表示される場合は、転送先サーバーの2段階認証コードを入力してください。
  • +
+
+
+
+
+

転送先で受信したファイルを確認する。

+
+
+
+
ls $NODE_HOME/params-test.json
+
+
+
+
+
+

ファイルパスの戻り値があれば転送成功。

+
+

4.転送先を追加する場合

+
+

転送先を追加する場合

+
    +
  • 1-2のSSH設定ファイルに転送先を追記する
  • +
  • 新しい転送先で2と3を実施する
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/sftp/index.html b/operation/sftp/index.html new file mode 100644 index 00000000..12ad945e --- /dev/null +++ b/operation/sftp/index.html @@ -0,0 +1,2877 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4-2.SFTPソフト設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

FileZillaのセットアップ

+
    +
  • 本手順は、MacOSで実施していますが、Windowsの方でもあまり違いはないかと思いますのでWindowsの方は読み替えて実施してください。
  • +
+
+

貢献者

+

[AKYO] AKYO🥁 Akyoさんに導入手順を作成頂きました。ありがとうございます!

+
+

1- FileZillaのダウンロード

+

1-1. 以下のリンク先からFileZilla Clientをダウンロードします。

+

FileZilla Clientをダウンロード

+ + + + + + + + + + + + + + + + + +
OSファイル名
MacOSFileZilla_X.XX.X_macosx-x86.app.tar.bz2
WindowsFileZilla_X.XX.X_win64-setup.exe
+

Quick download links +FileZilla-1

+
+

Show additional download options +FileZilla-2

+
+

Download FileZilla Client +FileZilla-3

+
+

Macであれば「FileZilla_X.XX.X_macosx-x86.app.tar.bz2」

+

Winであれば「FileZilla_X.XX.X_win64-setup.exe」 +- ダウンロードしたら解凍し、Macの方はDownloadsフォルダからApplicationフォルダへ移動してください。

+
+
+

1-2. ポップアップメッセージが表示されたら以下の画像のように進めてFileZillaを起動します。

+

FileZilla-4

+
+

FileZilla-5

+

2- SFTP設定

+

2-1. メニューバーから「FileZilla」→「設定」へと進みます。

+

FileZilla-6

+
+

2-2. SFTP設定します。 +FileZilla-7

+
+

2-3. 接続先の作成と設定をします。

+ + + + + + + + + + + + + + + + + + + + + + + + + +
プロトコルSFTP
ホストサーバーIP
ポート設定したsshポート番号
ログオンタイプインタラクティブ
ユーザーユーザー名
+
+

「新しいサイト」で作成した名称は例ですのでお好みで設定してください。

+
+

FileZilla-8

+
+

うまく接続できなかった場合は、ログオンタイプを一度「鍵ファイル」とし、秘密鍵を指定して接続を試みて、その後ログオンタイプを「インタラクティブ」にしてGoogle認証での6桁の数字を入力してみてください。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/sjg-fixed/index.html b/operation/sjg-fixed/index.html new file mode 100644 index 00000000..2de1894d --- /dev/null +++ b/operation/sjg-fixed/index.html @@ -0,0 +1,2907 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + SJG 修正プログラム - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

SJG 修正プログラム

+

envファイル対応

+
+

最終更新日:2022/02/19 v1.0

+
+

概要

+

■発生事象
+gliveview.sh/cncli.sh実行時に、実行したディレクトリにenv/gliveview.sh/cncli.shが生成されてしまう。

+

■原因
+env内のアップデート関数処理変更に伴うもの

+

■修正プログラム内容
+⇒.bashrc内aliasに設定中の変数(glive/blocks)のコマンドを変更
+⇒cncli系サービスファイルのWorkingDirectoryを変更

+

■対象者 +* プール構築中でブロックログの設定まで完了した方 +* プール運営中SPOの方

+

■対象サーバー
+BP/リレー

+

■修正プログラム適用手順

+

BP/リレー共通

+

1.修正プログラムをダウンロードする(BP/リレー共通) +

cd $NODE_HOME/scripts
+wget -q https://raw.githubusercontent.com/btbf/coincashew/master/guild-tools/service_fixed.sh -O service_fixed.sh
+

+

2.パーミッションを設定し、実行する +

chmod 755 service_fixed.sh
+./service_fixed.sh
+

+

3.プログラムが終了するのを待つ

+

4. bashrcを読み込む +

source $HOME/.bashrc
+

+

5.修正プログラムを削除する +

cd $NODE_HOME/scripts
+rm service_fixed.sh
+

+

6.アップデート確認対応

+
cd $HOME
+glive
+
+
+

Script update(s) detected, do you want to download the latest version? (yes/no):yes

+
+

再度、gliveviewを実行する +

cd $HOME
+glive
+
+アップデート確認が出なくなるまでyes で対応する。

+

BPのみ

+

9.(BPのみ)各サービスが動いているか確認する

+
+

複数のサービスでアップデート確認が表示されている場合がありますが、どれか1つでyesにしたら他のサービスではnoにしてください
+例)
+ tmux a -t cncliではyes
+Script update(s) detected, do you want to download the latest version? (yes/no):yes
+
+
tmux a -t validateではno
+Script update(s) detected, do you want to download the latest version? (yes/no):no

+
+

tmux a -t cncli
+
+
tmux a -t validate
+
+
tmux a -t leaderlog
+
+
tmux a -t logmonitor
+

+
+

tmux a -t leaderlogは、今回のプログラムでは中断処理を入れてるので以下の表記になっていますが問題ありません。

+
> Checking for script updates...  
+> ^C
+
+次エポックのスケジュールを取得したい場合は、別途ノードを再起動してください。
+
+ +

お疲れさまでした。

+

作業ディレクトリ名修正

+

最終更新日:2021年12月27日の時点 version 2.2

+
+

概要

+
    +
  • ノードを止めるため、ブロック生成予定が無い時間帯に実行してください。
  • +
  • BP/リレーは自動判定し、それぞれの依存ファイルを修正します。
  • +
  • 環境変数$NODE_HOMEに設定されているパスを読み取り自動置換します。
    +ex) /home/user/cardano-my-node ⇒ /home/user/cnode
    +ex) /home/user/cardano-node ⇒ /home/user/cnode
  • +
  • 現在設定中のノードポート番号やプールIDを読み取り、各ファイルに自動反映します。
  • +
+
+
+

注意

+

🛑 日本語マニュアルで使われてる各種スクリプトのファイル名を任意の名前に変更している場合は、正しく動作しない場合があります。 🚧
+もし、スクリプトファイルやキーファイル名を変更している場合は実行前にBTBFまでご相談ください。

+
+

1. プログラムをダウンロードする

+
cd $HOME
+wget -q https://raw.githubusercontent.com/btbf/coincashew/master/guild-tools/dirname_cng.sh -O dirname_cng.sh
+
+

2.プログラムを実行する

+
chmod 755 dirname_cng.sh
+./dirname_cng.sh
+
+
+

画面の指示に従って進めてください。

+
+

3.起動確認

+

ノードログ表示 +

journalctl --unit=cardano-node --follow
+

+
+

エラーが出てる場合は、$HOME直下にある「dirname-***.log」ログファイルをギルドに提出してください。

+
+

環境変数確認 +

source $HOME/.bashrc
+echo $NODE_HOME
+

+
+

例) /home/user/cnode と表示されればOK

+
+

gliveview確認

+
+

表示できるか確認してください。 +Script update(s) detected, do you want to download the latest version? (yes/no):」が表示される場合は、出なくなるまで Y

+
+

ノード別確認事項

+
+
+
+

clontab確認 +

crontab -l
+

+
+

例) "22 * * * * /home/user/cnode/topologyUpdater.sh" のように表示されればOK

+
+
+
+

ブロックログ起動確認 +

tmux a -t cncli
+

+
+

~~~100.00% syncedが表示されたらOK
+赤文字はノードが同期するまで表示される文章であり、エラーではないのでノードが同期するまでお待ちください

+
+

アップデート警告文がある場合

+
+

Script update(s) detected, do you want to download the latest version? (yes/no):」が表示されている場合は Y +デタッチしてからサービス再起動 +

sudo systemctl reload-or-restart cnode-cncli-sync.service
+

+
+

再度確認 +

tmux a -t cncli
+

+
+

~~~100.00% syncedが表示されたらOK

+
+
+
+
+

実行ファイル削除

+
rm $HOME/dirname_cng.sh
+
+

4.エアギャップディレクトリ名変更

+
+

エアギャップでは、上記のプログラムを実行する必要はありません。

+
+
cd $HOME
+mv ./cardano-my-node ./cnode
+
+
sed -e "s@cardano-my-node@cnode@g" -i $HOME/.bashrc
+source $HOME/.bashrc
+echo $NODE_HOME
+
+
+

例) /home/user/cnode と表示されればOK

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ +
+ + + + +
+ +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/spo-poll/index.html b/operation/spo-poll/index.html new file mode 100644 index 00000000..0d09f35e --- /dev/null +++ b/operation/spo-poll/index.html @@ -0,0 +1,2997 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4-3.SPO投票 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

カルダノ財団SPO投票マニュアル

+
+

概要

+
    +
  • 投票トランザクション fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8
  • +
  • 投票期限:413エポック終了まで
  • +
  • CIP-0094ダッシュボード
    +Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]
  • +
  • トランザクション手数料のみで投票できます
  • +
  • CIP-0094に対応したcardano-cli(v8.0.0-untested または v8.0.0)が必要です
  • +
  • 投票は初回1回のみが有効です。
  • +
+
+

1.SJG TOOLで投票する

+
+

SJG TOOL投票仕様

+
    +
  • 投票データに簡易メッセージを添付可能!
    +ADASTATに実装された投票データ簡易メッセージを表示できます。
  • +
  • インストール済みのCLIがCIP-0094非対応の場合は、cardano-cli v8.0.0-untestedを別途自動インストールします。これは投票のみに使用し、通常のオペレーションには使用しません。
  • +
  • エアギャップにcardano-cli v8.0.0-untestedをインストールする必要はありません。
  • +
  • 投票内容の自動翻訳はAPI自動翻訳のため、正しい日本語になっていない場合があります。
  • +
+
+

1-1. SJG TOOLを起動し、v5.3へアップグレードしてください。

+

1-2. [5] SPO投票ツール を選択してください

+

1-3. 投票トランザクションハッシュを入力してください

+
fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8
+
+

1-4. 画面の指示に従って進めてください。(中断することも可能です)

+

1-5. 投票確認 +CIP-0094ダッシュボードで自身の投票を確認してみましょう!
+ Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]

+

以上です。

+

2.CLIコマンドで投票する

+
+

CLIコマンド投票仕様

+
    +
  • 投票データ簡易メッセージ添付には対応していません。添付したい場合は各自でメタデータファイルを編集するかSJGTOOLを利用してください。
  • +
+
+

2-1.CLIバージョンチェック +

cardano-cli version
+

+
+

v8.0.0はCIP-0094に対応しています。

+
+

CLIパスを設定する +

cli_path=$(which cardano-cli)
+

+

作業ディレクトリを作成する +

mkdir $HOME/git/spo-poll && cd $HOME/git/spo-poll
+

+
+

CLI v1.35.7以下の場合

+

CIP-0094に対応したCLIが必要のため、以下を実行しv8.0.0-untestedをダウンロードしてください。 これは投票のみに使用し、通常のオペレーションには使用しません。

+

v8.0.0-untestedをダウンロードする +

wget -q https://github.com/btbf/spojapanguild/raw/d7cd9792ab4cb532b74a8cd1bf30de3c1c03b8a6/scripts/spo-poll/cardano-cli.gz
+gzip -d cardano-cli.gz
+chmod 755 $HOME/git/spo-poll/cardano-cli
+
+バージョン確認 +
$HOME/git/spo-poll/cardano-cli version
+

+
+

cardano-cli 8.0.0 - linux-x86_64 - ghc-8.10 +git rev 0000000000000000000000000000000000000000

+
+

CLIパスを上書きする +

cli_path=$HOME/git/spo-poll/cardano-cli
+

+
    +
  • エアギャップにcardano-cli v8.0.0-untestedをインストールする必要はありません。
  • +
+
+

投票トランザクションハッシュを設定する +

txHash="fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8"
+

+

投票Cborデータ(json)をダウンロードする +

wget https://raw.githubusercontent.com/cardano-foundation/CIP-0094-polls/main/networks/${NODE_CONFIG}/${txHash}/poll.json -O $HOME/git/spo-poll/poll_${txHash}-CBOR.json
+

+

投票ファイル作成コマンドを実行する

+
${cli_path} governance answer-poll --poll-file $HOME/git/spo-poll/poll_${txHash}-CBOR.json > $HOME/git/spo-poll/poll_${txHash}-poll-answer.json
+
+

投票トランザクション送信準備

+
+
+
+

ウォレット残高確認 +

cd $NODE_HOME
+cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+

+

UTXO計算 +

tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+

+

投票用トランザクションファイルを作成する +

cd $NODE_HOME
+cardano-cli transaction build \
+    $NODE_NETWORK \
+    ${tx_in} \
+    --change-address $(cat payment.addr) \
+    --metadata-json-file $HOME/git/spo-poll/poll_${txHash}-poll-answer.json \
+    --json-metadata-detailed-schema \
+    --required-signer-hash $(cat pool.id) \
+    --out-file $NODE_HOME/poll-answer.tx
+

+
+
+
+
+

ファイル転送

+

BPのpoll-answer.tx をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|poll-answer.tx| B[エアギャップ];

+
+

エアギャップで署名ファイルを作成します。

+
+
+
+
cd $NODE_HOME
+chmod u+rwx $HOME/cold-keys
+cardano-cli transaction sign \
+    --tx-body-file poll-answer.tx \
+    --signing-key-file $HOME/cold-keys/node.skey \
+    --signing-key-file payment.skey \
+    $NODE_NETWORK \
+    --out-file poll-answer-tx.signed
+chmod a-rwx $HOME/cold-keys
+
+
+
+
+
+

ファイル転送

+

エアギャップのpoll-answer-tx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|poll-answer-tx.signed| B[BP];

+
+

BPでトランザクションを送信します

+
+
+
+
submit_txHash=$(cardano-cli transaction txid --tx-file $NODE_HOME/poll-answer.tx)
+cardano-cli transaction submit --tx-file $NODE_HOME/poll-answer-tx.signed $NODE_NETWORK
+
+
+
+
+

数分後にトランザクションメタデータを確認する +

curl -sX POST "https://api.koios.rest/api/v0/tx_metadata" -H "accept: application/json" -H "content-type: application/json"  -d "{\"_tx_hashes\":[\"${submit_txHash}\"]}" | jq .
+

+

投票確認

+

CIP-0094ダッシュボードで自身の投票を確認してみましょう!
+Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]

+

以上です。

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/start-guide/index.html b/operation/start-guide/index.html new file mode 100644 index 00000000..c393380c --- /dev/null +++ b/operation/start-guide/index.html @@ -0,0 +1,3395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 運用ガイド - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

カルダノステークプール運用ガイド

+
+

サポート

+

サポートが必要な場合は、SPO JAPAN GUILDコミュニティで現役のSPOに質問できます

+
+

パラメーターを理解する

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目用途
optimal_pool_count(K)500飽和閾値設定用
a00.3誓約報酬係数 
max_tx_size16384最大トランザクションサイズ 
max_block_size90112最大ブロックサイズ 
epochLength4320001エポックのスロット数 
slotsPerKESPeriod1296001KES当たりのスロット数 
maxKESEvolutions62KES有効期間 
activeSlotsCoeff0.051エポック内の有効スロット率 
+

スロットを理解する

+
    +
  • Slot = ジェネシススロットからのスロット
  • +
  • +

    Slot epoch = エポック内のスロット

    +
  • +
  • +

    1スロット=1秒

    +
  • +
  • 1エポック=432000スロット(epochLength)
    + (432000 / 60 = 7200分 / 60 = 120時間 / 24 = 5日)
  • +
+

ブロック生成スロットリーダー

+

1エポック内のブロック生成有効スロットは5%(432000スロット × 5% = 約21600スロット)
+委任量に応じて、スロットリーダーがランダムに決定されます。

+

1エポックで1ブロック割り当てられるために必要な委任量の目安は以下の通りです。

+
    +
  • 1M 60%
  • +
  • 2M 85%
  • +
  • 3M 95%
  • +
+

スロットリーダーの割り当ては、プール間同士で調整されないため以下のタイプのバトルが発生します。

+
+

スロットバトル(stolen)

+

他プールと同じスロットに割り当てられた際に発生
+vrf値によるサイコロゲームが行われ出た目の小さいプールのブロックが採用されます。(ステーク量による優位性はなくランダム)

+
+
+

ハイトバトル(Ghosted / missed)

+

他プールと5秒以内に割り当てられた場合や、前ブロック生成プールのサーバー設定・環境によりブロック伝播遅延が発生することで引き起こる現象。地理的優位性を無くすため、vrf値によるサイコロゲームが行われ出た目の小さいプールのブロックが採用されます。(ステーク量による優位性はなくランダム)

+
+

KESとは?

+
+

KES=Key-Evolving Signatures

+

ブロック生成署名用鍵ファイル。過去のブロック署名を書き換えることが出来ないよう90日ごとに更新が必要。

+
+

VRFとは?

+
+

VRF=Verifiable Random Function

+

Ouroboros Praosは、VRF(Verifiable Random Function)キーによって、ブロック生成にさらなるセキュリティ層を追加しています。 +Ouroboros Praosのスロットリーダーのスケジュールは非公開となっており、VRFキーを使ってスロットリーダーの検証を行っております。

+
+

各ファイルの役割と保管場所

+

証明書とペアキー

+

🔒・・・ロック必須・再作成不可・紛失不可
+🔃・・・更新時書き換え・再作成可能
+🔴・・・BP起動で使用
+🔷・・・ブロックログで使用

+
+

鍵ファイルバックアップについて

+

🔒マークが付いたファイルはプール運営にとても重要なファイルです。紛失・削除するとプール運営が継続できなくなったり、資金を引き出せなくなります。そのため同一ファイルを複数のUSBなどへ分散保管するようにしましょう。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル用途推奨保管場所重要度
payment.vkeypaymentアドレス公開鍵エアギャップ / USB🔒
payment.skeypaymentアドレス秘密鍵エアギャップ / USB🔒
stake.vkeyステークアドレス公開鍵エアギャップ / USB🔒
stake.skeyステークアドレス秘密鍵エアギャップ / USB🔒
vrf.vkey🔷VRF公開鍵BP / エアギャップ / USB🔒
vrf.skey🔴VRF秘密鍵BP / エアギャップ / USB🔒
node.vkeyコールド公開鍵エアギャップ / USB🔒
node.skeyコールド秘密鍵エアギャップ / USB🔒
payment.addrpaymentアドレスファイルBP / エアギャップ / USB🔃
stake.addrステークアドレス秘密鍵BP / エアギャップ / USB🔃
kes.vkeyKES公開鍵エアギャップ / USB🔃
kes.skey🔴KES秘密鍵BP / エアギャップ / USB🔃
node.cert🔴プール運用証明書BP / エアギャップ / USB🔃
pool.certプール登録証明書エアギャップ / USB🔃
node.counterカウンターファイルエアギャップ / USB🔃
+

ノード起動用設定ファイル

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル用途
mainnet-byron-genesis.jsonByron設定ファイル
mainnet-shelley-genesis.jsonShelley設定ファイル
mainnet-alonzo-genesis.jsonAlonzo設定ファイル
mainnet-config.jsonノード設定ファイル
mainnet-topology.jsonトポロジーファイル
+

スクリプトファイルやその他

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル用途推奨保管場所重要度
startRelayNode1.shリレー用ノード起動スクリプトリレー🔃
startBlockProducingNode.shBP用ノード起動スクリプトBP🔃
gLiveView.shノードGUI用スクリプトリレー/BP🔃
topologyUpdater.shトポロジーフェッチ登録スクリプトリレー🔃
relay-topology_pull.shトポロジーファイル生成スクリプトリレー🔃
params.jsonパラメーターファイルBP🔃
poolMetaData.jsonプール情報JSONBP🔃
poolMetaDataHash.txtpoolMetaData.jsonハッシュ値ファイルBP🔃
fullUtxo.outUTXO出力ファイル使用後削除可-
balance.outウォレット残高出力ファイル使用後削除可-
tx.tmp仮トランザクションファイル使用後削除可-
tx.rawトランザクションファイル使用後削除可-
tx.signedトランザクション署名付きファイル使用後削除可-
+

作業内容チェックリスト

+

日次作業

+
    +
  • ノード稼働状況チェック(Grafana等)
  • +
+

エポック毎作業

+ +

3か月毎作業

+ +

不定期作業

+
    +
  • ノードアップデート
  • +
  • サードパーティ製アプリアップデート
  • +
  • サーバー障害対応
  • +
  • プール設定変更など
  • +
+

トポロジーファイルの更新

+
+

概要

+

トポロジーファイルに記載されてるリレーノードは常に最新状態を保つことが望ましいため、1エポックに1回は書き換えることを推奨します。

+
+
+
+
+
+
+
cd $NODE_HOME
+./relay-topology_pull.sh
+
+
+

ヒント

+

relay-topology_pull.shを実行すると新しいトポロジーファイル(mainnet-topology.json)を生成します。 +新しいトポロジーファイルはノード再起動後に有効になります。

+
+
+
+
+
+
+
sudo systemctl reload-or-restart cardano-node
+
+

リレーノードでgLiveView を確認

+

ノードが同期するか確認します。

+
+
+
+
+
+
cd $NODE_HOME/scripts
+./gLiveView.sh
+
+

スケジュール算出

+
+

概要

+

次のスロットリーダースケジュールはエポック終了までにノードを再起動することによって算出され、把握できます。(1.5日前から算出可能)
+エポックが切り替わった後でも算出できますが、スケジュールが分からない状態でのノード再起動となり、リスクを伴うため事前に把握することを推奨します。

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/tool/index.html b/operation/tool/index.html new file mode 100644 index 00000000..87a6775d --- /dev/null +++ b/operation/tool/index.html @@ -0,0 +1,3390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4-1.SJGツール導入設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

SPO JAPAN GUILD TOOL

+

最終更新日:2024/1/30 v3.7.1

+
+

主な機能

+
    +
  • payment.addr残高照会
  • +
  • 報酬引き出し
  • +
  • ブロック生成可能可否確認
  • +
  • envファイルアップデート切り替え
  • +
  • Catalyst有権者登録
  • +
+
+

+

設定

+

スクリプトダウンロード +

cd $NODE_HOME/scripts
+wget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/sjgtool.sh -O sjgtool.sh
+chmod 755 sjgtool.sh
+

+

envファイル修正

+

そのまま全コピーして実行してください。 +

sed -i $NODE_HOME/scripts/env \
+    -e '1,73s!#WALLET_PAY_ADDR_FILENAME="payment.addr"!WALLET_PAY_ADDR_FILENAME="payment.addr"!' \
+    -e '1,73s!#WALLET_STAKE_ADDR_FILENAME="reward.addr"!WALLET_STAKE_ADDR_FILENAME="stake.addr"!' \
+    -e '1,73s!#POOL_HOTKEY_VK_FILENAME="hot.vkey"!POOL_HOTKEY_VK_FILENAME="kes.vkey"!' \
+    -e '1,73s!#POOL_HOTKEY_SK_FILENAME="hot.skey"!POOL_HOTKEY_SK_FILENAME="kes.skey"!' \
+    -e '1,73s!#POOL_COLDKEY_VK_FILENAME="cold.vkey"!POOL_COLDKEY_VK_FILENAME="node.vkey"!' \
+    -e '1,73s!#POOL_COLDKEY_SK_FILENAME="cold.skey"!POOL_COLDKEY_SK_FILENAME="node.skey"!' \
+    -e '1,73s!#POOL_OPCERT_COUNTER_FILENAME="cold.counter"!POOL_OPCERT_COUNTER_FILENAME="node.counter"!' \
+    -e '1,73s!#POOL_OPCERT_FILENAME="op.cert"!POOL_OPCERT_FILENAME="node.cert"!' \
+    -e '1,73s!#POOL_VRF_SK_FILENAME="vrf.skey"!POOL_VRF_SK_FILENAME="vrf.skey"!'
+

+
+
+
+

~/cnode/scripts/envファイル内の以下の変数に対し、先頭の#を削除しご自身の環境に合わせてファイル名を設定してください。

+
+

WALLET_PAY_ADDR_FILENAME="payment.addr"
+WALLET_STAKE_ADDR_FILENAME="stake.addr"
+POOL_HOTKEY_VK_FILENAME="kes.vkey"
+POOL_OPCERT_FILENAME="node.cert"
+POOL_VRF_SK_FILENAME="vrf.skey"
+POOL_OPCERT_COUNTER_FILENAME="node.counter"
+POOL_OPCERT_FILENAME="node.cert
+POOL_VRF_SK_FILENAME="vrf.skey

+
+
+
+
+

スクリプトへのパスを通し、任意の単語で起動出来るようにする +

echo alias gtool="'cd $NODE_HOME/scripts; ./sjgtool.sh'" >> $HOME/.bashrc
+source $HOME/.bashrc
+

+

TOOLを実行する +

gtool
+

+
+

既知の不具合

+
    +
  • [2] ブロック生成状態チェック
  • +
+

1.対象プール、プールIDがnullになる場合があります。
+2.エポック切り替わり後、半日~1日までは有効ステークが0ADAになります。

+

上記の不具合は、チェーンデータ取得用APIの既知の不具合によるもので、現在修正依頼中です。 +もしこの項目でNGが出た場合は、ディスコードでご質問ください。

+

また、その他バグを発見した場合はGithubでissueを提出してください。

+
+

更新履歴

+

3.7.1

+
* ブロック生成状態チェック 誓約チェック判定修正
+   (payment.addr + stake.addr報酬合計)
+* Pledge変更時の有効エポックチェック導入
+
+ +

3.7.0

+
* CLI 8.17.0.0対応
+* ディスク空き容量とDB容量表示追加
+
+ +

3.6.4

+
* gLiveView1.28.xアップデート機能
+* プールIDファイル名変更  
+ stakepoolid_hex → pool.id  
+ stakepoolid_bech32 → pool.id-bech32
+
+ +

3.6.3

+
* Catalyst有権者登録機能 payment.addrエラー修正
+
+ +

3.6.2

+
* Catalyst有権者登録機能 表示文言修正
+
+ +

3.6.0

+
* Catalyst有権者登録機能 実装
+ payment.addrのADAをCatalyst Votingパワーに使用できます
+
+ +

3.5.1

+
* SPO投票機能
+ cardano-cli 8.0.0-untested使用時、Txが作成されない不具合を解消
+
+ +

3.5.0

+
* SPO投票機能実装
+ 簡易メッセージ添付可能
+
+ +

3.4.6

+
* ブロック生成状態チェック
+    * メタデータハッシュチェック追加
+    * PeerInカウントから127.0.0.1を除外
+* PreviewネットワークTx確認リンクをCardanoScanへ変更
+
+ +

3.4.4

+
* Preview / PreProd テストネット対応(envファイル更新必須)
+* ブロック生成チェック総合判定導入
+
+ +

3.4.3

+
* 軽微な修正
+
+ +

3.4.2

+
* 364特別対応削除
+* envファイルアップデートチェックフラグ切替機能追加
+* トランザクション送信後、トランザクション確認URLを表示
+
+ +

3.3.1

+
* 364エポック特別対応 cncli.shパッチ適用追加
+
+ +

3.3.0

+
* 報酬/資金出金 任意アドレス出金ADA Handleに対応
+
+ +

3.2.1

+
* エアギャップコマンドを修正
+
+ +

3.2.0

+
* KES更新時のカウンターファイルチェック・作成手順追加
+* ブロック生成状態チェック KESファイルチェックルール変更
+
+ +

3.1.0

+
* KES更新時のnode.certバックアップ/削除追加
+
+ +

3.0.0

+
+
    +
  • KES更新機能追加
  • +
+

このアップデートに伴い、envファイルの修正が必要となります。 +v2.x.x以上をすでにインストールされていて、プールのKES秘密鍵のファイル名がkes.skeyの場合は以下のコードを1回だけ実行してください。 +違うファイル名をご利用の場合は任意に書き換えてください。 +

sed -i $NODE_HOME/scripts/env \
+-e '1,73s!#POOL_HOTKEY_SK_FILENAME="hot.skey"!POOL_HOTKEY_SK_FILENAME="kes.skey"!'
+

+
+

2.1.0

+
+
    +
  • DdzFアドレスへの報酬/資金出金を許可
  • +
  • payment.addr出金時、出金額表示単位バグを修正
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/transfer/index.html b/operation/transfer/index.html new file mode 100644 index 00000000..649dc3ac --- /dev/null +++ b/operation/transfer/index.html @@ -0,0 +1,3183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ファイル転送手順 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

サーバー間ファイル転送

+
+

メリット

+

複数台のサーバーがある場合に、以下の処理を行うことでビルド時間の短縮やノードのダウンタイムを抑えることが出来ます。

+
+
+

デメリット

+
    +
  • RSYNC+SSHを利用したアップデート方法は、転送元・転送先サーバーのディスク空き容量が150GB以上必要となります。
  • +
+
+
+

はじめに

+
    +
  • RSYNCを使用する場合、最初に事前設定を行ってください
  • +
+
+

1. バイナリファイル(node/cli)転送の場合

+

1-2.転送元サーバー作業

+
+
+
+

バイナリーファイルを転送フォルダ用にコピーする +

mkdir $NODE_HOME/Transfer
+cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-cli") $NODE_HOME/Transfer/cardano-cli
+cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-node") $NODE_HOME/Transfer/cardano-node
+

+

バージョン確認 +

$NODE_HOME/Transfer/cardano-cli version
+$NODE_HOME/Transfer/cardano-node version
+

+
+

希望するバージョンになっているか確認する

+
+
+
+
+

1-2.転送元から転送先へ転送する

+

変数forに転送先エイリアスを代入する

+
+
+
+

転送先エイリアスを指定する

+
for=xxxx
+
+
+

転送先エイリアスは、事前設定の 1-2.SSH設定ファイル作成 で設定した転送先Host名(エイリアス)を指定します。

+
+

ファイルを転送する +

rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-cli $for::Server/cardano-cli
+

+
+

転送が完了するまで待つ

+
+
rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-node $for::Server/cardano-node
+
+
+

転送が完了するまで待つ

+
+
+
+
+

1-3.転送先サーバー作業

+
+
+
+

ノードを停止する +

sudo systemctl stop cardano-node
+

+

バイナリーファイルをシステムフォルダーへコピーする +

sudo cp $NODE_HOME/cardano-cli /usr/local/bin/cardano-cli
+
+
sudo cp $NODE_HOME/cardano-node /usr/local/bin/cardano-node
+
+バージョン確認 +
cardano-cli version
+cardano-node version
+

+
+

希望するバージョンになっているか確認する

+
+

ノードを起動する +

sudo systemctl start cardano-node
+

+
+

ヒント

+
    +
  • GliveViewでノード状況を確認する
  • +
  • Syncing 100%がTip(diff): ** :)となるまで待つ
  • +
+
+
+
+
+

2.DBフォルダ転送の場合

+

2-1.転送元サーバー作業

+

容量確認 +転送元・転送先サーバー両方で確認してください +

df -h /usr
+
+Availが180GB以上あることを確認してください。

+
+
+
+

ノードを停止する +

sudo systemctl stop cardano-node
+

+

DBフォルダを圧縮する

+

新しいTMUXセッションを開く +

tmux new -s tar
+
+圧縮する +
tar cvzf $NODE_HOME/Transfer/cardano-db.tar.gz -C $NODE_HOME db
+

+

圧縮が終了したらTMUXを閉じる +

exit
+

+

ノードをスタートする +

sudo systemctl start cardano-node
+

+
+
+
+

2-2.転送元から転送先へ転送する

+
+
+
+

新しいTMUXセッションを開く +

tmux new -s rsync
+

+

転送先エイリアスを指定する。変数forに転送先エイリアスを代入する

+
for=xxxx
+
+
+

転送先エイリアスは、事前設定の 1-2.SSH設定ファイル作成 で設定した転送先Host名(エイリアス)を指定します。

+
+

圧縮されたDBを転送する +

rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-db.tar.gz $for::Server/cardano-db.tar.gz
+

+
+

転送が完了するまで待つ

+
+

転送が終了したらTMUXを閉じる +

exit
+

+
+
+
+

2-3.転送先サーバー作業

+

新しいTMUXセッションを開く +

tmux new -s tar
+

+
+
+
+

SSDの空き容量を再確認する +

df -h /usr
+
+Availが100GB以上あることを確認してください。

+

DBを解凍する +

mkdir $NODE_HOME/temp
+tar -xzvf $NODE_HOME/cardano-db.tar.gz -C $NODE_HOME/temp/
+

+
+

DBの解凍が終わるまで待ちます

+
+

解凍が終わったらTMUXを閉じる +

exit
+

+

ノードを停止する +

sudo systemctl stop cardano-node
+

+

DBフォルダを入れ替える +

mv $NODE_HOME/db $NODE_HOME/db_134
+mv $NODE_HOME/temp/db $NODE_HOME/db
+

+

ノードを起動する +

sudo systemctl start cardano-node
+

+
+

ヒント

+
    +
  • GliveViewでノード状況を確認する
  • +
  • Syncing 100%がTip(diff): ** :)となるまで待つ
  • +
+
+

バイナリーファイルを移動する +

cd $HOME/git
+rm -rf cardano-node-old/
+mv $HOME/git/cardano-node/ $HOME/git/cardano-node-old/
+mkdir cardano-node
+mv $NODE_HOME/cardano-cli $HOME/git/cardano-node/
+mv $NODE_HOME/cardano-node $HOME/git/cardano-node/
+

+
+

確認

+

ノードの同期が成功しブロック生成に成功し数エポック様子を見たあと、転送用ファイル・バックアップDBを削除してください

+
+
+
+
rm -rf $NODE_HOME/Transfer
+
+
+
+
rm -rf $NODE_HOME/db_134
+rm $NODE_HOME/1.35.3-db.tar.gz
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/ubuntu22/index.html b/operation/ubuntu22/index.html new file mode 100644 index 00000000..657be234 --- /dev/null +++ b/operation/ubuntu22/index.html @@ -0,0 +1,3885 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3-2.Ubuntu22.04移行 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + + + +
+ + + + + + + + +

Ubuntu20.04→22.04任意アップグレードマニュアル

+
+

アップグレード前の確認事項

+
    +
  • 2023年6月時点において、このアップグレードは任意です。
  • +
  • 20.04LTSのセキュリティサポートは2025年4月まで有効です。
  • +
  • IOGからは正式な22.04対応アナウンスはまだございませんが、内部開発・検証では22.04が使われております。
  • +
  • 22.04でのブロック生成・安定稼働確認済みです。
  • +
  • 作業前に一通り熟読し、作業フローを理解して下さい。
  • +
  • OSアップグレードのため、作業は慎重に実施してください。
  • +
+
+

1.事前準備

+

1-1.スナップショットの作成

+
+

スナップショットの作成

+

アップグレード前に必ず、VPSのサーバー管理画面から現時点のスナップショット(バックアップ)を作成してください。万一アップグレードに失敗した場合、素早く復旧できます。

+
+

1-2.SSH鍵の種類を確認する

+

SSH接続用のローカルパソコンに保存されている、SSH秘密鍵ファイルの種類を確認してください。

+
    +
  • id_rsa
  • +
  • ssh_ed25519
  • +
+

のどちらか

+

1-3.SSHターミナルバージョン最新化

+

WindowsでR-loginをご利用の場合は、RLogin-2.28.2を使用して下さい。

+

1-4.作業対象サーバログイン

+
+

接続方法

+

1-4~1-8は通常のSSH接続で作業する

+
+
+
+
+

22.04ではRSA方式が無効となっており、新しい鍵ペア(ed25519暗号方式)を作成します。

+

ペア鍵の作成

+
ssh-keygen -t ed25519 -N '' -C ssh_connect -f ~/.ssh/ssh_ed25519
+
+

ssh_ed25519(秘密鍵)とssh_ed25519.pub(公開鍵)というファイルが作成されているか確認する。

+
cd ~/.ssh
+ls
+
+

公開鍵を認証ファイルに書き込む +

cat ssh_ed25519.pub >> authorized_keys
+

+
+

SSH鍵ファイルをダウンロードする

+
    +
  1. R-loginの場合はファイル転送ウィンドウを開く
  2. +
  3. 左側ウィンドウ(ローカル側)は任意の階層にフォルダを作成する。
  4. +
  5. 右側ウィンドウ(サーバ側)は「.ssh」フォルダを選択する
  6. +
  7. 右側ウィンドウから、ssh_ed25519ssh_ed25519.pubの上で右クリックして 「ファイルのダウンロード」を選択する
  8. +
  9. 一旦サーバからログアウトする
  10. +
  11. R-Loginのサーバ接続編集画面を開き、「SSH認証鍵」をクリックし4でダウンロードしたssh_ed25519ファイルを選ぶ
  12. +
  13. サーバへ接続する
  14. +
+

※4でローカルにダウンロードしたSSH鍵ペアはバックアップを作成することをオススメします。

+
+

サーバーに接続できたことを確認して、サーバー内の鍵を削除する +

rm ~/.ssh/ssh_ed25519
+rm ~/.ssh/ssh_ed25519.pub
+

+
+
+

Ubuntu22.04に対応した暗号方式です。次の項目に移動して下さい。

+
+
+
+

1-5.ノードを停止する

+
sudo systemctl stop cardano-node
+
+

自動起動を一旦停止する +

sudo systemctl disable cardano-node
+

+

1-6.Ubuntuバージョン確認

+

現在のバージョンを確認する

+
cat /etc/os-release | grep "VERSION="
+
+
+

VERSION="20.04.x LTS (Focal Fossa)" xの数字はアップグレード時期によって変わります

+
+

アップグレード可能なバージョンを確認する

+
sudo do-release-upgrade -c | grep "New release"
+
+
+

New release '22.04.x LTS' available. xの数字はアップグレード時期によって変わります

+
+

1-7.システムアップデート

+
sudo apt full-upgrade -y
+
+

1-8.パッケージインストール

+
sudo apt install update-manager-core
+
+

1-9.システムを再起動

+
sudo reboot
+
+

2.Ubuntuアップグレード

+
+

アップグレードの注意点

+

Ubuntu22.04アップグレード(以下の作業)において、SSH接続での作業は不意な切断が発生した場合に復旧が困難になるため非推奨となっております。

+

そのため、契約事業者(VPS)のマイページまたはサーバパネルに付随しているコンソール画面(VNCまたはKVNなど)からの作業をオススメします。

+

ただし以下の点にご了承頂ける場合はSSH接続で作業することも可能です。

+
    +
  • 事前にスナップショット(バックアップ)作成が可能な方
  • +
  • 不意なSSH切断でアップグレードが中断してもご自身で復旧出来る方
  • +
+
+

SSHで作業する場合

+
    +
  • +

    予備のSSHポートを開放してください。
    +※ただしAWSやIONOSなど、VPSサーバー管理画面からファイアウォールを設定する場合は、以下のコードは実行せずVPS管理画面から設定してください。 +

    sudo ufw allow 1022/tcp
    +sudo ufw reload
    +

    +
  • +
  • +

    R-loginを使用する場合は、不意な切断を防ぐため以下の設定を行って下さい。

    +
  • +
+

「ファイル」→「サーバーに接続」→ 接続先右クリックし「接続を編集する」→「プロトコル」→ SSH枠の「KeepAlveパケット送信間隔(sec)」にチェックを入れ、空欄に20を入力する。

+
+
+

2-1.アップグレード実行

+
+

接続パターン

+
    +
  • パターン1:VPSサーバー管理画面のコンソールから接続する
  • +
  • パターン2:ローカルPCにインストールしたVNCクライアントから接続する(主にContabo)
  • +
  • パターン3:いつも通りSSHで接続する
  • +
+
+

アップグレードコマンドを実行する +

sudo do-release-upgrade
+

+

2-2.アップグレードメッセージ

+

以下、確認メッセージ例です。ご利用のサーバーによって表示内容が異なる場合があります。表示された内容をよく読んで下さい。

+
+

SSHで作業する場合

+

バックアップSSHポート開放
+y を入力してEnter +

Continue running under SSH?
+
+This session appears to be running under ssh. It is not recommended
+to perform a upgrade over ssh currently because in case of failure it
+is harder to recover.
+
+If you continue, an additional ssh daemon will be started at port
+'1022'.
+Do you want to continue?
+
+Continue [yN] y      # y を入力してEnter
+

+

sshdに1022ポート追加のお知らせ
+そのままENTER +

Starting additional sshd
+
+To make recovery in case of failure easier, an additional sshd will
+be started on port '1022'. If anything goes wrong with the running
+ssh you can still connect to the additional one.
+If you run a firewall, you may need to temporarily open this port. As
+this is potentially dangerous it's not done automatically. You can
+open the port with e.g.:
+'iptables -I INPUT -p tcp --dport 1022 -j ACCEPT'
+
+To continue please press [ENTER]  # ENTER 
+

+
+

パッケージダウンロードリポジトリ更新しますか?
+y を入力してEnter +

Updating repository information
+
+No valid mirror found
+
+While scanning your repository information no mirror entry for the
+upgrade was found. This can happen if you run an internal mirror or
+if the mirror information is out of date.
+
+Do you want to rewrite your 'sources.list' file anyway? If you choose
+'Yes' here it will update all 'focal' to 'jammy' entries.
+If you select 'No' the upgrade will cancel.
+
+Continue [yN] y      # y を入力してEnter
+

+

アップグレード開始しますか?
+y を入力してEnter +

Do you want to start the upgrade?
+
+
+3 installed packages are no longer supported by Canonical. You can
+still get support from the community.
+
+5 packages are going to be removed. 117 new packages are going to be
+installed. 629 packages are going to be upgraded.
+
+You have to download a total of 694 M. This download will take about
+2 minutes with a 40Mbit connection and about 18 minutes with a 5Mbit
+connection.
+
+Fetching and installing the upgrade can take several hours. Once the
+download has finished, the process cannot be canceled.
+
+ Continue [yN]  Details [d] y      # y を入力してEnter
+

+

libc6などのサービスを再起動しますか?
+カーソルキーでYESを選択してENTER +

+

設定ファイル更新の有無
+N を入力してEnter +

Configuration file '/etc/ssh/ssh_config'
+ ==> Modified (by you or by a script) since installation.
+ ==> Package distributor has shipped an updated version.
+   What would you like to do about it ? Your options are:
+    Y or I : install the package maintainer's version
+    N or O : keep your currently-installed version
+      D : show the differences between the versions
+      Z : start a shell to examine the situation
+ The default action is to keep your current version.
+*** ssh_config (Y/I/N/O/D/Z) [default=N] ?  N       # N を入力してEnter
+

+
+

注意

+
    +
  • この種類のメッセージは必ず N を入力して、「keep your currently-installed version(現在の設定を維持する)」を選択して下さい。
  • +
  • サーバーによってはssh_config以外にも同様のメッセージが表示される場合があります。(chrony,opne-ssh,sudoers,sysctl.confなど) いずれも N 「keep your currently-installed version(現在の設定を維持する)」を選択して下さい。
  • +
+
+

新しい設定ファイルの処理方法について
+keep the local version currently installed(インストール済みのローカルバージョンを維持する)が選択された状態でENTER +

+
+

注意

+
    +
  • この種類のメッセージは必ず 「keep the local version currently installed(インストール済みのローカルバージョンを維持する)」を選択して下さい。
  • +
  • サーバーによってはchrony以外にも同様のメッセージが表示される場合があります。(sshdなど) いずれも keep the local version currently installed(インストール済みのローカルバージョンを維持する)」を選択して下さい。
  • +
+
+

古いパッケージを削除しますか?
+y を入力してEnter +

Remove obsolete packages?
+
+
+73 packages are going to be removed.
+
+ Continue [yN]  Details [d] y      # y を入力してEnter
+

+

アップグレードが完了しました。再起動しますか?
+y を入力してEnter +

System upgrade is complete.
+
+Restart required
+
+To finish the upgrade, a restart is required.
+If you select 'y' the system will be restarted.
+
+Continue [yN] y      # y を入力してEnter
+

+

3.アップグレード確認(SSH接続)

+
+

接続方法

+

3~5はSSH接続で作業する

+
+

3-1.現在のUbuntuバージョンを確認する

+
cat /etc/os-release | grep "VERSION=" # (1)!
+
+
    +
  1. 22.04はブラケットペーストモードが有効になっているためコマンドペースト後、ENTERで実行する必要があります。
  2. +
+
+

VERSION="22.04.x LTS (Jammy Jellyfish)" xの数字はアップグレード時期によって変わります

+
+

3-2.ブラケットペーストモードOFF

+
echo "set enable-bracketed-paste off" >> ~/.inputrc
+
+

3-3.SSH再接続

+
exit
+
+
+

SSHで再接続する

+
+

4.依存関係再インストール

+

システムアップデート +

sudo apt update -y && sudo apt upgrade -y
+

+
+
+
+
sudo apt install needrestart git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y
+
+
+
+

sudo apt install needrestart git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y
+
+
pip install discordwebhook python-dotenv slackweb
+

+
+
+
+

デーモン再起動自動化 +

echo "\$nrconf{restart} = 'a';" | sudo tee /etc/needrestart/conf.d/50local.conf
+
+
echo "\$nrconf{blacklist_rc} = [qr(^cardano-node\\.service$) => 0,];" | sudo tee -a /etc/needrestart/conf.d/50local.conf
+

+ + +

自動起動有効化 +

sudo systemctl enable cardano-node
+

+

コンパイル済みHaskellパッケージ削除 +

cd ~/.cabal/store
+rm -rf ghc-8.10.7
+

+
+

SSHでアップグレードを実施した場合

+

1022ポートを削除する(AWSやIONOSなどはVPSのサーバー管理画面から) +

sudo ufw deny 1022/tcp
+sudo ufw reload
+

+
+

5. ノード再ビルド

+

既存のノードバージョンで作業内容が異なります。

+
+

既存ノード1.35系の場合

+

ノードアップデートマニュアル56以外は全て実施してください
+(RSYNCを使用しない場合3は実施不要)

+
    +
  • 1-4 BPのCNCLIが最新バージョンであっても赤枠を開いて再ビルドしてください
  • +
+
+
+

既存ノード8.1.2の場合

+

ノードアップデートマニュアル
+1-1、1-2、1-4(BPのみ)、2-1、2-2、2-3、2-5、4(BPのみ)

+
    +
  • 1-2 Cabalがアップデートされてますので必ず実施してください。
  • +
  • 1-4 BPのCNCLIが最新バージョンであっても赤枠を開いて再ビルドしてください
  • +
+
+

6. エアギャップマシンアップグレード

+

6-1. 事前準備

+
    +
  • 6-1-1.Ubuntuへログインし、主要ファイルのアクセス制限を解除する
  • +
+
cd $NODE_HOME
+chmod 700 payment.vkey
+chmod 700 payment.skey
+chmod 700 stake.vkey
+chmod 700 stake.skey
+chmod 700 stake.addr
+chmod 700 payment.addr
+chmod u+rwx $HOME/cold-keys
+
+
    +
  • +

    6-1-2.以下フォルダ内すべてのファイルを外部ストレージに退避させる

    +
  • +
  • +

    /home/user/cnode (userは各自で設定したユーザー名)

    +
  • +
  • +

    /home/cold-keys

    +
  • +
  • +

    6-1-3.退避させたら、上記ディレクトリ内のファイルをすべて削除する
    +(ディレクトリフォルダは残して下さい)

    +
  • +
  • +

    6-1-4.Ubuntuをシャットダウン(電源オフ)する

    +
  • +
+

6-2. VirtualBoxアップグレード

+

VirtualBoxのダウンロードサイトにアクセスし、VirtualBox 7.0.8 platform packagesWindows hostsまたはmacOSのリンクからダウンロードし、既存のVirtuialBoxに対して上書きインストールしてください

+ +

6-3. システムアップデート

+
    +
  • +

    6-3-1.VirtualBoxのマシン設定からネットワークを有効にする +

    +
  • +
  • +

    6-3-2.Ubuntuを起動する

    +
  • +
  • +

    6-3-3.ディスク容量を確認する

    +
  • +
+
df -h /root
+
+
+

Availの値が10G以上であることを確認する

+
+
    +
  • +

    Ubuntu設定から「電源管理」→「ブランクスクリーン」→「しない」に設定 +

    +
  • +
  • +

    アプリケーション一覧からsoftと検索し、[ソフトウェアとアップデート]を起動 +

    +
  • +
  • +

    [アップデート]タブの長期サポート(LTS)版が選択されていることを確認し、閉じる +

    +
  • +
  • +

    アプリケーション一覧からupdateと検索し、[ソフトウェアの更新]を起動 +

    +
  • +
  • +

    「今すぐインストール」をクリック。 +

    +
  • +
  • +

    インストール後再起動を求められたら再起動する。

    +
  • +
+

6-4. Ubuntuアップグレード

+
    +
  • +

    6-4-1.アプリケーション一覧からupdateと検索し、[ソフトウェアの更新]を起動 +

    +
  • +
  • +

    6-4-2.「アップグレード」をクリックする +

    +
  • +
+
+

アップグレード

+

表示された内容に沿ってアップグレードしてください。アップグレードには数十分かかります。

+
+
    +
  • 6-4-3.処理が進むと以下のような画像が表示されます。 +
  • +
+

+
    +
  • +

    6-4-4.FireFoxがインストールされている場合は以下の画像が表示されます。「NEXT」をクリックしてください。 +

    +
  • +
  • +

    6-4-5.更に処理が進み、サポート外パッケージを削除します +

    +
  • +
+

6-5. GuestAddtionsアップグレード

+
    +
  • 6-5-1.GuestAddtionsをアップグレードする +
  • +
+

+
    +
  • 6-5-2.Ubuntuをシャットダウン(電源オフ)する
  • +
+

6-6. 最終仕上げ

+
    +
  • +

    6-6-1.ネットワークオフ +

    +
  • +
  • +

    6-6-2.Ubuntuを起動する

    +
  • +
  • +

    6-6-3.ブラケットペーストモードOFF

    +
  • +
+
echo "set enable-bracketed-paste off" >> ~/.inputrc
+
+
    +
  • +

    6-6-4.退避したキーファイルをcnodeディレクトリに戻す

    +
  • +
  • +

    6-6-5.戻した主要ファイルのアクセス制限

    +
  • +
+
cd $NODE_HOME
+chmod 400 payment.vkey
+chmod 400 payment.skey
+chmod 400 stake.vkey
+chmod 400 stake.skey
+chmod 400 stake.addr
+chmod 400 payment.addr
+chmod a-rwx $HOME/cold-keys
+
+
    +
  • 6-6-6.Ubuntu22.04で再ビルドしたcardano-cliをコピーする(参考手順)
  • +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/operation/withdrawal/index.html b/operation/withdrawal/index.html new file mode 100644 index 00000000..9e489060 --- /dev/null +++ b/operation/withdrawal/index.html @@ -0,0 +1,3437 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1-3.資金引き出し - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + + + +
+ + + + + + + + +

資金引き出し

+

1 stake.addrからの引き出し

+
+

概要

+
    +
  • 報酬は stake.addr アドレスに蓄積されていきます。
  • +
  • 1回のトランザクションで引き出せる金額は残高全額のみです。
    +(分割して引き出すことはできません)
  • +
  • トランザクション手数料はpayment.addrから引き落とされます。
  • +
+

1-1 payment.addrへ送金する方法こちら

+

1-2 任意のアドレスへ送金する方法はこちら

+
+
+

注意

+

入力ミスなどで送金が失敗しても責任は負えません。自己責任のもと実施下さい。
+payment.skeystake.skeyは必ずオフライン環境で保管してください。

+
+

1-1 payment.addrへ送金する方法

+

現在のスロットを算出します

+
+
+
+
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

ステークアドレスの残高を算出します

+
+
+
+
cd $NODE_HOME
+rewardBalance=$(cardano-cli query stake-address-info \
+    $NODE_NETWORK \
+    --address $(cat stake.addr) | jq -r ".[0].rewardAccountBalance")
+echo rewardBalance: $rewardBalance
+
+
+
+
+

1 ADA = 1,000,000 lovelace.と覚えましょう

+

報酬の移動先となるpayment.addrを設定します。payment.addrには取引手数料を支払うための残高が必要です。

+
+
+
+
destinationAddress=$(cat payment.addr)
+echo destinationAddress: $destinationAddress
+
+
+
+
+

payment.addrの残高を算出します

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+withdrawalString="$(cat stake.addr)+${rewardBalance}"
+
+
+
+
+

build-raw transactionコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --withdrawal ${withdrawalString} \
+    --out-file tx.tmp
+
+
+
+
+

現在の最低料金を計算します。

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 2 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

変更出力を計算します。

+
+
+
+
txOut=$((${total_balance}-${fee}+${rewardBalance}))
+echo Change Output: ${txOut}
+
+
+
+
+

トランザクションをビルドします。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --withdrawal ${withdrawalString} \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

支払いとステークの秘密鍵の両方を使用してトランザクションに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+

署名されたトランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+

資金が到着したか確認します。

+
+
+
+
cardano-cli query utxo \
+    --address ${destinationAddress} \
+    $NODE_NETWORK
+
+
+
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+

更新されたラブレースの残高と報酬を表示します。

+
                           TxHash                                 TxIx        Lovelace
+----------------------------------------------------------------------------------------
+100322a39d02c2ead....  
+
+

1-2 任意のアドレスへ送金する方法

+

現在のスロットNoを算出します。

+
+
+
+
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

入金先アドレスを指定します。

+
+
+
+
destinationAddress=入金先アドレスを指定する
+echo destinationAddress: $destinationAddress
+
+
+
+
+

報酬アドレス残高を算出します

+
+
+
+
cd $NODE_HOME
+rewardBalance=$(cardano-cli query stake-address-info \
+    $NODE_NETWORK \
+    --address $(cat stake.addr) | jq -r ".[0].rewardAccountBalance")
+echo rewardBalance: $rewardBalance
+
+
+
+
+

payment.addr の残高を算出

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+withdrawalString="$(cat stake.addr)+${rewardBalance}"
+echo ${withdrawalString}
+
+
+
+
+

build-raw transactionコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+0 \
+    --tx-out ${destinationAddress}+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --withdrawal ${withdrawalString} \
+    --out-file tx.tmp
+
+
+
+
+

現在の最低料金を計算します。

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 2 \
+    $NODE_NETWORK \
+    --witness-count 2 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

変更出力を計算します。

+
+
+
+
txOut=$((${total_balance}-${fee}))
+echo Change Output: ${txOut}
+
+
+
+
+

トランザクションをビルドします。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --tx-out ${destinationAddress}+${rewardBalance} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --withdrawal ${withdrawalString} \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

支払いとステークの秘密鍵の両方を使用してトランザクションに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+

tx.signedブロックプロデューサノードのcnodeディレクトリにコピーします。

+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+

署名されたトランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+

資金が到着したか確認します。

+
+
+
+
cardano-cli query utxo \
+    --address ${destinationAddress} \
+    $NODE_NETWORK
+
+
+
+
+

更新されたラブレースの残高と報酬を表示します。

+
                           TxHash                                 TxIx        Lovelace
+----------------------------------------------------------------------------------------
+100322a39d02c2ead....  
+
+

2 Payment.addrからの引き出し

+
+

概要

+

payment.addrから任意のアドレスへ送信する例です

+
+
+

注意

+
    +
  • 入力ミスなどで送金が失敗しても責任は負えません。自己責任のもと実施下さい。
  • +
  • 宣言した誓約(Pledge)分まで引き出してしまうと、プール報酬がゼロになりますのでご注意ください
  • +
  • payment.skeystake.skeyは必ずオフライン環境で保管してください。
  • +
+
+

最新のスロット番号を取得します

+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

lovelace形式で送信する金額を設定します。1 ADA = 1,000,000 lovelace で覚えます。

+
+
+
+
amountToSend=10000000
+echo amountToSend: $amountToSend
+
+
+
+
+

送金先のアドレスを設定します。

+
+
+
+
destinationAddress=送金先アドレス
+echo destinationAddress: $destinationAddress
+
+
+
+
+

payment.addrの残高を算出します。

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

build-rawトランザクションコマンドを実行します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+0 \
+    --tx-out ${destinationAddress}+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --out-file tx.tmp
+
+
+
+
+

最低手数料を出力します

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 2 \
+    $NODE_NETWORK \
+    --witness-count 1 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

計算結果を出力します。

+
+
+
+
txOut=$((${total_balance}-${fee}-${amountToSend}))
+echo Change Output: ${txOut}
+
+
+
+
+

トランザクションファイルを構築します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --tx-out ${destinationAddress}+${amountToSend} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

トランザクションに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+

tx.signed をブロックプロデューサーノードのcnodeディレクトリにコピーします。

+
+

ファイル転送

+

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+

署名されたトランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+

入金されているか確認します。

+
+
+
+
cardano-cli query utxo \
+    --address ${destinationAddress} \
+    $NODE_NETWORK \
+
+
+
+
+

先程指定した金額と一致していれば問題ないです。

+
                           TxHash                                 TxIx        Lovelace
+----------------------------------------------------------------------------------------
+100322a39d02c2ead....                                              0        10000000
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/overrides/main.html b/overrides/main.html new file mode 100644 index 00000000..31c91aa6 --- /dev/null +++ b/overrides/main.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{% block extrahead %} + {% set title = config.site_name %} + {% if page and page.meta and page.meta.title %} + {% set title = title ~ " - " ~ page.meta.title %} + {% elif page and page.title and not page.is_homepage %} + {% set title = title ~ " - " ~ page.title %} + {% endif %} + + + + + + + + + + + + +{% endblock %} \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..7b7865a3 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["ja"],"separator":"[\\s\\-\u3000\u3001\u3002\uff0c\uff0e]+","pipeline":["stemmer"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"\u30ab\u30eb\u30c0\u30ce\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u69cb\u7bc9\u30ac\u30a4\u30c9","text":"

SPO JAPAN GUILD\u3067\u306f\u3001\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5206\u6563\u5316\u4fc3\u9032\u6d3b\u52d5\u306e\u4e00\u74b0\u3067\u3001\u65e5\u672c\u4eba\u5411\u3051\u306bSPO\u69cb\u7bc9\u30fb\u904b\u7528\u30de\u30cb\u30e5\u30a2\u30eb\u30fb\u30b5\u30dd\u30fc\u30c8\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u3092\u6574\u5099\u3057\u3066\u304a\u308a\u3001\u30ab\u30eb\u30c0\u30ce\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u306b\u5fc5\u8981\u306a\u77e5\u8b58\u3092\u7fd2\u5f97\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

\u60c5\u5831

\u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u306f\u3001\u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9v8.7.3\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002 \u6700\u7d42\u66f4\u65b0\u65e5\uff1a2024\u5e741\u670827\u65e5 guide version 13.0.1

\u30b5\u30dd\u30fc\u30c8

\u30b5\u30dd\u30fc\u30c8\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001\u30c7\u30a3\u30b9\u30b3\u30fc\u30c9SPO JAPAN GUILD\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u3067\u73fe\u5f79\u306eSPO\u306b\u8cea\u554f\u3067\u304d\u307e\u3059

"},{"location":"#_2","title":"\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3068\u306f\uff1f","text":"

\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30b3\u30f3\u30bb\u30f3\u30b5\u30b9\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0\u306fPoS\u3092\u63a1\u7528\u3057\u3001Cardano\u30ce\u30fc\u30c9\u3092\u904b\u7528\u3059\u308b\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306b\u3088\u3063\u3066\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\u3068\u30d6\u30ed\u30c3\u30af\u751f\u6210\u3092\u62c5\u5f53\u3057\u307e\u3059\u3002

"},{"location":"#spo","title":"SPO\u3068\u306f\uff1f","text":"

SPO\uff1dStake Pool Operator \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u904b\u7528\u3059\u308b\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u3092\u6307\u3057\u307e\u3059\u3002\u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9\u3092\u9069\u5207\u306b\u904b\u7528\u30fb\u76e3\u8996\u3057\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u7dad\u6301\u3057\u307e\u3059\u3002

"},{"location":"#spo_1","title":"SPO\u306e\u5fc5\u9808\u30b9\u30ad\u30eb","text":"

\u30ab\u30eb\u30c0\u30ce\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u904b\u55b6\u3059\u308b\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u30b9\u30ad\u30eb\u3092\u5fc5\u8981\u3068\u3057\u307e\u3059\u3002

  • \u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9\u3092\u7d99\u7d9a\u7684\u306b\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3001\u5b9f\u884c\u3001\u7dad\u6301\u3059\u308b\u904b\u7528\u30b9\u30ad\u30eb
  • \u30ce\u30fc\u30c9\u309224\u6642\u9593\u5e74\u4e2d\u7121\u4f11\u3067\u7dad\u6301\u3059\u308b\u30b3\u30df\u30c3\u30c8
  • \u30b7\u30b9\u30c6\u30e0\u904b\u7528\u30b9\u30ad\u30eb
  • \u30b5\u30fc\u30d0\u7ba1\u7406\u30b9\u30ad\u30eb (\u904b\u7528\u304a\u3088\u3073\u4fdd\u5b88)
  • \u958b\u767a\u3068\u904b\u7528\u7d4c\u9a13 (DevOps)
  • \u30b5\u30fc\u30d0\u5f37\u5316\u3068\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306b\u95a2\u3059\u308b\u30b9\u30ad\u30eb
"},{"location":"#spo_2","title":"SPO\u306f\u4f55\u3092\u3059\u308b\u306e\u304b\uff1f","text":"
  • \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u69cb\u7bc9
  • \u30b5\u30fc\u30d0\u30fc(\u30ce\u30fc\u30c9)\u76e3\u8996
  • \u5272\u308a\u5f53\u3066\u30d6\u30ed\u30c3\u30af\u751f\u6210 \u203b\u30ce\u30fc\u30c9\u8a2d\u5b9a\u304c\u6b63\u3057\u3051\u308c\u3070\u81ea\u52d5\u751f\u6210\u3055\u308c\u307e\u3059
  • \u30de\u30fc\u30b1\u30c6\u30a3\u30f3\u30b0\u30fb\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u8ca2\u732e\u6d3b\u52d5
"},{"location":"#_3","title":"\u904b\u7528\u30b3\u30b9\u30c8","text":"\u9805\u76ee \u30b3\u30b9\u30c8 \u30d7\u30fc\u30eb\u767b\u9332\u6599(\u521d\u56de\u306e\u307f) 500ADA \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u767a\u884c\u6599(\u521d\u56de\u306e\u307f) 2ADA \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u624b\u6570\u6599 \u6570ADA \u30b5\u30fc\u30d0\u30fc\u4ee3(\u6700\u5c0f\u69cb\u6210\uff12\u53f0)/\u6708 16000\u5186\uff5e32000\u5186"},{"location":"#_4","title":"\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c","text":"

\u2460\uff0b\uff08 \u30d7\u30fc\u30eb\u7dcf\u5831\u916c - \u2460 \uff09* \u2461\uff1d\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c

\u9805\u76ee \u5831\u916c \u2460\u56fa\u5b9a\u5831\u916c \u6700\u4f4e170ADA\u304b\u3089\u8a2d\u5b9a\u53ef\u80fd \u2461\u5909\u52d5\u5831\u916c 0%\uff5e100%\u307e\u3067\u8a2d\u5b9a\u53ef\u80fd

\u6ce8\u610f

\u203b\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c\u8a2d\u5b9a\u5024\u304c\u5927\u304d\u304f\u306a\u308c\u3070\u306a\u308b\u307b\u3069\u59d4\u4efb\u8005\u306e\u5831\u916c\u304c\u6e1b\u5c11\u3057\u307e\u3059

"},{"location":"#_5","title":"\u30b5\u30fc\u30d0\u30fc\u30b9\u30da\u30c3\u30af\u8981\u4ef6","text":"\u6700\u5c0f\u69cb\u6210\u63a8\u5968\u69cb\u6210 \u9805\u76ee \u8981\u4ef6 \u30b5\u30fc\u30d0\u30fc BP\u75281\u53f0 \u30ea\u30ec\u30fc\u75281\u53f0 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f31\u53f0 OS 64-bit Linux (Ubuntu 20.04 LTS) CPU 2Ghz\u4ee5\u4e0a 2\u30b3\u30a2\u306eIntel\u307e\u305f\u306fAMD x86\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc \u30e1\u30e2\u30ea 24GB \u30b9\u30c8\u30ec\u30fc\u30b8 300GB \u30cd\u30c3\u30c8\u30ef\u30fc\u30af 10Mbps \u5e2f\u57df 1\u6642\u9593\u3042\u305f\u308a1GB\u306e\u5e2f\u57df \u96fb\u529b 24\u6642\u9593365\u65e5\u5b89\u5b9a\u4f9b\u7d66 ADA 600ADA \u9805\u76ee \u8981\u4ef6 \u30b5\u30fc\u30d0\u30fc BP\u75281\u53f0 \u30ea\u30ec\u30fc\u75282\u53f0 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f31\u53f0 OS 64-bit Linux (Ubuntu 20.04 LTS) CPU 2Ghz\u4ee5\u4e0a 4\u30b3\u30a2\u306eIntel\u307e\u305f\u306fAMD x86\u30d7\u30ed\u30bb\u30c3\u30b5\u30fc \u30e1\u30e2\u30ea 24GB over \u30b9\u30c8\u30ec\u30fc\u30b8 300GB\u4ee5\u4e0a \u30cd\u30c3\u30c8\u30ef\u30fc\u30af 100Mbps \u5e2f\u57df \u7121\u5236\u9650 \u96fb\u529b 24\u6642\u9593365\u65e5\u5b89\u5b9a\u4f9b\u7d66 ADA \u7121\u5236\u9650"},{"location":"#_6","title":"\u30b5\u30fc\u30d0\u30fc\u69cb\u6210\u30a4\u30e1\u30fc\u30b8","text":"

\u6700\u5c0f\u69cb\u6210

    flowchart BT\n        a2[\u30ea\u30ec\u30fc1] <-- \u958b\u653eFW --> a4[\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af]\n        subgraph ide1[\u30d7\u30fc\u30eb]\n            subgraph \u30ea\u30ec\u30fcIP\u6307\u5b9aFW\n                a1[BP]\n            end\n        a1[BP] <--> a2[\u30ea\u30ec\u30fc1]\n        end\n        c1[PC] --> ide1\n        c1[PC] --> \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7

\u63a8\u5968\u69cb\u6210

    flowchart BT\n        a2[\u30ea\u30ec\u30fc1] & a3[\u30ea\u30ec\u30fc2] <-- \u958b\u653eFW --> a4[\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af]\n        subgraph ide1[\u30d7\u30fc\u30eb]\n            subgraph \u30ea\u30ec\u30fcIP\u6307\u5b9aFW\n                a1[BP]\n            end\n                a1[BP] <--> a2[\u30ea\u30ec\u30fc1] & a3[\u30ea\u30ec\u30fc2]\n        end\n        c1[PC] --> ide1\n        c1[PC] --> \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7

\u30b5\u30dd\u30fc\u30c8

\u30b5\u30dd\u30fc\u30c8\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001SPO JAPAN GUILD\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u3067\u73fe\u5f79\u306eSPO\u306b\u8cea\u554f\u3067\u304d\u307e\u3059

"},{"location":"#_7","title":"\u30b5\u30fc\u30d0\u30fc\u9078\u5b9a\u306b\u3064\u3044\u3066","text":"

\u30ab\u30eb\u30c0\u30ce\u306f\u6700\u3082\u5206\u6563\u5316\u3055\u308c\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5411\u4e0a\u3092\u76ee\u6307\u3057\u3066\u304a\u308a\u3001\u4e16\u754c\u4e2d\u306b\u5206\u6563\u3055\u308c\u305f\u30ce\u30fc\u30c9\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u5f62\u6210\u304c\u3001\u30ab\u30eb\u30c0\u30ce\u306b\u3068\u3063\u3066\u6700\u3082\u91cd\u8981\u306b\u306a\u308a\u307e\u3059\u3002 \u3053\u306e\u3053\u3068\u304b\u3089\u3001\u5f53\u30ae\u30eb\u30c9\u5185\u3067\u306f\u300c\u304a\u3059\u3059\u3081\u306e\u30b5\u30fc\u30d0\u30fc(VPS)\u696d\u8005\u300d\u306e\u60c5\u5831\u5171\u6709\u306f\u884c\u3063\u3066\u304a\u308a\u307e\u305b\u3093\u306e\u3067\u3001\u5404\u81ea\u3067\u9078\u5b9a\u3092\u304a\u9858\u3044\u81f4\u3057\u307e\u3059\u3002

"},{"location":"#_8","title":"\u304a\u8a66\u3057\u30ce\u30fc\u30c9\u8d77\u52d5","text":"
  • Linux\u30b5\u30fc\u30d0\u306e\u30b3\u30de\u30f3\u30c9\u3084\u3001\u30ce\u30fc\u30c9\u8d77\u52d5\u306a\u3069\u304a\u8a66\u3057\u30c6\u30b9\u30c8\u3067\u3084\u3063\u3066\u307f\u305f\u3044\u65b9\u306f\u3001\u624b\u5143\u306e\u30d1\u30bd\u30b3\u30f3\u3067\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u74b0\u5883\u3092\u69cb\u7bc9\u5f8c\u3001\u30d7\u30fc\u30eb\u69cb\u7bc9\u30de\u30cb\u30e5\u30a2\u30eb\u306e2. \u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u3084\u3063\u3066\u307f\u307e\u3057\u3087\u3046\uff01
  • \u3053\u306e\u9805\u76ee\u306f\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306b\u306f\u76f4\u63a5\u7684\u306b\u5f71\u97ff\u304c\u306a\u3044\u306e\u3067\u3001\u305f\u3068\u3048\u9593\u9055\u3063\u305f\u30b3\u30de\u30f3\u30c9\u3092\u9001\u4fe1\u3057\u3066\u3082\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b\u306f\u554f\u984c\u3054\u3056\u3044\u307e\u305b\u3093\u3002
"},{"location":"changelogs/","title":"\u5909\u66f4\u5c65\u6b74","text":""},{"location":"changelogs/#2024127-ver-1301","title":"2024/1/27\u3000ver. 13.0.1","text":"
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0
    • cncli.sh \u540c\u671f\u30a8\u30e9\u30fc\u306e\u5bfe\u51e6\u6cd5\u8ffd\u52a0
    • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#2024126-ver-1300","title":"2024/1/26\u3000ver. 13.0.0","text":"
  • \u63a8\u5968\u30b5\u30fc\u30d0\u30fc\u30b9\u30da\u30c3\u30af\u5909\u66f4 RAM 16GB\u219224GB / SSD 200GB\u2192300GB

  • Cardano-node8.7.3\u5bfe\u5fdc

  • \u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806

    • blst\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u8ffd\u52a0
    • GHCUP\u5909\u6570\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5c0e\u5165
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0

    • cardano-node v8.7.3\u5bfe\u5fdc
    • \u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u306e\u4f7f\u7528
    • Mithril\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u306e\u5c0e\u5165
  • \u30b5\u30fc\u30d0\u30fc\u5f15\u8d8a\u3057\u624b\u9806\u8ffd\u52a0 \u30ea\u30ec\u30fc\u7528 / BP\u7528

  • Grafana\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a Grafana\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u5bfe\u5fdc

  • SJG TOOL v3.7.0\u30ea\u30ea\u30fc\u30b9

    • CLI 8.17.0.0\u5bfe\u5fdc
    • \u30c7\u30a3\u30b9\u30af\u7a7a\u304d\u5bb9\u91cf\u3068DB\u5bb9\u91cf\u8868\u793a\u8ffd\u52a0
"},{"location":"changelogs/#202415-ver-1295","title":"2024/1/5\u3000ver. 12.9.5","text":"
  • \u30d7\u30fc\u30eb\u60c5\u5831(pool.cert)\u306e\u66f4\u65b0 \u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u306bnonce\u5024\u3092\u8ffd\u52a0 \u30d7\u30fc\u30eb\u60c5\u5831\u66f4\u65b0\u6642\u306b\u304a\u3044\u3066\u30e1\u30bf\u30c7\u30fc\u30bfURL\u306e\u307f\u306e\u5909\u66f4\u3067\u3001\u540c\u4e00\u30d5\u30a1\u30a4\u30eb(\u30cf\u30c3\u30b7\u30e5\u5024)\u3092\u4f7f\u7528\u3057\u305f\u5834\u5408\u3001SMASH\u30b5\u30fc\u30d0\u30fc\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u8aad\u307f\u8fbc\u307f\u306b\u304a\u3044\u3066\u53c2\u7167\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u304c\u53d6\u308c\u305a\u3001KoiosAPI\u3067\u3082\u30c7\u30fc\u30bf\u53c2\u7167\u51fa\u6765\u306a\u3044\u305f\u3081\u30e1\u30bf\u30c7\u30fc\u30bf\u306bnonce\u5024\u3092\u8a2d\u5b9a\u3057\u7570\u306a\u308b\u30cf\u30c3\u30b7\u30e5\u5024\u3067\u30c1\u30a7\u30fc\u30f3\u306b\u767b\u9332\u3059\u308b\u4ed5\u69d8\u3078\u5909\u66f4\u3002
"},{"location":"changelogs/#20231230-ver-1294","title":"2023/12/30\u3000ver. 12.9.4","text":"
  • Ubuntu22.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u624b\u9806 \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20231220-ver-1293","title":"2023/12/20\u3000ver. 12.9.3","text":"
  • 8.1.2\u7528\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5143\u5909\u66f4
"},{"location":"changelogs/#20231129-ver-1292","title":"2023/11/29\u3000ver. 12.9.2","text":"
  • SJG TOOL v3.6.4\u30ea\u30ea\u30fc\u30b9
  • \u30d7\u30fc\u30ebID\u30d5\u30a1\u30a4\u30eb\u540d\u5909\u66f4 stakepoolid_hex \u2192 pool.id stakepoolid_bech32 \u2192 pool.id-bech32
"},{"location":"changelogs/#20231125-ver-1291","title":"2023/11/25\u3000ver. 12.9.1","text":"
  • \u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u6642\u306eP2P\u8a2d\u5b9a\u3092\u524a\u9664
"},{"location":"changelogs/#20231120-ver-1290","title":"2023/11/20\u3000ver. 12.9.0","text":"
  • R-Login\u4f7f\u7528\u6642\u306e\u63a8\u5968\u8a2d\u5b9a\u3092\u63b2\u8f09 Ubuntu\u521d\u671f\u8a2d\u5b9a
  • Tracemempool\u521d\u671f\u5024\u5909\u66f4\u5bfe\u5fdc
  • SPO\u30df\u30fc\u30c6\u30a3\u30f3\u30b0\u8b70\u4e8b\u9332\u30ea\u30f3\u30af\u63b2\u8f09 SJG\u30e9\u30fc\u30cb\u30f3\u30b0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20231028-ver-1289","title":"2023/10/28\u3000ver. 12.8.9","text":"
  • minPoolCost\u5909\u66f4\u306b\u4f34\u3046\u8868\u8a18\u304a\u3088\u3073\u30b3\u30de\u30f3\u30c9\u4fee\u6b63
  • Grafana\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a\u306bKES\u6b8b\u65e5\u6570\u3068\u30c7\u30a3\u30b9\u30af\u5bb9\u91cf\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230927-ver-1288","title":"2023/09/27\u3000ver. 12.8.8","text":"
  • DB\u540c\u671f(Mithril)\u30d9\u30fc\u30bf\u7248\u624b\u9806\u8ffd\u52a0
"},{"location":"changelogs/#20230919-ver-1287","title":"2023/09/19\u3000ver. 12.8.7","text":"
  • Grafana\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u624b\u9806\u4fee\u6b63
  • Grafana\u30ea\u30dd\u30b8\u30c8\u30ea \u66f4\u65b0\u624b\u9806\u8ffd\u52a0
  • \u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u30ce\u30fc\u30c9\u30d3\u30eb\u30c9\u524d\u306bTMUX\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230811-ver-1286","title":"2023/08/11\u3000ver. 12.8.6","text":"
  • Ubuntu22.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u624b\u9806 BP\u306b\u304a\u3051\u308bCNCLI\u518d\u30d3\u30eb\u30c9\u6ce8\u610f\u66f8\u304d\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230725-ver-1285","title":"2023/07/25\u3000ver. 12.8.5","text":"
  • Cardano-node8.1.2\u5bfe\u5fdc
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0
"},{"location":"changelogs/#20230718-ver-1284","title":"2023/07/18\u3000ver. 12.8.4","text":"
  • SJG TOOL v3.6.0\u30ea\u30ea\u30fc\u30b9(Catalyst\u6709\u6a29\u8005\u767b\u9332\u6a5f\u80fd\u5b9f\u88c5)
  • Catalyst\u6709\u6a29\u8005\u767b\u9332 Catalyst\u6709\u6a29\u8005\u767b\u9332\u3092\u8ffd\u52a0
"},{"location":"changelogs/#20230718-ver-1283","title":"2023/07/18\u3000ver. 12.8.3","text":"
  • KES\u66f4\u65b0 \u65e2\u5b58\u30d5\u30a1\u30a4\u30eb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u624b\u9806\u8ffd\u52a0
  • \u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 Prometheus.yml\u69cb\u6587\u30c1\u30a7\u30c3\u30af\u8ffd\u52a0
"},{"location":"changelogs/#20230627-ver-1282","title":"2023/06/27\u3000ver. 12.8.2","text":"
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806 2-6\u30922-5\u3078\u7d71\u5408
  • Ubuntu22.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u624b\u9806 \u300c3-3.\u30c7\u30fc\u30e2\u30f3\u518d\u8d77\u52d5\u81ea\u52d5\u5316\u300d\u3092\u8ffd\u52a0
  • 1.Ubuntu\u521d\u671f\u8a2d\u5b9a \u300cUbuntu22.04\u306e\u5834\u5408\u306e\u7279\u5225\u8a2d\u5b9a\u300d\u3092\u8ffd\u52a0
  • Grafana\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a 2-2\u4fee\u6b63
  • 7.\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306e\u767b\u9332\u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u4f5c\u6210\u65b9\u6cd5\u3092\u5909\u66f4
"},{"location":"changelogs/#20230620-ver-1281","title":"2023/06/20\u3000ver. 12.8.1","text":"
  • Ubuntu22.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u624b\u9806\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u66f4\u65b0\u624b\u9806\u4fee\u6b63
"},{"location":"changelogs/#20230620-ver-1280","title":"2023/06/20\u3000ver. 12.8.0","text":"
  • Cardano-node8.1.1\u5bfe\u5fdc
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0
  • Ubuntu22.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u624b\u9806\u8ffd\u52a0
  • SJG\u30e9\u30fc\u30cb\u30f3\u30b0\u8cc7\u6599\u8ffd\u52a0
  • [\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u8a2d\u5b9a]\u30c8\u30dd\u30ed\u30b8\u30fc\u30ea\u30ed\u30fc\u30c9\u7528\u74b0\u5883\u5909\u6570\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230518-ver-1271","title":"2023/05/18\u3000ver. 12.7.1","text":"
  • SJG TOOL v3.5\u30ea\u30ea\u30fc\u30b9(SPO\u6295\u7968\u6a5f\u80fd\u5b9f\u88c5)
  • SPO\u6295\u7968\u30e1\u30a4\u30f3\u30cd\u30c3\u30c8\u624b\u9806\u8ffd\u52a0
"},{"location":"changelogs/#20230513-ver-1270","title":"2023/05/13\u3000ver. 12.7.0","text":"
  • Cardano-node8.0.0\u5bfe\u5fdc
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0
"},{"location":"changelogs/#20230504-ver-1263","title":"2023/05/04\u3000ver. 12.6.3","text":"
  • SPO\u6295\u7968(\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8)\u624b\u9806\u8ffd\u52a0
"},{"location":"changelogs/#20230413-ver-1262","title":"2023/04/13\u3000ver. 12.6.2","text":"
  • CNCLI 5.3.2 musl\u30d3\u30eb\u30c9\u5bfe\u5fdc
"},{"location":"changelogs/#20230404-ver-1261","title":"2023/04/04\u3000ver. 12.6.1","text":"
  • CNCLI 5.3.2\u5bfe\u5fdc
  • P2P\u8a2d\u5b9a\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u8ffd\u52a0
"},{"location":"changelogs/#20230404-ver-1260","title":"2023/04/04\u3000ver. 12.6.0","text":"
  • Cardano-node1.35.7\u5bfe\u5fdc
  • [\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u8a2d\u5b9a] \u30de\u30cb\u30e5\u30a2\u30eb\u8ffd\u52a0
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30c6\u30b9\u901a\u77e5 v1.9.3
  • SJG\u30e9\u30fc\u30cb\u30f3\u30b0\u8cc7\u6599\u8ffd\u52a0
"},{"location":"changelogs/#20230307-ver-1251","title":"2023/03/07\u3000ver. 12.5.1","text":"
  • [\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7] prometheus.yml\u5185\u5bb9\u4fee\u6b63
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30c6\u30b9\u901a\u77e5 v1.9.0
"},{"location":"changelogs/#20230307-ver-1250","title":"2023/03/07\u3000ver. 12.5.0","text":"
  • Grafana\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u8a2d\u5b9a\u8ffd\u52a0
  • Grafana\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a\u8ffd\u52a0
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30c6\u30b9\u901a\u77e5 v1.8.9 \u3000\u901a\u77e5\u8a2d\u5b9a\u6709\u7121\u691c\u77e5\u3001\u8d77\u52d5\u6642\u901a\u77e5\u6a5f\u80fd\u8ffd\u52a0
  • CNCLI5.3.1\u5bfe\u5fdc
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230210-ver-1248","title":"2023/02/10\u3000ver. 12.4.8","text":"
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30c6\u30b9\u901a\u77e5 v1.8.6 \u3000\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u81ea\u52d5\u5316\u6a5f\u80fd\u8ffd\u52a0
"},{"location":"changelogs/#20230208-ver-1247","title":"2023/02/08\u3000ver. 12.4.7","text":"
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30c6\u30b9\u901a\u77e5 v1.8 \u3000\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u81ea\u52d5\u5316\u6a5f\u80fd\u8ffd\u52a0
"},{"location":"changelogs/#20230204-ver-1246","title":"2023/02/04\u3000ver. 12.4.6","text":"
  • CNCLI5.3.0\u5bfe\u5fdc
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230129-ver-1245","title":"2023/01/29\u3000ver. 12.4.5","text":"
  • Cardano-node1.35.5\u5bfe\u5fdc
  • cncli.sh\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8
  • \u30d6\u30ed\u30c3\u30af\u30ed\u30b0 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u624b\u9806\u3092\u5909\u66f4
  • \u8ca2\u732e\u8005\u30da\u30fc\u30b8\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230123-ver-1244","title":"2023/01/23\u3000ver. 12.4.4","text":"
  • SJG\u30e9\u30fc\u30cb\u30f3\u30b0\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20230105-ver-1243","title":"2023/01/05\u3000ver. 12.4.3","text":"
  • \u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u5897\u8a2d\u30de\u30cb\u30e5\u30a2\u30eb\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20221220-ver-1242","title":"2022/12/20\u3000ver. 12.4.2","text":"
  • \u6700\u65b0\u30ea\u30ea\u30fc\u30b91.35.4\u30d3\u30eb\u30c9\u5931\u6557\u306e\u56de\u907f\u30b3\u30de\u30f3\u30c9\u3092\u8ffd\u8a18
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20221203-ver-1241","title":"2022/12/03\u3000ver. 12.4.1","text":"
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20221202-ver-1240","title":"2022/12/02\u3000ver. 12.4.0","text":"
  • Cardano-node1.35.4\u5bfe\u5fdc
  • prometheus-node-exporter1.5.0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u8ffd\u52a0 (9.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3001\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8)
  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u4f5c\u6210 \u30da\u30fc\u30b8\u65b0\u8a2d\u3002Version7\u5bfe\u5fdc
  • 1.Ubuntu\u521d\u671f\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u306e\u4e00\u90e8\u3092\u5909\u66f4 (\u8a2d\u5b9a\u304c\u5fc5\u8981\u306a\u5404\u30da\u30fc\u30b8(3-\u30ea\u30ec\u30fc/BP\u306e\u63a5\u7d9a\u30019.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7)\u3078\u79fb\u52d5)
  • \u30ea\u30ec\u30fc2\u53f0\u76ee\u4ee5\u964d\u306e\u8a2d\u5b9a\u624b\u9806\u3092\u5404\u30da\u30fc\u30b8\u306b\u8ffd\u52a0
  • Grafana\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u66f4\u65b0\u3002 (KoiosAPI\u3092\u5229\u7528\u3057\u30c6\u30a3\u30c3\u30ab\u30fc\u540d\u3001\u30d7\u30fc\u30eb\u59d4\u4efb\u91cf\u3001\u59d4\u4efb\u8005\u6570\u60c5\u5831\u8868\u793a)
  • \u30d7\u30fc\u30eb\u904b\u7528\u30ac\u30a4\u30c9\u30ab\u30c6\u30b4\u30ea\u3092\u6574\u7406
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20221017-ver-1236","title":"2022/10/17\u3000ver. 12.3.6","text":"
  • 2. \u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u30ce\u30fc\u30c9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5143URL\u3092\u5909\u66f4
  • config\u30d5\u30a1\u30a4\u30eb\u4fee\u6b63\u5185\u5bb9\u30b3\u30de\u30f3\u30c9\u5316
  • \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u3082\u30ed\u30b0\u51fa\u529b\u3059\u308b\u3088\u3046\u624b\u9806\u4fee\u6b63
  • \u63a5\u7d9a\u3059\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af(\u30e1\u30a4\u30f3\u30cd\u30c3\u30c8/\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8)\u3092\u9078\u629e\u53ef\u80fd\u306b\u3059\u308b\u30b3\u30de\u30f3\u30c9\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20220910-ver-1235","title":"2022/09/10\u3000ver. 12.3.5","text":"
  • 9.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7 (\u9805\u76ee9\u306eJSON\u30d5\u30a1\u30a4\u30eb\u3092\u5909\u66f4)
  • SPO JAPAN GUILD TOOL v3.3.0 \u30ea\u30ea\u30fc\u30b9
"},{"location":"changelogs/#20220828-ver-1234","title":"2022/08/28\u3000ver. 12.3.4","text":"
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u5185\u3001\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7secp256k1\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u624b\u9806\u4fee\u6b63
"},{"location":"changelogs/#20220827-ver-1233","title":"2022/08/27\u3000ver. 12.3.3","text":"
  • logMonitor.sh\u53d6\u5f97\u5148\u3092\u5909\u66f4
"},{"location":"changelogs/#20220827-ver-1232","title":"2022/08/27\u3000ver. 12.3.2","text":"
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u4e00\u90e8\u4fee\u6b63
  • SSH\u8a8d\u8a3c\u9375\u30d5\u30a1\u30a4\u30eb\u751f\u6210\u30b3\u30fc\u30c9\u3092SHA2\u306b\u5909\u66f4
"},{"location":"changelogs/#20220825-ver-1231","title":"2022/08/25\u3000ver. 12.3.1","text":"
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u4e00\u90e8\u4fee\u6b63
"},{"location":"changelogs/#20220825-ver-1230","title":"2022/08/25\u3000ver. 12.3.0","text":"
  • cardano-node v1.35.3 \u306b\u5bfe\u5fdc
  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u4f5c\u6210\u624b\u9806\u66f4\u65b0
  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u624b\u9806\u66f4\u65b0
  • SFTP\u30bd\u30d5\u30c8\u8a2d\u5b9a\u624b\u9806\u8ffd\u52a0
"},{"location":"changelogs/#20220724-ver-1220","title":"2022/07/24\u3000ver. 12.2.0","text":"
  • RSYNC+SSH\u30b5\u30fc\u30d0\u30fc\u9593\u8ee2\u9001\u8a2d\u5b9a\u624b\u9806\u8ffd\u52a0
"},{"location":"changelogs/#20220606-ver-1211","title":"2022/06/06\u3000ver. 12.1.1","text":"
  • env\u30d5\u30a1\u30a4\u30eb\u306eCCLI\u884c\u306bRTS\u30d5\u30e9\u30b0\u3092\u8ffd\u52a0
  • \u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20220530-ver-121","title":"2022/05/30\u3000ver. 12.1","text":"
  • \u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u30b3\u30fc\u30c9\u3092\u4fee\u6b63 \u3000\u30ce\u30fc\u30c9\u8d77\u52d5\u30b3\u30de\u30f3\u30c9\u306b\u30ac\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u554f\u984c\u306b\u5bfe\u5fdc\u3057\u305fRTS\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0
"},{"location":"changelogs/#20220510-ver-120","title":"2022/05/10\u3000ver. 12.0","text":"
  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u4f5c\u6210\u624b\u9806\u3092\u8ffd\u52a0
  • Linux\u30b3\u30de\u30f3\u30c9\u96c6\u3092\u8ffd\u52a0
  • SJG Tool\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7
  • \u305d\u306e\u4ed6\u8efd\u5fae\u306a\u4fee\u6b63
"},{"location":"changelogs/#20220420-ver-114","title":"2022/04/20\u3000ver. 11.4","text":"
  • \u30ce\u30fc\u30c9\u8d77\u52d5\u30fb\u518d\u8d77\u52d5\u30fb\u505c\u6b62\u30a8\u30a4\u30ea\u30a2\u30b9\u30b3\u30de\u30f3\u30c9\u8ffd\u52a0 (2-\u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb)
  • \u5bc4\u4ed8\u5148\u30a2\u30c9\u30ec\u30b9\u306bada $handle\u3092\u8ffd\u52a0
"},{"location":"changelogs/#20220414-ver-113","title":"2022/04/14\u3000ver. 11.3","text":"
  • SPO JAPAN GUILD TOOL\u3092\u30ea\u30ea\u30fc\u30b9
"},{"location":"changelogs/#20220407-ver-112","title":"2022/04/07\u3000ver. 11.2","text":"
  • payment.addr\u306b\u30cd\u30a4\u30c6\u30a3\u30d6\u30c8\u30fc\u30af\u30f3\u304c\u542b\u307e\u308c\u3066\u3044\u308b\u5834\u5408\u306eTx\u9001\u4fe1\u30a8\u30e9\u30fc\u4fee\u6b63 \u30d7\u30fc\u30eb\u60c5\u5831\u306e\u66f4\u65b0 / \u8cc7\u91d1\u5f15\u304d\u51fa\u3057 / \u30d7\u30fc\u30eb\u5ec3\u6b62
  • \u904b\u7528\u30ac\u30a4\u30c9\u5185\u30ea\u30f3\u30af\u4fee\u6b63
"},{"location":"changelogs/#20220311-ver-111","title":"2022/03/11\u3000ver. 11.1","text":"
  • 8-P2P\u30c8\u30dd\u30ed\u30b8\u30fc\u8a2d\u5b9a \u306b\u30ce\u30fc\u30c9\u8d77\u52d5\u6700\u7d42\u8abf\u6574\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002
"},{"location":"changelogs/#20220307-ver-110","title":"2022/03/07\u3000ver. 11.0","text":"
  • cardano-node v1.34.1 \u306b\u5bfe\u5fdc
"},{"location":"changelogs/#20220301-ver-100","title":"2022/03/01\u3000ver. 10.0","text":"
  • \u30ab\u30eb\u30c0\u30ce\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u69cb\u7bc9\u624b\u9806\u65e5\u672c\u8a9e\u7ffb\u8a33\u3092\u5237\u65b0\u3057\u3001\u300cSPO JAPAN GUILD DOCS\u300d\u3068\u3057\u3066\u751f\u307e\u308c\u5909\u308f\u308a\u307e\u3057\u305f\uff01
"},{"location":"contributors/","title":"SJG\u8ca2\u732e\u8005","text":"

\u5275\u8a2d\u30fb\u904b\u55b6\u8005 BTBF | Pool: [XSP]X-StakePool / [XSP2]X-StakePool \u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u904b\u55b6/\u6280\u8853\u30b5\u30dd\u30fc\u30c8/\u30c4\u30fc\u30eb\u958b\u767a/\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u6574\u5099 \u62c5\u5f53

"},{"location":"contributors/#_1","title":"\u4e3b\u306a\u8ca2\u732e\u8005","text":"

\u30c7\u30a3\u30b9\u30b3\u30fc\u30c9\u5185\u30b5\u30dd\u30fc\u30c8 \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u5bc4\u7a3f\u30fb\u4fee\u6b63 \u6280\u8853\u691c\u8a3c\u4f5c\u696d\u306a\u3069\u306b\u3054\u5354\u529b\u9802\u3044\u305f\u7686\u69d8\u3067\u3059\u3002

\u30fbSAKAKIBARA | Pool: [1JPN] \u65e5\u672c\u58f1\u30d7\u30fc\u30eb \u30fbAkyo | Pool:[AKYO] AKYO\ud83e\udd41 \u30fbSMAN | Pool:[SA8] SMAN8 \u30fbAICHI | Pool:[AICHI] Aichi Stake Pool / [TOKAI] Tokai Stake Pool \u30fbNori | Pool:[1STEP] 1STEP \u30fbSUGAR | Pool:[SUGAR] Sugar Stake Pool \u30fbMOBC | Pool: [MOBC] MOBC StakePoolServer And More...

"},{"location":"learning/","title":"SJG\u30e9\u30fc\u30cb\u30f3\u30b0","text":"

SJG\u30e9\u30fc\u30cb\u30f3\u30b0\u3068\u306f\uff1f

\u3053\u3061\u3089\u306e\u5185\u5bb9\u306fSJG\u30c7\u30a3\u30b9\u30b3\u30fc\u30c9\u3067\u6bce\u9031\u571f\u66dc\u65e521\u6642\u304b\u3089\u958b\u50ac\u306eSPO\u30df\u30fc\u30c6\u30a3\u30f3\u30b0\u5185\u3067\u4e0d\u5b9a\u671f\u306b\u5b9f\u65bd\u3057\u3066\u3044\u308bSJG\u30e9\u30fc\u30cb\u30f3\u30b0\u6559\u6750\u3067\u3059\u3002\u30d7\u30fc\u30eb\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306b\u304a\u3051\u308b\u57fa\u790e\u77e5\u8b58\u3092\u5171\u6709\u3057SPO\u306e\u30ec\u30d9\u30eb\u30a2\u30c3\u30d7\u3092\u56f3\u308a\u307e\u3059\u3002

SPO\u30df\u30fc\u30c6\u30a3\u30f3\u30b0\u8b70\u4e8b\u9332\u306f\u3053\u3061\u3089

"},{"location":"learning/#1","title":"\u7b2c1\u56de \u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3068\u30dd\u30fc\u30c8\u306e\u57fa\u790e\u77e5\u8b58","text":""},{"location":"learning/#2","title":"\u7b2c2\u56de \u30ab\u30eb\u30c0\u30ce\u30fb\u30d7\u30ed\u30c8\u30b3\u30eb\u30d1\u30e9\u30e1\u30fc\u30bf","text":""},{"location":"learning/#3","title":"\u7b2c3\u56de \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u30b5\u30fc\u30d3\u30b9\u306e\u95a2\u4fc2\u6027","text":""},{"location":"learning/#4","title":"\u7b2c4\u56de \u30ea\u30ec\u30fc\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30c8\u30dd\u30ed\u30b8\u30fc","text":""},{"location":"learning/#5","title":"\u7b2c5\u56de \u76e3\u8996\u30e1\u30c8\u30ea\u30af\u30b9","text":""},{"location":"learning/#6-cardano-cli","title":"\u7b2c6\u56de cardano-cli\u306e\u4f7f\u3044\u65b9","text":""},{"location":"learning/#7-p2p","title":"\u7b2c7\u56de \u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P","text":""},{"location":"learning/#8","title":"\u7b2c8\u56de \u30ce\u30fc\u30c9\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0","text":""},{"location":"faq/blocklog/","title":"\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u95a2\u9023\u306e\u3088\u304f\u3042\u308b\u8cea\u554f","text":""},{"location":"faq/blocklog/#q1","title":"Q1.\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093","text":"A.cncli\u30b5\u30fc\u30d3\u30b9\u3092\u78ba\u8a8d\u3057\u307e\u3059

** 1. \u30b5\u30fc\u30d3\u30b9\u306e\u8d77\u52d5\u72b6\u614b\u3092\u78ba\u8a8d\u3059\u308b **

tmux a -t cncli\n

** \u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b **

\u623b\u308a\u5024\u30d1\u30bf\u30fc\u30f3\u2460\u623b\u308a\u5024\u30d1\u30bf\u30fc\u30f3\u2461\u623b\u308a\u5024\u30d1\u30bf\u30fc\u30f3\u2462

\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u4fc3\u3059\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b

\u623b\u308a\u5024

Script update(s) detected, do you want to download the latest version? (yes/no):

yes \u3092\u5165\u529b\u3002\u30d5\u30a1\u30a4\u30eb\u304c\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3055\u308c\u305f\u3089Enter\u3092\u62bc\u3057\u3001\u30c7\u30bf\u30c3\u30c1[Ctrl+b\u3000d]\u3057\u3066\u623b\u308b

cncli\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl reload-or-restart cnode-cncli-sync.service\n

\u300c1. \u30b5\u30fc\u30d3\u30b9\u306e\u8d77\u52d5\u72b6\u614b\u3092\u78ba\u8a8d\u3059\u308b\u300d\u306b\u623b\u3063\u3066\u518d\u5ea6\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

\u623b\u308a\u5024

Looks like cardano-node is running with socket-path as\uff5e\uff5e

\u8d64\u6587\u5b57\u3067\u5927\u91cf\u306b\u30ed\u30b0\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3002\u21d2\u30ce\u30fc\u30c9\u8d77\u52d5\u5f85\u3061\u72b6\u614b \uff08\u30c7\u30bf\u30c3\u30c1[Ctrl+B D]\u3057\u3066\u623b\u308b\uff09

\u30ce\u30fc\u30c9\u30ed\u30b0\u3092\u78ba\u8a8d\u3059\u308b

journalctl --unit=cardano-node --follow\n

\u623b\u308a\u5024

Started opening Ledger DB

\u3053\u306e\u8868\u793a\u304c\u51fa\u3066\u304f\u308c\u3070OK\u3002\u30ed\u30b0\u304c\u6d41\u308c\u308b\u307e\u3067\u5f85\u6a5f

\u30ce\u30fc\u30c9\u540c\u671f\u5f8c\u3001leaderlog\u30b5\u30fc\u30d3\u30b9\u3092\u78ba\u8a8d\u3059\u308b

tmux a -t leaderlog\n

\u623b\u308a\u5024

~ CNCLI Leaderlog started ~ Node in sync, sleeping for 60s before running leaderlogs for current epoch

\u3053\u306e\u8868\u793a\u304c\u51fa\u3066\u304f\u308c\u3070OK\uff08\u30c7\u30bf\u30c3\u30c1[Ctrl+B D]\u3057\u3066\u623b\u308b\uff09 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u8a08\u7b97\u3055\u308c\u308b\u307e\u3067\u6570\u5341\u5206\u304b\u304b\u308a\u307e\u3059\u3002

\u623b\u308a\u5024

INFO cardano_ouroboros_network::protocols::\uff5e\uff5e\uff5e 100.00% synced

\u3053\u306e\u8868\u793a\u304c\u51fa\u3066\u304f\u308c\u3070OK\uff08\u30c7\u30bf\u30c3\u30c1[Ctrl+B D]\u3057\u3066\u623b\u308b\uff09

leaderlog\u30b5\u30fc\u30d3\u30b9\u3092\u78ba\u8a8d\u3059\u308b

tmux a -t leaderlog\n

\u623b\u308a\u5024

~ CNCLI Leaderlog started ~ Node in sync, sleeping for 60s before running leaderlogs for current epoch

\u3053\u306e\u8868\u793a\u304c\u51fa\u3066\u304f\u308c\u3070OK\uff08\u30c7\u30bf\u30c3\u30c1[Ctrl+B D]\u3057\u3066\u623b\u308b\uff09

"},{"location":"faq/blocklog/#q2","title":"Q2.\u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u539f\u56e0\u306f\u4f55\u3067\u3057\u3087\u3046\u304b\uff1f","text":"A.\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u78ba\u8a8d\u3057\u307e\u3059 Stolen\u306e\u5834\u5408ghosted\u306e\u5834\u5408Missed\u306e\u5834\u5408Invalid\u306e\u5834\u5408

\u901a\u79f0\uff1aSlotBattle VRF\u5024\u304c\u5c0f\u3055\u3044\u307b\u3046\u306e\u30d6\u30ed\u30c3\u30af\u304c\u63a1\u7528\u3055\u308c\u308b\u305f\u3081\u904b\u6b21\u7b2c\u3068\u306a\u3063\u3066\u304a\u308a\u89e3\u6c7a\u65b9\u6cd5\u306f\u3042\u308a\u307e\u305b\u3093\u3002

1\u30a8\u30dd\u30c3\u30af = 432000slot\u306e\u3046\u3061\u30d6\u30ed\u30c3\u30af\u751f\u6210\u53ef\u80fd\u30b9\u30ed\u30c3\u30c8\u306f5%(21600slot)\u306b\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u304c\u3001\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u30d7\u30fc\u30eb\u9593\u540c\u58eb\u3067\u306f\u8abf\u6574\u3055\u308c\u306a\u3044\u4ed5\u69d8\u306b\u306a\u3063\u3066\u3044\u308b\u305f\u3081\u3001\u8907\u6570\u306e\u30d7\u30fc\u30eb\u306b\u540c\u4e00\u30b9\u30ed\u30c3\u30c8\u306b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002

\u3057\u304b\u3057\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306b\u63a1\u7528\u3055\u308c\u308b\u30d6\u30ed\u30c3\u30af\u306f1\u30b9\u30ed\u30c3\u30c81\u30d6\u30ed\u30c3\u30af\u306a\u306e\u3067\u3001\u3069\u306e\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u3092\u63a1\u7528\u3059\u308b\u304b\u3092\u6c7a\u5b9a\u3059\u308b\u969b\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u6642\u306b\u30d7\u30fc\u30eb\u304c\u30e9\u30f3\u30c0\u30e0\u306b\u6392\u51fa\u3059\u308bVRF\u5024\u304c\u5c0f\u3055\u3044\u65b9\u306e\u30d6\u30ed\u30c3\u30af\u3092\u63a1\u7528\u3059\u308b\u4ed5\u69d8\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002

\u539f\u56e01:VRF\u5024\u306b\u3088\u308b\u5224\u5b9a\u306e\u305f\u3081\u904b\u6b21\u7b2c \u901a\u79f0\uff1aHeightBattle \u30d6\u30ed\u30c3\u30af\u4f1d\u64ad\u306e\u5f71\u97ff\u3092\u53d7\u3051\u3066\u3044\u307e\u3059\u3002

\u73fe\u5728\u306e\u30ab\u30eb\u30c0\u30ce\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306f5\u79d2\u4ee5\u5185\u306b\u4f1d\u64ad\u3067\u304d\u308c\u3070\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4e0a\u554f\u984c\u306a\u3044\u3068\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3057\u304b\u3057\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u3068\u306e\u30c8\u30ec\u30fc\u30c9\u30aa\u30d5\u3067\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u51e6\u7406\u901f\u5ea6\u3092\u3042\u3052\u308b\u305f\u3081\u306b\u30d6\u30ed\u30c3\u30af\u30b5\u30a4\u30ba\u3084\u30b9\u30de\u30fc\u30c8\u30b3\u30f3\u30c8\u30e9\u30af\u30c8\u30b9\u30af\u30ea\u30d7\u30c8\u30e1\u30e2\u30ea\u30b5\u30a4\u30ba\u306a\u3069\u3092\u5897\u3084\u3057\u3066\u3044\u304f\u3068\u305d\u306e\u5206\u4f1d\u64ad\u901f\u5ea6\u3082\u9045\u304f\u306a\u308a\u307e\u3059\u3002

\u3053\u306e\u3053\u3068\u304b\u3089\u30011\u79d2\uff5e3\u79d2\u524d\u5f8c\u306b\u8907\u6570\u306e\u30d7\u30fc\u30eb\u3067\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3067\u767a\u751f\u3057\u3084\u3059\u304f\u3001\u5206\u6563\u5316\u306e\u89b3\u70b9\u304b\u3089\u30d7\u30fc\u30eb\u9593\u306e\u5730\u7406\u7684\u512a\u4f4d\u6027\u3092\u7121\u304f\u3059\u305f\u3081\u306bVRF\u5024\u306b\u3088\u308b\u5224\u5b9a\u3067\u63a1\u7528\u30d6\u30ed\u30c3\u30af\u304c\u6c7a\u5b9a\u3055\u308c\u307e\u3059\u3002

\u539f\u56e02:\u30b5\u30fc\u30d0\u30fc\u6642\u9593\u306e\u30ba\u30ec\u304b\u3089\u767a\u751f \u30ab\u30eb\u30c0\u30ce\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306f\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u8981\u4ef6\u304c\u5fc5\u8981\u306a\u305f\u3081\u3001\u30b5\u30fc\u30d0\u30fc\u5185\u90e8\u6642\u8a08\u3068\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u6642\u9593(NTP\u30b5\u30fc\u30d0\u30fc)\u304c\u540c\u671f\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u4e88\u5b9a\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3067\u9023\u7d9a\u3057\u3066\u767a\u751f\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u30ea\u30ec\u30fc\u304a\u3088\u3073BP\u306b\u3066Chrony\u8a2d\u5b9a\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

chronyc tracking\n
\u2192 \u300cLeap status\u300d\u304c\u300cNormal\u300d\u306a\u3089OK\u3002\u300cNot synchronized\u300d\u306a\u3089NG

\u30df\u30b9\u3057\u305f\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u3092\u7528\u3044\u3066\u3001\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u307e\u3059

55901248\u3092\u30df\u30b9\u3057\u305f\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u306b\u76f4\u3057\u3066\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cd $NODE_HOME/logs\ncat node*.json | grep 55901248\n

\u8a72\u5f53\u30b9\u30ed\u30c3\u30c8\u306e\u30ed\u30b0\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408 \u30d6\u30ed\u30c3\u30af\u4f1d\u64ad\u306e\u5f71\u97ff\u3092\u53d7\u3051\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 1\u79d2\uff5e3\u79d2\u524d\u5f8c\u306b\u8907\u6570\u306e\u30d7\u30fc\u30eb\u3067\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3067\u767a\u751f\u3057\u3084\u3059\u304f\u3001\u81ea\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u4e88\u5b9a\u307e\u3067\u306b\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u3092\u53d7\u3051\u53d6\u308c\u306a\u3044\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 \u5730\u7406\u7684\u306b\u5206\u6563\u3057\u305f\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u914d\u7f6e\u3059\u308b\u304b\u3001\u30ea\u30ec\u30fc/BP\u306emainnet-config.json\u306b\"MaxConcurrencyDeadline\":4,\u3092\u8a2d\u5b9a\u3057\u3066\u30ce\u30fc\u30c9\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

\u8a72\u5f53\u30b9\u30ed\u30c3\u30c8\u306e\u30ed\u30b0\u304c\u8868\u793a\u3055\u308c\u306a\u3044\u5834\u5408 \u30ce\u30fc\u30c9\u304c\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u3066\u3044\u305f\u304b\u3001slotsMissed\u306b\u306a\u3063\u305f\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002 \u30ea\u30ec\u30fc1\u53f0\u306e\u5834\u5408\u3001\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u304c\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3059\u308b\u3068BP\u3067\u30d6\u30ed\u30c3\u30af\u751f\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002 \u304b\u305f\u3084\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u304c\u7a3c\u50cd\u3057\u3066\u3044\u3066\u3082\u3001BP\u30ce\u30fc\u30c9\u304c\u30b7\u30e3\u30c3\u30c8\u30a2\u30a6\u30c8\u3057\u3066\u3044\u305f\u5834\u5408\u3082\u751f\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002 Grafana\u306a\u3069\u3067\u30ce\u30fc\u30c9\u7a3c\u50cd\u72b6\u614b\u3092\u76e3\u8996\u3057\u3001\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u305f\u5834\u5408\u306b\u30b9\u30de\u30db\u306a\u3069\u3078\u901a\u77e5\u3059\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u3087\u3046\u3002 miss\u306b\u306a\u3063\u305f\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u306e\u3001\u524d\u5f8c\u306e\u30b9\u30ed\u30c3\u30c8\u756a\u53f720\uff5e30\u3050\u3089\u3044\u3092\u30ed\u30b0\u691c\u7d22\u3057\u3066\u51fa\u3066\u304f\u308c\u3070\u3001\u30ce\u30fc\u30c9\u306f\u52d5\u3044\u3066\u3044\u305f\u53ef\u80fd\u6027\u304c\u9ad8\u3044\u3067\u3059\u3002

slotsMissed\u3068\u306f\uff1f [gLiveView\u306b\u8868\u793a\u3055\u308c\u308bMissed slot leader checks] BP\u30ce\u30fc\u30c9\u306f\u6bce\u79d2\u3054\u3068\u306b\u81ea\u5206\u304c\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u306a\u306e\u304b\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u3044\u307e\u3059\u304c\u3001\u30ce\u30fc\u30c9\u306e\u72b6\u614b\u3084\u30b5\u30fc\u30d0\u30fc\u8ca0\u8377\u306b\u3088\u3063\u3066\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u30c1\u30a7\u30c3\u30af\u306b\u5931\u6557\u3057\u307e\u3059\u3002 \u3053\u306e\u30bf\u30a4\u30df\u30f3\u30b0\u306b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u91cd\u306a\u308b\u3068\u30d6\u30ed\u30c3\u30af\u751f\u6210\u3067\u304d\u307e\u305b\u3093\u3002

\u73fe\u5728\u308f\u304b\u3063\u3066\u3044\u308b\u3053\u3068\u306f\u3001\u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u306bRTS\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3067\u8efd\u6e1b\u3067\u304d\u307e\u3059\u3002\u307e\u305f\u5951\u7d04\u30b5\u30fc\u30d0\u30fc\u306e\u5185\u90e8\u4ed5\u69d8\u306b\u3088\u3063\u3066\u3082\u5909\u308f\u3063\u3066\u304f\u308b\u3088\u3046\u306a\u306e\u3067 slotsMissed\u306e\u767a\u751f\u304c\u591a\u3044\u5834\u5408\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u4e57\u308a\u63db\u3048\u3082\u691c\u8a0e\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u3057\u307e\u3059\u3002(\u30b5\u30fc\u30d0\u30fc\u5185\u90e8\u8a2d\u5b9a\u306f\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5074\u3067\u306f\u5909\u66f4\u3067\u304d\u307e\u305b\u3093)

KES\u66f4\u65b0\u30fb\u904b\u7528\u8a3c\u660e\u66f8\u306e\u767a\u884c\u306b\u5931\u6557\u3057\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059

logmonitor\u306b\u8868\u793a\u3055\u308c\u308b\u3001base64\u30b3\u30fc\u30c9\u3092\u30c7\u30b3\u30fc\u30c9\u3057\u3066\u539f\u56e0\u3092\u63a2\u308a\u307e\u3059\u3002

tmux a -t logmonitor\n
\u30ed\u30b0\u30e2\u30cb\u30bf\u30fc\u306b\u8868\u793a\u3055\u308c\u308b\u3001echo \uff5e jq -r\u307e\u3067\u3092\u30b3\u30d4\u30fc\u3059\u308b \u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u306f\u4f8b\u3067\u3059\u3002

echo eyJ0aHJlYWQiOiIxMzUiLCJzZXYiOiJFcnJvciIsImRhdGEiOnsidmFsIjp7ImtpbmQiOiJUcmFjZUZvcmdlZEludmFsaWRCbG9jayIsInNsb3QiOjQ5MTY1ODc5LCJyZWFzb24iOnsia2luZCI6IlZhbGlkYXRpb25FcnJvciIsImVycm9yIjp7ImtpbmQiOiJIZWFkZXJQcm90b2NvbEVycm9yIiwiZXJyb3IiOnsiZmFpbHVyZXMiOlt7Im9wQ2VydEV4cGVjdGVkS0VTRXZvbHV0aW9ucyI6IjI1Iiwia2luZCI6IkludmFsaWRLZXNTaWduYXR1cmVPQ0VSVCIsIm9wQ2VydEtFU1N0YXJ0UGVyaW9kIjoiMzU0Iiwib3BDZXJ0S0VTQ3VycmVudFBlcmlvZCI6IjM3OSIsImVycm9yIjoiUmVqZWN0In1dLCJraW5kIjoiQ2hhaW5UcmFuc2l0aW9uRXJyb3IifX19fSwiY3JlZGVudGlhbHMiOiJDYXJkYW5vIn0sImxvYyI6bnVsbCwiZW52IjoiMS4zMi4xOjRmNjVmIiwibXNnIjoiIiwiYXBwIjpbXSwiaG9zdCI6ImlwLTE3Mi0yIiwiYXQiOiIyMDIxLTEyLTI4VDIyOjU2OjEwLjQzWiIsIm5zIjpbImNhcmRhbm8ubm9kZS5Gb3JnZSJdLCJwaWQiOiIzODY1MzAifQ== | base64 -d | jq -r

Ctrl+b d\u3067\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u3001\u4e0a\u8a18\u3067\u30b3\u30d4\u30fc\u3057\u305f\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3002 \"error\":\"failures\":\"kind\":\u306e\u5024\u304c\u5931\u6557\u3057\u305f\u7406\u7531\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002

{\n    \"thread\": \"135\",\n    \"sev\": \"Error\",\n    \"data\": {\n        \"val\": {\n        \"kind\": \"TraceForgedInvalidBlock\",\n        \"slot\": 49165879,\n        \"reason\": {\n            \"kind\": \"ValidationError\",\n            \"error\": {\n            \"kind\": \"HeaderProtocolError\",\n            \"error\": {\n                \"failures\": [\n                {\n                    \"opCertExpectedKESEvolutions\": \"25\",\n                    \"kind\": \"InvalidKesSignatureOCERT\",\n                    \"opCertKESStartPeriod\": \"354\",\n                    \"opCertKESCurrentPeriod\": \"379\",\n                    \"error\": \"Reject\"\n                }\n                ],\n                \"kind\": \"ChainTransitionError\"\n            }\n            }\n        }\n        },\n        \"credentials\": \"Cardano\"\n    },\n    \"loc\": null,\n    \"env\": \"1.32.1:4f65f\",\n    \"msg\": \"\",\n    \"app\": [],\n    \"host\": \"ip-172-2\",\n    \"at\": \"2021-12-28T22:56:10.43Z\",\n    \"ns\": [\n        \"cardano.node.Forge\"\n    ],\n    \"pid\": \"386530\"\n}\n

"},{"location":"faq/blocklog/#q3sns","title":"Q3.\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092SNS\u3067\u516c\u958b\u3057\u3066\u3082\u3044\u3044\u3067\u3059\u304b\uff1f","text":"A.NG\u3067\u3059

\u672a\u6765\u306e\u751f\u6210\u4e88\u5b9a\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u516c\u958b\u3059\u308b\u3068\u3001\u305d\u306e\u6642\u9593\u3092\u72d9\u3063\u3066\u60aa\u610f\u306e\u3042\u308b\u8005\u304b\u3089\u653b\u6483\u3092\u53d7\u3051\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u3001 \u4e88\u5b9a\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u516c\u958b\u3059\u308b\u3053\u3068\u306f\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u640d\u306a\u3046\u91cd\u5927\u306a\u554f\u984c\u3068\u306a\u308a\u307e\u3059\u3002

"},{"location":"faq/blocklog/#q4error-database-is-locked","title":"Q4.\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u6642\u300cError: database is locked\u300d\u304c\u8868\u793a\u3055\u308c\u308b","text":"A.\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u518d\u53d6\u5f97\u3057\u3066\u304f\u3060\u3055\u3044

tmux a -t leaderlog\u3067\u53d6\u5f97\u3055\u308c\u305f\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u78ba\u8a8d\u3059\u308b\u3068\u300cError: database is locked\u300d\u304c\u8868\u793a\u3055\u308c\u308b\u6642\u304c\u3042\u308a\u307e\u3059\u3002

\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u6642\u306eblocklog\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u66f8\u304d\u8fbc\u307f\u30a8\u30e9\u30fc\u306b\u3088\u308b\u3082\u306e\u3067\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u3042\u308b\u3082\u306e\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u683c\u7d0d\u3055\u308c\u307e\u305b\u3093\u3002 \u76f4\u8fd11\u6642\u9593\u4ee5\u5185\u306b\u30d6\u30ed\u30c3\u30af\u751f\u6210\u304c\u7121\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3001tmux a -t leaderlog\u3092\u958b\u304d$NODE_HOME/scripts/cncli.sh leaderlog force\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u518d\u53d6\u5f97\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"faq/monitoring/","title":"\u30ce\u30fc\u30c9\u76e3\u8996\u306b\u95a2\u3059\u308b\u3088\u304f\u3042\u308b\u8cea\u554f","text":""},{"location":"faq/monitoring/#q1grafana","title":"Q1.Grafana\u306e\u30ed\u30b0\u30a4\u30f3\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5fd8\u308c\u307e\u3057\u305f","text":"A.\u30ed\u30b0\u30a4\u30f3\u306b\u5fc5\u8981\u306a\u60c5\u5831\u3092\u521d\u671f\u5316\u3057\u307e\u3059

\u30ea\u30ec\u30fc\uff11\u306b\u3066\u4ee5\u4e0b\u3092\u5b9f\u65bd\u3057\u307e\u3059\u3002

sudo sqlite3 /var/lib/grafana/grafana.db\n
update user set password = '59acf18b94d7eb0694c61e60ce44c110c7a683ac6a8f09580d626f90f4a242000746579358d77dd9e570e83fa24faa88a8a6', salt = 'F3FAxVm33R' where login = 'admin';\n
.quit\n
\u4ee5\u4e0b\u306e\u60c5\u5831\u3067\u30ed\u30b0\u30a4\u30f3\u3057\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u518d\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044

Username:admin password:admin

"},{"location":"faq/node/","title":"\u30ce\u30fc\u30c9\u306b\u95a2\u3059\u308b\u3088\u304f\u3042\u308b\u8cea\u554f","text":""},{"location":"faq/node/#q1","title":"Q1.\u30ce\u30fc\u30c9\u304c\u8d77\u52d5\u30fb\u540c\u671f\u3057\u307e\u305b\u3093","text":"A.\u8d77\u52d5\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

\u30ce\u30fc\u30c9\u8d77\u52d5\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u30a8\u30e9\u30fc\u8868\u793a\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

journalctl --unit=cardano-node --follow\n

\u300cInvalidYaml (Just (YamlParseException\u300d\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408

  • mainnet-config.json \u69cb\u6587\u30a8\u30e9\u30fc\u306e\u305f\u3081\u30d5\u30a1\u30a4\u30eb\u5185\u3092\u898b\u76f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    , {} ()\u306a\u3069\u304c\u629c\u3051\u3066\u3044\u305f\u308a\u3001\u591a\u304b\u3063\u305f\u308a\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u305f\u3089\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059

sudo systemctl reload-or-restart cardano-node\n

JSON\u69cb\u6587\u30c1\u30a7\u30c3\u30af\u30c4\u30fc\u30eb\uff08\u30e9\u30c3\u30b3\u30c4\u30fc\u30eb\u30ba\uff09

\u300cIs your topology file formatted correctly?\u300d \u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408

  • mainnet-topology.json \u69cb\u6587\u30a8\u30e9\u30fc\u306e\u305f\u3081\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u898b\u76f4\u3057\u3066\u304f\u3060\u3055\u3044

\u30d5\u30a1\u30a4\u30eb\u3092\u78ba\u8a8d\u3057\u305f\u3089\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059

sudo systemctl reload-or-restart cardano-node\n

Progress: xx.xx%\u306e\u8868\u793a\u304c\u3042\u308b\u5834\u5408 \u524d\u56de\u30ce\u30fc\u30c9\u7d42\u4e86\u6642\u306b\u30e1\u30e2\u30ea\u4e0d\u8db3\u306a\u3069\u3067\u5f37\u5236\u7d42\u4e86\u3057\u305f\u305f\u3081\u3001DB\u518d\u30c1\u30a7\u30c3\u30af\u304c\u884c\u308f\u308c\u3066\u3044\u307e\u3059\u3002\u540c\u671f\u307e\u3067\u306b\u7d0420\u5206\u4ee5\u4e0a\u304b\u304b\u308a\u307e\u3059\u306e\u3067\u305d\u306e\u307e\u307e\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002

\u6ce8\u610f

\u30ce\u30fc\u30c9\u304c\u5b8c\u5168\u540c\u671f\u3057\u306a\u3044\u3046\u3061\u306b\u30ce\u30fc\u30c9\u8d77\u52d5\u30fb\u518d\u8d77\u52d5\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3068\u3001DB\u518d\u30c1\u30a7\u30c3\u30af\u304c\u884c\u308f\u308c\u308b\u305f\u3081\u540c\u671f\u304c\u3055\u3089\u306b\u9045\u304f\u306a\u308a\u307e\u3059\u306e\u3067\u3054\u6ce8\u610f\u304f\u3060\u3055\u3044

BP\u304c\u540c\u671f\u3057\u306a\u3044\u5834\u5408 \u30ea\u30ec\u30fc\u3068\u306e\u63a5\u7d9a\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • BP\u306emainnet-topology.json
  • BP\u306e\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a
  • \u30ea\u30ec\u30fc\u306e\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a
  • \u5951\u7d04\u30b5\u30fc\u30d0\u30fc\u72ec\u81ea\u306e\u4ed5\u69d8
"},{"location":"faq/node/#q2","title":"Q2.\u30ce\u30fc\u30c9\u304c\u518d\u8d77\u52d5\u3092\u7e70\u308a\u8fd4\u3057\u307e\u3059","text":"A.\u30c7\u30a3\u30b9\u30af\u7a7a\u304d\u5bb9\u91cf\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

df -h /usr\n
\u623b\u308a\u5024\u306eUse%\u304c100%\u306b\u8fd1\u3044\u3068\u30ce\u30fc\u30c9DB\u3092\u66f4\u65b0\u3059\u308b\u7a7a\u304d\u5bb9\u91cf\u304c\u8db3\u308a\u306a\u3044\u305f\u3081\u3001\u518d\u8d77\u52d5\u3092\u7e70\u308a\u8fd4\u3057\u307e\u3059\u3002\u5951\u7d04VPS\u306e\u30b5\u30fc\u30d0\u30fc\u30b9\u30da\u30c3\u30af\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/add-relay/","title":"\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u5897\u8a2d\u30de\u30cb\u30e5\u30a2\u30eb","text":""},{"location":"operation/add-relay/#1ubuntu","title":"1.Ubuntu\u521d\u671f\u8a2d\u5b9a","text":"

https://docs.spojapanguild.net/setup/1-ubuntu-setup/

"},{"location":"operation/add-relay/#2","title":"2.\u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

https://docs.spojapanguild.net/setup/2-node-setup/

"},{"location":"operation/add-relay/#3","title":"3.\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u306e\u8a2d\u5b9a\u5909\u66f4","text":"

https://docs.spojapanguild.net/setup/3-relay-bp-setup/#3-1

"},{"location":"operation/add-relay/#4bpfw","title":"4.BP\u306eFW\u3068\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u5909\u66f4","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc
PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n

<\u5897\u8a2d\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306eIP> \u306e <>\u3092\u9664\u3044\u3066IP\u306e\u307f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo ufw allow from <\u5897\u8a2d\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306eIP> to any port ${b_PORT}\nsudo ufw reload\n

\u30d2\u30f3\u30c8

\u81ea\u8eab\u306eBP\u30ce\u30fc\u30c9\u304b\u3089\u63a5\u7d9a\u3059\u308b\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306eIP\u3068\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002 \u3042\u3089\u304b\u3058\u3081\u3001\u300cxxx.xxx.xxx.xxx\u300d\u306f\u3054\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u3068\u30dd\u30fc\u30c8\u756a\u53f7\u3000\u306b\u7f6e\u304d\u63db\u3048\u3066\u304b\u3089\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002\u30ea\u30ec\u30fc\u53f0\u6570\u5206\u8a18\u8f09\u3057\u307e\u3059\u3002

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF \n{\n    \"Producers\": [\n    {\n        \"addr\": \"aa.xxx.xxx.xxx\",\n        \"port\": 6000,\n        \"valency\": 1\n    },\n    {\n        \"addr\": \"bb.xxx.xxx.xxx\",\n        \"port\": 6000,\n        \"valency\": 1\n    }\n    ]\n}\nEOF\n
sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/add-relay/#5p2p","title":"5.P2P\u30c8\u30dd\u30ed\u30b8\u30fc\u8a2d\u5b9a","text":"\u5897\u8a2d\u30ea\u30ec\u30fc

https://docs.spojapanguild.net/setup/8.topology-setup/

"},{"location":"operation/add-relay/#6","title":"6.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"\u5897\u8a2d\u30ea\u30ec\u30fc

9-1.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u300cBP\u307e\u305f\u306f\u30ea\u30ec\u30fc2\u4ee5\u964d\u300d\u30bf\u30d6\u3068\u300c\u5168\u30b5\u30fc\u30d0\u30fc\u300d\u30bf\u30d6\u3092\u5897\u8a2d\u30ea\u30ec\u30fc\u3067\u5b9f\u65bd https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/#1

9-3.\u30ce\u30fc\u30c9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u66f4\u65b0 https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/#3

9-2.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210 \u30b0\u30e9\u30d5\u30a1\u30ca\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u30b5\u30fc\u30d0\u30fc\u3067 \u300c\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91(\u30ea\u30ec\u30fc2\u53f0\u306e\u5834\u5408)\u300d\u30bf\u30d6\u3092\u5b9f\u65bd

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91

https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/#2

"},{"location":"operation/bp-move/","title":"BP\u30b5\u30fc\u30d0\u30fc\u306e\u5f15\u8d8a\u3057\u624b\u9806\uff08\u65e7VPS\u4f1a\u793e\u2192\u65b0VPS\u4f1a\u793e\uff09","text":"

\u524d\u63d0\u6ce8\u610f\u4e8b\u9805

  • \u672c\u307e\u3068\u3081\u306f\u73feVPS\u4f1a\u793e\u2192\u65b0VPS\u4f1a\u793e\u3078\u3068 BP\u306e\u307f \u3092\u79fb\u884c\u3059\u308b\u307e\u3068\u3081\u3067\u3059\u3002
  • \u5b9f\u969b\u306b\u884c\u3046\u969b\u306b\u306f\u624b\u9806\u3092\u3088\u304f\u8aad\u307f\u306a\u304c\u3089\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u4e88\u5b9a\u307e\u3067\u4f59\u88d5\u304c\u3042\u308b\u6642\u306b\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u65e7BP\u306f3-3.\u65e7BP\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u307e\u3067\u3001\u8d77\u52d5\u72b6\u614b \u306b\u3057\u3066\u304a\u3044\u3066\u304f\u3060\u3055\u3044\u3002
"},{"location":"operation/bp-move/#1bp","title":"1.\u65b0BP\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u7559\u610f\u4e8b\u9805

  1. \u30b5\u30fc\u30d0\u72ec\u81ea\u6a5f\u80fd\u306b\u7559\u610f\u3059\u308b
    • \u3055\u304f\u3089\u306e\u30d1\u30b1\u30c3\u30c8\u30d5\u30a3\u30eb\u30bf\u3084\u3001AWS\u306eFW\u8a2d\u5b9a\u306a\u3069\u306e\u30b5\u30fc\u30d0\u30fc\u72ec\u81ea\u306e\u6a5f\u80fd\u306b\u6c17\u3092\u4ed8\u3051\u3066\u304f\u3060\u3055\u3044\u3002
  2. \u65b0BP\u306e\u30d5\u30a1\u30a4\u30e4\u30fc\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u306f\u3001\u65e7BP\u3068\u540c\u3058\u8a2d\u5b9a\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  3. \u65e7BP\u306e\u30e6\u30fc\u30b6\u30fc\u540d\uff08\u4f8b\uff1aubuntu\uff09\u3068\u65b0BP\u306e\u30e6\u30fc\u30b6\u30fc\u540d\u306f\u5909\u66f4\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
    • \u3082\u3057\u5909\u66f4\u3059\u308b\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u30d5\u30a1\u30a4\u30eb\u5185\u306e\u30d1\u30b9\u540d\u3092\u624b\u52d5\u3067\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002
    • startBlockProducingNode.sh DIRECTORY=/home/\u30e6\u30fc\u30b6\u30fc\u540d/cnode
"},{"location":"operation/bp-move/#1-1ubuntu","title":"1-1.Ubuntu\u521d\u671f\u8a2d\u5b9a","text":"

\u65b0\u30b5\u30fc\u30d0\u30fc\u3067Ubuntu\u521d\u671f\u8a2d\u5b9a\u3092\u5b9f\u65bd\u3057\u307e\u3059\u3002

"},{"location":"operation/bp-move/#1-2","title":"1-2.\u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u4f9d\u5b58\u95a2\u4fc2\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u301c gLiveView\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u307e\u3067\u5b9f\u65bd\u3057\u307e\u3059\u3002

"},{"location":"operation/bp-move/#2","title":"2.\u65e2\u5b58\u30ea\u30ec\u30fc\u4f5c\u696d","text":"

\u30ea\u30ec\u30fc\u30c8\u30dd\u30ed\u30b8\u30fc\u60c5\u5831\u5909\u66f4

\u624b\u52d5P2P\u306e\u5834\u5408\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u306e\u5834\u5408 \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9

nano $NODE_HOME/relay-topology_pull.sh\n
\u65e7BP\u306eIP\u3068\u30dd\u30fc\u30c8\u3092\u65b0BP\u306eIP\u3068\u30dd\u30fc\u30c8\u306b\u5909\u66f4\u3059\u308b

  • BLOCKPRODUCING_IP=xxx.xxx.xxx
  • BLOCKPRODUCING_PORT=xxxx

relay-topology_pull.sh\u3092\u5b9f\u884c\u3057\u3001\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

cd $NODE_HOME\n./relay-topology_pull.sh\n
\u30ce\u30fc\u30c9\u518d\u8d77\u52d5
sudo systemctl reload-or-restart cardano-node\n

gLiveview\u3067\u30ea\u30ec\u30fc\u304c\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u3068\u540c\u671f\u3059\u308b\u3053\u3068\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044

nano $NODE_HOME/${NODE_CONFIG}-topology.json\n

\u65e7BP\u306eIP\u3068\u30dd\u30fc\u30c8\u3092\u65b0BP\u306eIP\u3068\u30dd\u30fc\u30c8\u306b\u5909\u66f4\u3059\u308b

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u518d\u8aad\u307f\u8fbc\u307f

kill -SIGHUP $(pidof cardano-node)\n

\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u6709\u52b9\u6642\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u5909\u66f4\u306b\u3088\u308b\u518d\u8d77\u52d5\u306f\u4e0d\u8981\u3067\u3059\u3002

"},{"location":"operation/bp-move/#3bp","title":"3.\u65e7BP\u79fb\u884c\u51e6\u7406","text":""},{"location":"operation/bp-move/#3-1bp","title":"3-1.\u65e7BP\u30ce\u30fc\u30c9\u505c\u6b62","text":"\u65e7BP

sudo systemctl stop cardano-node\n
sudo systemctl disable cardano-node\n

"},{"location":"operation/bp-move/#3-2bp","title":"3-2.\u65e7BP\u30d5\u30a1\u30a4\u30eb\u79fb\u52d5","text":"\u53c2\u8003\uff09\u79fb\u884c\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7 \u30d5\u30a1\u30a4\u30eb\u540d \u7528\u9014 vrf.skey \u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5fc5\u9808 vrf.vkey \u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5fc5\u9808 kes.skey \u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5fc5\u9808 kes.vkey KES\u516c\u958b\u9375 node.cert \u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5fc5\u9808 payment.addr \u6b8b\u9ad8\u78ba\u8a8d\u3067\u5fc5\u8981 stake.addr \u6b8b\u9ad8\u78ba\u8a8d\u3067\u5fc5\u8981 mainnet-topology.json \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb poolMetaData.json pool.cert\u4f5c\u6210\u6642\u306b\u5fc5\u8981 poolMetaDataHash.txt pool.cert\u4f5c\u6210\u6642\u306b\u5fc5\u8981 startBlockProducingNode.sh \u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8 pool.id-bech32 stakepoolid(bech32\u5f62\u5f0f) pool.id stakepoolid(hex\u5f62\u5f0f) guild-db \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u95a2\u9023\u30d5\u30a9\u30eb\u30c0(cncli.db\u4ee5\u5916) \u65e7BP

Zstandard\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

sudo apt install zstd\n

\u4e0a\u8a18\u306e\u79fb\u884c\u30d5\u30a1\u30a4\u30eb\u3092\u4e00\u3064\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u5727\u7e2e\u3059\u308b

cd $NODE_HOME\ntar --exclude \"guild-db/cncli/cncli.db\" -acvf bp-move.zst guild-db/ vrf.skey vrf.vkey kes.skey kes.vkey node.cert payment.addr stake.addr mainnet-topology.json poolMetaData.json poolMetaDataHash.txt startBlockProducingNode.sh pool.id-bech32 pool.id\n

\u65e7BP\u306ecnode\u306b\u3042\u308bbp-move.zst\u3092\u65b0BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3059\u308b

graph LR\n    A[\u65e7BP] -->|bp-move.zst| B[\u65b0BP];

"},{"location":"operation/bp-move/#3-3bp","title":"3-3.\u65e7BP\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3","text":"
sudo shutdown -h now\n
"},{"location":"operation/bp-move/#4bp","title":"4.\u65b0BP\u518d\u8a2d\u5b9a","text":""},{"location":"operation/bp-move/#4-1","title":"4-1.\u79fb\u884c\u30d5\u30a1\u30a4\u30eb\u5fa9\u5143","text":"\u65b0BP

\u30ce\u30fc\u30c9\u505c\u6b62

sudo systemctl stop cardano-node\n

\u30d5\u30a1\u30a4\u30eb\u78ba\u8a8d

ls $NODE_HOME/bp-move.zst\n

\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002 \u4f8b\uff09/home/cardano/cnode/bp-move.zst

\u30d5\u30a1\u30a4\u30eb\u5c55\u958b

cd $NODE_HOME\ntar -xvf bp-move.zst\n

\u623b\u308a\u5024\u306b\u79fb\u884c\u30d5\u30a1\u30a4\u30eb\u4e00\u89a7\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

\u5727\u7e2e\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3059\u308b

rm bp-move.zst\n

"},{"location":"operation/bp-move/#4-2","title":"4-2. \u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u5909\u66f4","text":"\u65b0BP
cd $NODE_HOME\nchmod 400 vrf.skey\nchmod 400 vrf.vkey\nchmod +x startBlockProducingNode.sh\n

\u30ce\u30fc\u30c9\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl start cardano-node\n
\u30ce\u30fc\u30c9\u30ed\u30b0\u78ba\u8a8d
journalctl --unit=cardano-node --follow\n

"},{"location":"operation/bp-move/#4-3-bp","title":"4-3. \u65b0BP\u63a5\u7d9a\u78ba\u8a8d","text":"

gLiveView\u3067\u65b0BP\u304c\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u3068\u540c\u671f\u5f8c\u3001\u30ea\u30ec\u30fc\u3068\u758e\u901a(I/O)\u304c\u3067\u304d\u3066\u3044\u308b\u304b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u65b0BP

gLiveView\u78ba\u8a8d

cd $NODE_HOME/scripts\n./gLiveView.sh\n

In\u3068Out\u306b\u30ea\u30ec\u30fc\u306eIP\u304c\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/bp-move/#4-4-paramsjson","title":"4-4. params.json\u518d\u4f5c\u6210","text":"\u65b0BP
cd $NODE_HOME\ncardano-cli query protocol-parameters \\\n    --mainnet \\\n    --out-file params.json\n
"},{"location":"operation/bp-move/#4-5","title":"4-5. \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u8a2d\u5b9a","text":"
  • \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u5c0e\u5165\u624b\u9806

\u6ce8\u610f

\u300c10-6. \u904e\u53bb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u5b9f\u7e3e\u53d6\u5f97\u300d\u306f\u5b9f\u65bd\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/bp-move/#4-6-sjg","title":"4-6. SJG\u30c4\u30fc\u30eb\u5c0e\u5165","text":"
  • SPO JAPAN GUILD TOOL
"},{"location":"operation/bp-move/#4-7","title":"4-7. \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af","text":"

SJG\u30c4\u30fc\u30eb\u3092\u8d77\u52d5\u3057\u3001\u300c[2] \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af\u300d\u3067\u3059\u3079\u3066\u306e\u9805\u76ee\u304cOK\u306b\u306a\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

"},{"location":"operation/bp-move/#4-8","title":"4-8. \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u8a2d\u5b9a","text":"\u65e7BP\u3067\u5c0e\u5165\u6e08\u307f\u306e\u5834\u5408\u65e7BP\u3067\u672a\u5c0e\u5165\u306e\u5834\u5408

\u4f9d\u5b58\u74b0\u5883\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

\u65b0BP

sudo apt install -y python3-watchdog python3-tz python3-dateutil python3-requests build-essential libssl-dev libffi-dev python3-dev python3-pip\n
pip install discordwebhook python-dotenv slackweb\n
\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u5909\u66f4
chmod +x $NODE_HOME/guild-db/blocklog/block_check.py\n
\u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210
cat > $NODE_HOME/service/cnode-blockcheck.service << EOF \n# file: /etc/systemd/system/cnode-blockcheck.service\n\n[Unit]\nDescription=Cardano Node - CNCLI blockcheck\nBindsTo=cnode-cncli-sync.service\nAfter=cnode-cncli-sync.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME\nExecStart=/usr/bin/tmux new -d -s blockcheck\nExecStartPost=/usr/bin/tmux send-keys -t blockcheck 'cd $NODE_HOME/guild-db/blocklog' Enter\nExecStartPost=/usr/bin/tmux send-keys -t blockcheck python3 Space block_check.py Enter\nExecStop=/usr/bin/tmux kill-session -t blockcheck\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-blockcheck\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cnode-cncli-sync.service\nEOF\n
sudo cp $NODE_HOME/service/cnode-blockcheck.service /etc/systemd/system/cnode-blockcheck.service\nsudo chmod 644 /etc/systemd/system/cnode-blockcheck.service\n
sudo systemctl daemon-reload\nsudo systemctl enable cnode-blockcheck.service\n

\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u304b\u3089\u5c0e\u5165\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/bp-move/#5-prometheus","title":"5. Prometheus\u8a2d\u5b9a","text":""},{"location":"operation/bp-move/#5-1bpnode-exporter","title":"5-1.\u65b0BPnode exporter\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"\u65b0BP
sudo apt install -y prometheus-node-exporter\n

\u30b5\u30fc\u30d3\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3001\u81ea\u52d5\u7684\u306b\u958b\u59cb\u3055\u308c\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3059\u3002

sudo systemctl enable prometheus-node-exporter.service\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/bp-move/#5-2grafanaprometheusyml","title":"5-2.Grafana\u30b5\u30fc\u30d0\u30fcprometheus.yml\u306e\u4fee\u6b63","text":"Grafana\u30b5\u30fc\u30d0\u30fc(\u30ea\u30ec\u30fc1)

prometheus.yml\u306b\u8a18\u8f09\u3055\u308c\u3066\u308b\u65e7BP\u306eIP\u3092\u65b0BP\u306eIP\u3078\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044

sudo nano /etc/prometheus/prometheus.yml\n

\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5

sudo systemctl restart grafana-server.service\nsudo systemctl restart prometheus.service\nsudo systemctl restart prometheus-node-exporter.service\n

\u30b5\u30fc\u30d3\u30b9\u304c\u6b63\u3057\u304f\u5b9f\u884c\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service\n

Grafana\u306bBP\u306e\u30e1\u30c8\u30ea\u30af\u30b9(KES\u306a\u3069)\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b\u3002

"},{"location":"operation/bp-move/#6","title":"6.\u88dc\u8db3","text":""},{"location":"operation/bp-move/#tracemempool","title":"Tracemempool\u7121\u52b9\u5316","text":"

Tx\u306e\u5897\u52a0\u304c\u78ba\u8a8d\u3067\u304d\u305f\u3089Tracemempool\u3092\u7121\u52b9\u306b\u3057\u307e\u3059\u3002

\u65b0BP
sed -i $NODE_HOME/${NODE_CONFIG}-config.json \\\n    -e \"s/TraceMempool\\\": true/TraceMempool\\\": false/g\"\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/bp-move/#mithril-signer","title":"Mithril-Signer\u518d\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u65e7\u30b5\u30fc\u30d0\u30fc\u3067Mithril-Signer-Node\u3092\u5b9f\u884c\u3057\u3066\u3044\u305f\u5834\u5408\u306f\u3001\u65b0\u30b5\u30fc\u30d0\u30fc\u3067\u3082\u518d\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e0d\u660e\u70b9\u304c\u3042\u308b\u5834\u5408\u306fBTBF SPO LAB.\u3067\u3054\u8cea\u554f\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/bpport/","title":"BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u5909\u66f4\u624b\u9806","text":"

BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u30926000\u756a\u3067\u904b\u7528\u3055\u308c\u3066\u308b\u65b9\u5411\u3051\u306e\u5909\u66f4\u30de\u30cb\u30e5\u30a2\u30eb\u3067\u3059\u3002

BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5909\u66f4\u3059\u308b\u7406\u7531

CNTOOL\u3067\u306f\u53c2\u8003\u3068\u3057\u30666000\u30dd\u30fc\u30c8\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u3066\u304a\u308a\u3001\u3053\u3061\u3089\u306b\u5408\u308f\u305b\u308b\u5f62\u3067\u5f53\u30de\u30cb\u30e5\u30a2\u30eb\u30826000\u3092\u63a1\u7528\u3057\u3066\u304a\u308a\u307e\u3057\u305f\u304c\u30016000\u30dd\u30fc\u30c8\u306f\u300cx window system\u300d\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u3066\u308b\u30dd\u30fc\u30c8\u3067\u3001\u4f7f\u308f\u306a\u3051\u308c\u3070\u4f7f\u3063\u3066\u3082\u5927\u4e08\u592b\u3068\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u305f\u3060\u3057\u3001BP\u30dd\u30fc\u30c8=6000\u3068\u3044\u3046\u8a8d\u8b58\u304c\u5e83\u307e\u3063\u3066\u3044\u304f\u3068\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u4e0a\u597d\u307e\u3057\u304f\u306a\u304f\u5404\u30d7\u30fc\u30eb\u3067\u72ec\u81ea\u30dd\u30fc\u30c8\u3092\u63a1\u7528\u3057\u305f\u307b\u3046\u304c\u826f\u3044\u305f\u3081\u3002

"},{"location":"operation/bpport/#_1","title":"\u5909\u66f4\u70b9","text":"
  1. \u30c0\u30a4\u30ca\u30df\u30c3\u30af\u30dd\u30fc\u30c8(49513\uff5e65535\u307e\u3067\u306e\u756a\u53f7)\u3092\u4f7f\u3044\u307e\u3059\u3002
  2. $NODE_HOME/startBlockProducingNode.sh\u306ePORT=6000\u3092\u5909\u66f4\u3059\u308b\u30dd\u30fc\u30c8\u756a\u53f7\u3078\u3068\u66f8\u304d\u63db\u3048\u307e\u3059\u3002
  3. $NODE_HOME/scripts/env\u306eCNODE_PORT=6000\u3092\u5909\u66f4\u3059\u308b\u30dd\u30fc\u30c8\u756a\u53f7\u3078\u3068\u66f8\u304d\u63db\u3048\u307e\u3059\u3002
"},{"location":"operation/bpport/#bp_1","title":"BP\u306b\u3066\u5b9f\u65bd","text":"

\u65b0\u3057\u3044BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u6c7a\u3081\u308b\u70ba\u3001xxxxx\u3092(49513\uff5e65535)\u306e\u7bc4\u56f2\u5185\u3067\u6c7a\u3081\u3066\u5165\u529b\u3057\u307e\u3059\u3002

PORT=xxxxx\n

\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u30dd\u30fc\u30c8\u3092\u65b0\u3057\u3044\u30dd\u30fc\u30c8\u306b\u66f8\u304d\u63db\u3048\u308b(\u3053\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c)

sed -i $NODE_HOME/startBlockProducingNode.sh \\\n    -e '1,73s!PORT=6000!PORT='${PORT}'!'\nsed -i $NODE_HOME/scripts/env \\\n    -e '1,73s!CNODE_PORT=6000!CNODE_PORT='${PORT}'!'\n

"},{"location":"operation/bpport/#bpufw","title":"BP\u30b5\u30fc\u30d0\u30fcufw\u8a2d\u5b9a\u5909\u66f4","text":"

ufw\u3092\u4f7f\u308f\u306a\u3044\u30b1\u30fc\u30b9

AWS\u3084VSP\u306b\u3088\u3063\u3066\u306f\u7ba1\u7406\u753b\u9762\u3067\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a(\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb)\u3092\u884c\u3046\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u3001\u305d\u306e\u5834\u5408\u306f\u3001\u7ba1\u7406\u753b\u9762\u304b\u3089\u8a2d\u5b9a\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u65b0\u3057\u3044\u30dd\u30fc\u30c8\u756a\u53f7\u53d6\u5f97

PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n
\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u65e7BP\u30dd\u30fc\u30c8\u8a31\u53ef\u3092\u524a\u9664

\u5c71\u304b\u3063\u3053<>\u306f\u4e0d\u8981\u3067\u3059

sudo ufw status numbered\nsudo ufw delete <\u524a\u9664\u3057\u305f\u3044\u756a\u53f7>\n

\u65b0\u3057\u3044BP\u30dd\u30fc\u30c8\u756a\u53f7\u306e\u8a31\u53ef\u3092\u8a2d\u5b9a\uff08\u30ea\u30ec\u30fc\u304c\uff12\u53f0\u3042\u308b\u60f3\u5b9a\uff09

sudo ufw allow from <\u30ea\u30ec\u30fc\uff11> to any port ${b_PORT}\nsudo ufw allow from <\u30ea\u30ec\u30fc\uff12> to any port ${b_PORT}\nsudo ufw reload\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/bpport/#_2","title":"\u5909\u66f4\u78ba\u8a8d","text":"
  • BP\u30dd\u30fc\u30c8\u304c\u304d\u3061\u3093\u3068\u5909\u66f4\u3055\u308c\u305f\u304b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002
ps aux | grep cardano-node\n

\u623b\u308a\u5024\u306e --port \u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

  • BP\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u5f8c\u3001\u5404\u30b5\u30fc\u30d3\u30b9\u304c\u6b63\u5e38\u7a3c\u50cd\u3057\u3066\u3044\u308b\u3053\u3068\u3082\u4f75\u305b\u3066\u78ba\u8a8d\u3057\u3066\u304a\u304d\u307e\u3059\u3002
tmux a -t cncli\ntmux a -t leaderlog\ntmux a -t logmonitor\ntmux a -t validate\ntmux a -t blockcheck\n

blockcheck\u30b5\u30fc\u30d3\u30b9\u3092\u5c0e\u5165\u3057\u3066\u3044\u308b\u5834\u5408\u306e\u30b3\u30de\u30f3\u30c9\u3082\u4f75\u305b\u3066\u8a18\u8f09\u3057\u3066\u307e\u3059\u3002

\u88dc\u8db3 \u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5\u30b3\u30de\u30f3\u30c9
sudo systemctl reload-or-restart cnode-cncli-sync.service\n
\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30c3\u30af\u518d\u8d77\u52d5\u30b3\u30de\u30f3\u30c9
sudo systemctl reload-or-restart cnode-blockcheck.service\n
\u30c7\u30bf\u30c3\u30c1\u65b9\u6cd5
Ctrl + b \u2192 d\n
"},{"location":"operation/bpport/#_3","title":"\u30ea\u30ec\u30fc\u306b\u3066\u5b9f\u65bd","text":"

\u758e\u901a\u78ba\u8a8d

0.0.0.0\u3092BPIP\u306b\u66f8\u304d\u63db\u3048\u3066\u3001 xxxxx\u3092BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5165\u529b\u3057\u5b9f\u884c\u3002

nc -vz 0.0.0.0 xxxxx\n

port [tcp/*] succeeded! \u3067\u3042\u308c\u3070OK\u3067\u3059\u3002

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u751f\u6210\u7528\u30b9\u30af\u30ea\u30d7\u30c8\u66f8\u304d\u63db\u3048

\u30c8\u30dd\u30ed\u30b8\u30fc\u5171\u6709\u306e\u305f\u3081\u5225\u30d5\u30a1\u30a4\u30eb\u3092\u81ea\u8eab\u3067\u4f5c\u6210\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u305d\u3061\u3089\u3067\u3082\u5fd8\u308c\u305a\u306b\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5909\u66f4\u3057\u3066\u304a\u3044\u3066\u304f\u3060\u3055\u3044\u3002 xxxxx\u306f\u3001BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5165\u529b\u3057\u307e\u3059\u3002

PORT=xxxxx\n
sed -i $NODE_HOME/relay-topology_pull.sh \\\n    -e '1,10s!BLOCKPRODUCING_PORT=6000!BLOCKPRODUCING_PORT='${PORT}'!'\n

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u518d\u4f5c\u6210\u3057\u307e\u3059\u3002

cd $NODE_HOME\n./relay-topology_pull.sh\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl reload-or-restart cardano-node\n

BP\u30dd\u30fc\u30c8\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

cat $NODE_HOME/mainnet-topology.json\n

"},{"location":"operation/bpport/#_4","title":"\u6700\u7d42\u78ba\u8a8d","text":"

BP\u306eGliveView\u3092\u8d77\u52d5\u3057\u3001[p] Peer Analysis\u3092\u8868\u793a\u3002 \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306eIP\u304ci\u3068o\u4e21\u65b9\u3067\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002

"},{"location":"operation/catalyst-voting/","title":"1-4.\u30ab\u30bf\u30ea\u30b9\u30c8\u6709\u6a29\u8005\u767b\u9332","text":"

\u6982\u8981

  • \u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u306f\u3001\u30d7\u30fc\u30eb\u306epayment.addr\u3092\u6709\u6a29\u8005\u767b\u9332\u3059\u308b\u65b9\u6cd5\u3067\u3059\u3002 payment.addr\u306e\u8cc7\u91d1\u3092Voting\u30d1\u30ef\u30fc\u306b\u4f7f\u7528\u3067\u304d\u3001Catalyst\u6295\u7968\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002

  • \u4f9d\u5b58\u95a2\u4fc2\u306fBP\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • \u6709\u6a29\u8005\u767b\u9332\u4f5c\u696d\u306fSJG TOOL\u3067\u884c\u3044\u307e\u3059\u3002
"},{"location":"operation/catalyst-voting/#1","title":"1. \u4e8b\u524d\u6e96\u5099\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u4ee5\u4e0b\u306e\u4f9d\u5b58\u95a2\u4fc2\u306fBP\u30b5\u30fc\u30d0\u30fc\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u304f\u3060\u3055\u3044

\u5fc5\u8981\u306a\u30d0\u30a4\u30ca\u30ea

bech32 cardano-signer catalyst-toolbox v1.1.3 v1.13.0 v0.5.0"},{"location":"operation/catalyst-voting/#bech32","title":"Bech32\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $HOME/git\nwget https://github.com/input-output-hk/bech32/archive/refs/tags/$(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz\ntar -xf $(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz\nmv bech32-$(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name | tr -d v) bech32\nrm $(curl -s https://api.github.com/repos/input-output-hk/bech32/releases/latest | jq -r .tag_name).tar.gz\n

\u30d3\u30eb\u30c9

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd bech32\ncabal update\ncabal build bech32\n

bin\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
sudo cp $(find $HOME/git/bech32/dist-newstyle/build -type f -name \"bech32\") /usr/local/bin/bech32\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
bech32 -v\n

\u623b\u308a\u5024 1.1.3

"},{"location":"operation/catalyst-voting/#cardano-signer","title":"cardano-signer\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $HOME/git\nwget https://github.com/gitmachtl/cardano-signer/releases/download/$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name)/cardano-signer-$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name | tr -d v)_linux-x64.tar.gz\ntar -xf cardano-signer-$(curl -s https://api.github.com/repos/gitmachtl/cardano-signer/releases/latest | jq -r .tag_name | tr -d v)_linux-x64.tar.gz\n

bin\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
sudo cp $HOME/git/cardano-signer /usr/local/bin/cardano-signer\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-signer help | grep -m 1 \"cardano-signer\"\n

cardano-signer 1.13.0

"},{"location":"operation/catalyst-voting/#_1","title":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3078\u30b3\u30d4\u30fc","text":"

BP\u306e$HOME/git/\u76f4\u4e0b\u306b\u3042\u308bcardano-signer\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3001\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306e$HOME/git/\u76f4\u4e0b\u306b\u30b3\u30d4\u30fc\u3059\u308b

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306b\u3042\u308bcardano-signer\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306e$HOME/git/\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|cardano-signer| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

bin\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7
sudo cp $HOME/git/cardano-signer /usr/local/bin/cardano-signer\n

\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7
sudo chmod 755 /usr/local/bin/cardano-signer\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7
cardano-signer help | grep -m 1 \"cardano-signer\"\n

cardano-signer 1.13.0

"},{"location":"operation/catalyst-voting/#catalyst-toolbox","title":"catalyst-toolbox\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $HOME/git\ngit clone https://github.com/input-output-hk/catalyst-toolbox.git\ncd catalyst-toolbox\ngit checkout 6c3ebb7\n

Rust\u30d1\u30c3\u30b1\u30fc\u30b8\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
rustup update\n

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd catalyst-toolbox\ncargo install --path . --force\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
catalyst-toolbox --version\n

catalyst-toolbox 0.5.0

"},{"location":"operation/catalyst-voting/#2","title":"2. \u6709\u6a29\u8005\u767b\u9332\u4f5c\u696d","text":""},{"location":"operation/catalyst-voting/#sjgtool","title":"SJGTOOL\u8d77\u52d5","text":"

\u6709\u6a29\u8005\u767b\u9332\u306e\u6d41\u308c

    graph LR\n        A[\u4f9d\u5b58\u95a2\u4fc2\u30c1\u30a7\u30c3\u30af] --> B[\u6295\u7968\u7528\u30ad\u30fc\u4f5c\u6210] --> C[\u30e1\u30bf\u30c7\u30fc\u30bf\u4f5c\u6210] --> D[Tx\u4f5c\u6210/\u9001\u4fe1] --> E[QR\u30b3\u30fc\u30c9\u4f5c\u6210];

\u4f5c\u6210\u30d5\u30a1\u30a4\u30eb\u306b\u3064\u3044\u3066

XXX_voting.skey / XXX_voting.vkey / XXX_voting.json (XXX\u306f\u30c6\u30a3\u30c3\u30ab\u30fc\u540d)

  • \u4e0a\u8a18\u306e3\u30d5\u30a1\u30a4\u30eb\u306f\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u3001USB\u306a\u3069\u3078\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • XXX_voting.json\u306b\u306f\u3001\u5fa9\u5143\u30d5\u30ec\u30fc\u30ba\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002 Fund11\u304b\u3089\u958b\u59cb\u4e88\u5b9a\u306eWeb\u7248Catalyst\u6295\u7968\u30bb\u30f3\u30bf\u30fc\u3092\u4f7f\u7528\u3059\u308b\u969b\u306b\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u306e\u3067\u3001\u53b3\u91cd\u306b\u4fdd\u7ba1\u3057\u3066\u4e0b\u3055\u3044\u3002

\u4e2d\u65ad\u3057\u305f\u5834\u5408

\u51e6\u7406\u304c\u9014\u4e2d\u3067\u4e2d\u65ad\u3057\u305f\u5834\u5408\u3067\u3082\u3001SJGTOOL\u3092\u8d77\u52d5\u3057[5]Catalyst\u6709\u6a29\u8005\u767b\u9332\u3092\u9078\u629e\u3059\u308c\u3070\u9014\u4e2d\u304b\u3089\u518d\u958b\u3067\u304d\u307e\u3059\u3002

"},{"location":"operation/catalyst-voting/#qr","title":"QR\u30b3\u30fc\u30c9\u4f5c\u6210\u5f8c","text":"

QR\u30b3\u30fc\u30c9\u304c\u767a\u884c\u3067\u304d\u305f\u3089$HOME/CatalystVoting\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u5185\u30d5\u30a1\u30a4\u30eb\u306e\u6574\u7406\u3092\u304a\u9858\u3044\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u540d \u30b5\u30fc\u30d0\u30fc\u5185\u51e6\u7406 \u30d0\u30c3\u30af\u30a2\u30c3\u30d7 XXX_voting.skey \u524a\u9664 \u5fc5\u9808 XXX_voting.vkey \u524a\u9664 \u5fc5\u9808 XXX_voting.json \u524a\u9664 \u5fc5\u9808 vote-registration.cbor \u524a\u9664 \u4efb\u610f XXX_vote_qrcode.png \u4fdd\u7ba1 \u5fc5\u9808 txhash.log \u4fdd\u7ba1 \u4efb\u610f"},{"location":"operation/cert-update/","title":"\u30d7\u30fc\u30eb\u60c5\u5831(pool.cert)\u306e\u66f4\u65b0","text":"

\u6982\u8981

  • \u8a93\u7d04\u3001\u56fa\u5b9a\u624b\u6570\u6599\u3001\u5909\u52d5\u624b\u6570\u6599\u3001\u30ea\u30ec\u30fc\u60c5\u5831\u3001\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u306b\u5b9f\u65bd\u3057\u307e\u3059\u3002
  • \u30e1\u30bf\u30c7\u30fc\u30bfURL\u306e\u307f\u5909\u66f4\u306b\u306a\u308b\u5834\u5408\u3067\u3082\u300c\u30e1\u30bf\u30c7\u30fc\u30bf\u66f4\u65b0\u3092\u542b\u3080\u5834\u5408\u300d\u3092\u5b9f\u65bd\u3057\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u518d\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u6ce8\u610f

\u8a93\u7d04\u30fb\u56fa\u5b9a\u624b\u6570\u6599\u30fb\u5909\u52d5\u624b\u6570\u6599\u306e\u53cd\u6620\u306f\u63d0\u51fa\u30a8\u30dd\u30c3\u30af\uff0b3\u30a8\u30dd\u30c3\u30af\u5f8c\u304b\u3089\u306b\u306a\u308a\u307e\u3059\u3002 \u4f8b\uff09 320\u30a8\u30dd\u30c3\u30af\u306b\u5909\u66f4\u7533\u8acb 321\u30a8\u30dd\u30c3\u30af\u3067\u6709\u52b9\u5316 322\u30a8\u30dd\u30c3\u30af\u3067\u5f85\u6a5f 323\u30a8\u30dd\u30c3\u30af\u3067\u53cd\u6620

\u30e1\u30bf\u30c7\u30fc\u30bf\u66f4\u65b0\u3092\u542b\u3080\u5834\u5408\u8a93\u7d04\u3001\u624b\u6570\u6599\u3001\u30ea\u30ec\u30fc\u60c5\u5831\u306e\u307f\u66f4\u65b0\u306e\u5834\u5408 \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

\u5909\u6570\u306b\u30d7\u30fc\u30eb\u30e1\u30bf\u30c7\u30fc\u30bf\u5024\u3092\u8a2d\u5b9a\u3057\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

\u6587\u5b57\u5217\u306f''\u3067\u56f2\u3063\u3066\u304f\u3060\u3055\u3044 extended\u3092\u8a2d\u5b9a\u3057\u3066\u3044\u306a\u3044\u5834\u5408\u306f ''\u306e\u307e\u307e\u3067\u5927\u4e08\u592b\u3067\u3059

name=''\ndescription=''\nticker=''\nhomepage=''\nextended=''\n

\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

\u5168\u9078\u629e\u30b3\u30d4\u30fc\u3057\u3066\u305d\u306e\u307e\u307e\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cat > $NODE_HOME/poolMetaData.json << EOF\n{\n    \"name\": \"$name\",\n    \"description\": \"$description\",\n    \"ticker\": \"$ticker\",\n    \"homepage\": \"$homepage\",\n    \"extended\": \"$extended\",\n    \"nonce\":\"$(date +%s)\"\n}\nEOF\n

poolMetaData.json\u3092\u5404\u30db\u30b9\u30c8\u30b5\u30fc\u30d0\u30fc\u3078\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b

poolMetaData.json\u3092\u30ed\u30fc\u30ab\u30eb\u30de\u30b7\u30f3\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3001Github\u307e\u305f\u306f\u3054\u81ea\u8eab\u306e\u30b5\u30fc\u30d0\u30fc\u306e\u6240\u5b9a\u306e\u4f4d\u7f6e\u306b\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044

\u30cf\u30c3\u30b7\u30e5\u5024\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt\n

\u30aa\u30f3\u30e9\u30a4\u30f3\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u5024\u78ba\u8a8d

https:****.**.**\u3092\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u306eURL\u306b\u7f6e\u304d\u63db\u3048\u3066\u304b\u3089\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cd $NODE_HOME\nwget -O onlineMetaData.json https:****.**.**\n

\u30aa\u30f3\u30e9\u30a4\u30f3\u30e1\u30bf\u30c7\u30fc\u30bf\u30cf\u30c3\u30b7\u30e5\u5024

cardano-cli stake-pool metadata-hash --pool-metadata-file onlineMetaData.json > onlineMetaDataHash.txt\n

\u30cf\u30c3\u30b7\u30e5\u5024

printf \"\\n\u3000\u30b5\u30fc\u30d0\u30fc:$(cat poolMetaDataHash.txt)\\n\u30aa\u30f3\u30e9\u30a4\u30f3:$(cat onlineMetaDataHash.txt)\\n\\n\"\n

\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u7570\u306a\u308b\u5834\u5408\u306f\u30db\u30b9\u30c8\u30b5\u30fc\u30d0\u30fc\u3078\u6b63\u3057\u304f\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3055\u308c\u3066\u3044\u308b\u304b\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002

\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u305f\u3089\u3001\u78ba\u8a8d\u7528\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3059\u308b\u3002

rm onlineMetaDataHash.txt\nrm onlineMetaData.json\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306epoolMetaDataHash.txt \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|poolMetaDataHash.txt| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30cf\u30c3\u30b7\u30e5\u5024\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\n$(cat poolMetaDataHash.txt)\n
\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\n$(cat poolMetaDataHash.txt)\n

\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u7570\u306a\u3063\u3066\u3044\u308b\u5834\u5408\u306f\u3001BP\u306epoolMetaDataHash.txt\u304c\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306b\u6b63\u3057\u304f\u30b3\u30d4\u30fc\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002

\u767b\u9332\u8a3c\u660e\u66f8\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3059\u308b

\u8907\u6570\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u8a2d\u5b9a\u3059\u308b\u5834\u5408\u306f \u8907\u6570\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u69cb\u6210\u3059\u308b\u8a18\u8ff0\u65b9\u6cd5 \u3092\u53c2\u8003\u306b\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u6307\u5b9a\u3057\u3066\u4e0b\u3055\u3044\u3002

\u6ce8\u610f

\u4ee5\u4e0b\u306f\u53c2\u8003\u30b3\u30fc\u30c9\u3067\u3059\u3002\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u8a2d\u5b9a\u5024\u306b\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044 \u4f8b\uff09

  • \u56fa\u5b9a\u8cbb\u30fb\u30fb\u30fb170ADA
  • Margin\u30fb\u30fb\u30fb5%
  • \u8a93\u7d04\u30fb\u30fb\u30fb1000ADA
\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\n
chmod u+rwx $HOME/cold-keys\ncardano-cli stake-pool registration-certificate \\\n    --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n    --vrf-verification-key-file vrf.vkey \\\n    --pool-pledge 1000000000 \\\n    --pool-cost 170000000 \\\n    --pool-margin 0.05 \\\n    --pool-reward-account-verification-key-file stake.vkey \\\n    --pool-owner-stake-verification-key-file stake.vkey \\\n    $NODE_NETWORK \\\n    --pool-relay-ipv4 ***.***.***.*** \\\n    --pool-relay-port 6000 \\\n    --metadata-url https://xxx.xxx.xxx/poolMetaData.json \\\n    --metadata-hash $(cat poolMetaDataHash.txt) \\\n    --out-file pool.cert\n

\u30d2\u30f3\u30c8

\u4e0a\u8a18\u306e\u30b3\u30fc\u30c9\u3092\u81ea\u30d7\u30fc\u30eb\u7528\u306e\u8a2d\u5b9a\u306b\u4fee\u6b63\u3057\u305f\u3089\u3001\u6b21\u56de\u3082\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u30c6\u30ad\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3068\u3057\u3066\u4fdd\u5b58\u3057\u3066\u304a\u3044\u3066\u304f\u3060\u3055\u3044\u3002

\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306b\u8a93\u7d04\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli stake-address delegation-certificate \\\n    --stake-verification-key-file stake.vkey \\\n    --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n    --out-file deleg.cert\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306epool.cert\u3068deleg.cert\u3092\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|pool.cert / deleg.cert| B[BP];

\u6700\u65b0\u306e\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u3092\u53d6\u5f97\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

build-raw\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${total_balance} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --certificate-file pool.cert \\\n    --certificate-file deleg.cert \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u624b\u6570\u6599\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 3 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u8a08\u7b97\u7d50\u679c\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}))\necho txOut: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u69cb\u7bc9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --certificate-file pool.cert \\\n    --certificate-file deleg.cert \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file $HOME/cold-keys/node.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\nchmod a-rwx $HOME/cold-keys\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

"},{"location":"operation/command/","title":"5.Linux\u30b3\u30de\u30f3\u30c9\u96c6","text":"

[AKYO] AKYO\ud83e\udd41 Akyo\u3055\u3093\u304b\u3089\u3054\u63d0\u4f9b\u3044\u305f\u3060\u304d\u307e\u3057\u305f\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\uff01

"},{"location":"operation/command/#_1","title":"\u30ce\u30fc\u30c9\u505c\u6b62","text":"
sudo systemctl stop cardano-node\n

\u203b\u30a8\u30a4\u30ea\u30a2\u30b9\u8a2d\u5b9a\u6e08\u307f\u306e\u5834\u5408

cnstop\n

"},{"location":"operation/command/#_2","title":"\u30ce\u30fc\u30c9\u8d77\u52d5","text":"
sudo systemctl start cardano-node\n

\u203b\u30a8\u30a4\u30ea\u30a2\u30b9\u8a2d\u5b9a\u6e08\u307f\u306e\u5834\u5408

cnstart\n

"},{"location":"operation/command/#_3","title":"\u30ce\u30fc\u30c9\u518d\u8d77\u52d5","text":"
sudo systemctl reload-or-restart cardano-node\n

\u203b\u30a8\u30a4\u30ea\u30a2\u30b9\u8a2d\u5b9a\u6e08\u307f\u306e\u5834\u5408

cnrestart\n

"},{"location":"operation/command/#_4","title":"\u30b5\u30fc\u30d0\u518d\u8d77\u52d5","text":"

\u88dc\u8db3 - \u30ce\u30fc\u30c9\u505c\u6b62\u3057\u3066\u304b\u3089\u5b9f\u65bd\u3057\u307e\u3057\u3087\u3046\u3002

sudo reboot\n

"},{"location":"operation/command/#_5","title":"\u30d7\u30ed\u30bb\u30b9\u78ba\u8a8d","text":"

\u88dc\u8db3 - \u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9\u30b5\u30fc\u30d3\u30b9

ps aux | grep cardano-node\n

"},{"location":"operation/command/#_6","title":"\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u78ba\u8a8d","text":"
networkctl status -a\n
"},{"location":"operation/command/#_7","title":"\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u758e\u901a\u78ba\u8a8d","text":"
nc -vz <IP> <Port>\n
"},{"location":"operation/command/#_8","title":"\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u5404\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5","text":"

\u88dc\u8db3 - (cncli / leaderlog / validate / logmonitor)

sudo systemctl reload-or-restart cnode-cncli-sync.service\n

"},{"location":"operation/command/#_9","title":"\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30c3\u30af\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5","text":"
sudo systemctl reload-or-restart cnode-blockcheck.service\n
"},{"location":"operation/command/#_10","title":"\u30d1\u30e9\u30e1\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0","text":"

\u88dc\u8db3 - \u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u53ca\u3073\u66f4\u65b0\u3001\u78ba\u8a8d

cd $NODE_HOME\ndate=`date +\\%Y\\%m\\%d`\nmv params.json params-$date.json\ncardano-cli query protocol-parameters \\\n    --mainnet \\\n    --out-file params.json\n
nano params.json\n

"},{"location":"operation/command/#tracemempooltruefalse","title":"TraceMempool\u3092True\u304b\u3089False\u306b\u3059\u308b","text":"

cd $NODE_HOME\nsed -i ${NODE_CONFIG}-config.json \\\n    -e \"s/TraceMempool\\\": true/TraceMempool\\\": false/g\"\n
- \u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u3057\u8a2d\u5b9a\u3092\u53cd\u6620\u3059\u308b
sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/command/#tracemempoolfalsetrue","title":"TraceMempool\u3092False\u304b\u3089True\u306b\u3059\u308b","text":"

cd $NODE_HOME\nsed -i ${NODE_CONFIG}-config.json \\\n    -e \"s/TraceMempool\\\": false/TraceMempool\\\": true/g\"\n
- \u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u3057\u8a2d\u5b9a\u3092\u53cd\u6620\u3059\u308b
sudo systemctl reload-or-restart cardano-node\n

"},{"location":"operation/command/#_11","title":"\u65e2\u5b58\u306e\u30b9\u30ef\u30c3\u30d7\u30d5\u30a1\u30a4\u30eb\u524a\u9664","text":"
cd $HOME\nsudo swapoff /swapfile\nsudo rm /swapfile\n
"},{"location":"operation/command/#_12","title":"\u30b9\u30ef\u30c3\u30d7\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210","text":"

\u88dc\u8db3 - 8GB\u306e\u30b9\u30ef\u30c3\u30d7\u3092\u8a2d\u5b9a\u3059\u308b\u30b3\u30de\u30f3\u30c9

sudo systemctl stop cardano-node\n
cd $HOME\nsudo fallocate -l 8G /swapfile\nsudo chmod 600 /swapfile\nsudo mkswap /swapfile\nsudo swapon /swapfile\nsudo swapon --show\nsudo cp /etc/fstab /etc/fstab.bak\necho '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab\necho 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf\necho 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf\ncat /proc/sys/vm/vfs_cache_pressure\ncat /proc/sys/vm/swappiness\n
sudo reboot\n

"},{"location":"operation/command/#ssh","title":"SSH\u63a5\u7d9a","text":"
ssh -i /Users/\u30ed\u30fc\u30ab\u30eb\u30e6\u30fc\u30b6\u540d/\u30ed\u30fc\u30ab\u30eb\u683c\u7d0d\u5148/id_rsa \u63a5\u7d9a\u5148\u30e6\u30fc\u30b6\u540d@\u63a5\u7d9a\u5148IP -p \u30dd\u30fc\u30c8\u756a\u53f7\n
"},{"location":"operation/command/#systemd","title":"systemd\u6d3b\u7528\u30b3\u30de\u30f3\u30c9","text":""},{"location":"operation/command/#_13","title":"\ud83d\uddc4 \u30ed\u30b0\u306e\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0","text":"

\u6628\u65e5\u306e\u30ed\u30b0

journalctl --unit=cardano-node --since=yesterday\n

\u30b3\u30de\u30f3\u30c9\u5165\u529b\u306b\u623b\u308b\u5834\u5408\u306f\u300cCtrl\uff0bC\u300d\uff08\u30ce\u30fc\u30c9\u306f\u7d42\u4e86\u3057\u307e\u305b\u3093\uff09

\u4eca\u65e5\u306e\u30ed\u30b0

journalctl --unit=cardano-node --since=today\n

\u30b3\u30de\u30f3\u30c9\u5165\u529b\u306b\u623b\u308b\u5834\u5408\u306f\u300cCtrl\uff0bC\u300d\uff08\u30ce\u30fc\u30c9\u306f\u7d42\u4e86\u3057\u307e\u305b\u3093\uff09

\u671f\u9593\u6307\u5b9a

journalctl --unit=cardano-node --since='2020-07-29 00:00:00' --until='2020-07-29 12:00:00'\n

\u30b3\u30de\u30f3\u30c9\u5165\u529b\u306b\u623b\u308b\u5834\u5408\u306f\u300cCtrl\uff0bC\u300d\uff08\u30ce\u30fc\u30c9\u306f\u7d42\u4e86\u3057\u307e\u305b\u3093\uff09

"},{"location":"operation/grafana-alert/","title":"Grafana\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a","text":"

\u6982\u8981

\u30b5\u30fc\u30d0\u30fc\u7570\u5e38\u72b6\u614b\u767a\u751f\u6642\u306b\u4efb\u610f\u306e\u30a2\u30d7\u30ea\u3078\u901a\u77e5\u3092\u9001\u4fe1\u3059\u308b\u8a2d\u5b9a\u3067\u3059\u3002 \u30b5\u30fc\u30d0\u30fc\u76e3\u8996\u306b\u306f\u5fc5\u9808\u8a2d\u5b9a\u3068\u306a\u308a\u307e\u3059\u3002

"},{"location":"operation/grafana-alert/#1","title":"1.\u4e8b\u524d\u78ba\u8a8d","text":"
  • Grafana\u30d0\u30fc\u30b8\u30e7\u30f3v9.4.1\u4ee5\u4e0a
  • Grafana SJG\u6700\u65b0\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u9069\u7528\u6e08\u307f
"},{"location":"operation/grafana-alert/#grafana_1","title":"Grafana\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d","text":"
grafana-cli -v\n
"},{"location":"operation/grafana-alert/#grafana_2","title":"Grafana\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"
sudo apt update -y && sudo apt upgrade -y\n
"},{"location":"operation/grafana-alert/#2","title":"2.\u30a2\u30e9\u30fc\u30c8\u30eb\u30fc\u30eb\u306e\u4f5c\u6210","text":"

\u901a\u77e5\u306e\u57fa\u6e96\u3068\u306a\u308b\u30a2\u30e9\u30fc\u30c8\u30eb\u30fc\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

1.\u300c\u5de6\u30b5\u30a4\u30c9\u30e1\u30cb\u30e5\u30fc\u300d\u2192\u300cAlerting\u300d\u306e\u53f3\u306e\u77e2\u5370\u2192\u300cAlert rules\u300d\u2192\u300cNew alert rule\u300d\u306e\u9806\u306b\u30af\u30ea\u30c3\u30af\u3059\u308b

"},{"location":"operation/grafana-alert/#2-1","title":"2-1.\u30ce\u30fc\u30c9\u30b9\u30ed\u30c3\u30c8\u76e3\u8996","text":"
  • \u2460:Relay1-\u30b9\u30ed\u30c3\u30c8\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d
  • \u2461:Metrics Browser\u3092\u30af\u30ea\u30c3\u30af
  • \u2462:cardano_node_metrics_slotInEpoch_int\u3092\u9078\u629e
  • \u2463:alias\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d
  • \u2464:\u76e3\u8996\u3059\u308b\u30ce\u30fc\u30c9\u540d\u3092\u9078\u629e
  • \u2465:Use query\u3092\u30af\u30ea\u30c3\u30af

  • \u2466:B\u306e\u30b4\u30df\u7bb1\u30de\u30fc\u30af\u3092\u30af\u30ea\u30c3\u30af

  • \u2467:C\u306e\u30b4\u30df\u7bb1\u30de\u30fc\u30af\u3092\u30af\u30ea\u30c3\u30af
  • \u2468:Add expression\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001Classic_condition\u3092\u9078\u629e

  • \u2469:last() / A / HAS NO VALUE\u9078\u629e

  • \u246a:Set as alert condition\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001Alert condition\u306e\u8868\u793a\u306b\u5909\u3048\u308b
  • \u246b:New folder\u3092\u9078\u629e\u3057\u3001SJG\u3092\u5165\u529b\u3057\u3066Create
  • \u246c:New evaluation group\u3092\u9078\u629e\u3057\u3001Evaluation group name\u306b\u30ce\u30fc\u30c9\u76e3\u8996\u3001Evaluation interval\u306b10s\u3092\u5165\u529b\u3057\u3066Create
  • \u246d:20s\u3092\u5165\u529b
  • \u246e:Alerting\u3092\u9078\u629e
  • \u246f:Alerting\u3092\u9078\u629e

  • \u2470:Add custom annotaion\u3092\u9078\u629e

  • \u2471:\u691c\u77e5\u5185\u5bb9\u3092\u5165\u529b
  • \u2472:\u30d5\u30a3\u30fc\u30eb\u30c9\u306b\u691c\u77e5\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5165\u529b \u4f8b\uff09Relay1\u306e\u30b9\u30ed\u30c3\u30c8\u3092\u53d6\u5f97\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30ce\u30fc\u30c9\u8d77\u52d5\u72b6\u614b\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e

\u6b8b\u308a\u306e\u5168\u3066\u306e\u30ce\u30fc\u30c9\u306e\u30b9\u30ed\u30c3\u30c8\u76e3\u8996\u3092\u8a2d\u5b9a\u3059\u308b

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460\u3092\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09 cardano_node_metrics_slotInEpoch_int{alias=\"block-producing-node\"} cardano_node_metrics_slotInEpoch_int{alias=\"relaynode2\"}

  • \u300c4 Add annotations\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b

  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#2-2bp","title":"2-2.BP\u2192\u30ea\u30ec\u30fc\u63a5\u7d9a\u76e3\u8996","text":"

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460:BP\u30ea\u30ec\u30fc\u63a5\u7d9a\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d\u306b\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092cardano_node_metrics_peers_connectedPeers_int{alias=\"block-producing-node\"}\u306b\u7f6e\u304d\u63db\u3048\u308b
  • \u2469:last() / A / IS BELOW\u306b\u5207\u308a\u66ff\u30481\u3092\u5165\u529b
  • \u246e:Alerting\u3092\u9078\u629e
  • \u246f:Alerting\u3092\u9078\u629e
  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09BP\u304b\u3089\u30ea\u30ec\u30fc\u3078\u306e\u63a5\u7d9a\u304c\u78ba\u8a8d\u3067\u304d\u307e\u305b\u3093\u3002\u63a5\u7d9a\u72b6\u6cc1\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#2-3","title":"2-3.\u30c1\u30a7\u30fc\u30f3\u5bc6\u5ea6\u76e3\u8996","text":"

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460:\u30c1\u30a7\u30fc\u30f3\u5bc6\u5ea6\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d\u306b\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092cardano_node_metrics_density_real{alias=\"relaynode1\"} * 100\u306b\u7f6e\u304d\u63db\u3048\u308b
  • \u2469:last() / A / IS BELOW\u306b\u5207\u308a\u66ff\u30484.5\u3092\u5165\u529b
  • \u246e:OK\u3092\u9078\u629e
  • \u246f:OK\u3092\u9078\u629e
  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09\u30c1\u30a7\u30fc\u30f3\u5bc6\u5ea6\u304c4.5\uff05\u3092\u4e0b\u56de\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306f\u30ab\u30eb\u30c0\u30ce\u30c1\u30a7\u30fc\u30f3\u5168\u4f53\u306e\u554f\u984c\u3067\u3059
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#2-4","title":"2-4.\u30ce\u30fc\u30c9\u30bf\u30a4\u30e0\u76e3\u8996","text":"

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460:Relay1-\u30ce\u30fc\u30c9\u30bf\u30a4\u30e0\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d\u306b\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092node_timex_maxerror_seconds{alias=\"relaynode1\"} * 1000\u306b\u7f6e\u304d\u63db\u3048\u308b
  • \u2469:last() / A / IS ABOVE\u306b\u5207\u308a\u66ff\u3048100\u3092\u5165\u529b
  • \u246e:OK\u3092\u9078\u629e
  • \u246f:OK\u3092\u9078\u629e
  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09Relay1\u306e\u30ce\u30fc\u30c9\u30bf\u30a4\u30e0\u304c100ms\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\u3002chrony\u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e

\u6b8b\u308a\u5168\u3066\u306e\u30ce\u30fc\u30c9\u306e\u30ce\u30fc\u30c9\u30bf\u30a4\u30e0\u76e3\u8996\u3092\u8a2d\u5b9a\u3059\u308b

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460\u3092\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09 node_timex_maxerror_seconds{alias=\"block-producing-node\"} * 1000 node_timex_maxerror_seconds{alias=\"relaynode2\"} * 1000

  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b

  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#2-5kes","title":"2-5.KES\u6b8b\u308a\u65e5\u6570\u76e3\u8996","text":"

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460:BP-KES\u6b8b\u308a\u65e5\u6570\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d\u306b\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092(cardano_node_metrics_remainingKESPeriods_int * 1.5)\u306b\u7f6e\u304d\u63db\u3048\u308b
  • \u2469:last() / A / IS BELOW\u306b\u5207\u308a\u66ff\u304810\u3092\u5165\u529b
  • \u246e:OK\u3092\u9078\u629e
  • \u246f:OK\u3092\u9078\u629e
  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09KES\u30ad\u30fc\u306e\u671f\u9650\u304c\u8feb\u3063\u3066\u3044\u307e\u3059\u3002\u30d6\u30ed\u30c3\u30af\u751f\u6210\u4e88\u5b9a\u306e\u306a\u3044\u30bf\u30a4\u30df\u30f3\u30b0\u3067KES\u30ad\u30fc\u3092\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#2-6","title":"2-6.\u30c7\u30a3\u30b9\u30af\u4f7f\u7528\u7387\u76e3\u8996","text":"

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460:Relay1-\u30c7\u30a3\u30b9\u30af\u4f7f\u7528\u7387\u76e3\u8996\u306a\u3069\u4efb\u610f\u306e\u30eb\u30fc\u30eb\u540d\u306b\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u30921 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias=\"relaynode1\",mountpoint=\"/\"}\u306b\u7f6e\u304d\u63db\u3048\u308b
  • \u2469:last() / A / IS ABOVE\u306b\u5207\u308a\u66ff\u30480.9\u3092\u5165\u529b
  • \u246e:OK\u3092\u9078\u629e
  • \u246f:OK\u3092\u9078\u629e
  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09Relay1\u306e\u30c7\u30a3\u30b9\u30af\u4f7f\u7528\u7387\u304c90%\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\u3002100%\u306b\u9054\u3059\u308b\u524d\u306b\u5951\u7d04\u30b5\u30fc\u30d0\u30fc\u306e\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306a\u3069\u3092\u884c\u3046\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e

\u6b8b\u308a\u5168\u3066\u306e\u30ce\u30fc\u30c9\u306e\u30c7\u30a3\u30b9\u30af\u4f7f\u7528\u7387\u76e3\u8996\u3092\u8a2d\u5b9a\u3059\u308b

\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30eb\u30fc\u30eb\u3092\u30b3\u30d4\u30fc\u3059\u308b

  • \u2460\u3092\u66f8\u304d\u63db\u3048\u308b
  • \u2461:Metrics Browser\u3092\u66f8\u304d\u63db\u3048\u308b \u4f8b\uff09 1 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias=\"block-producing-node\",mountpoint=\"/\"} 1 - node_filesystem_avail_bytes / node_filesystem_size_bytes{alias=\"relaynode2\",mountpoint=\"/\"}

  • \u300c4 Add annotation\u300d\u306e\u691c\u77e5\u5185\u5bb9\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b

  • \u2473:\u30da\u30fc\u30b8\u4e0a\u90e8\u306eSave rule and exit\u3092\u9078\u629e
"},{"location":"operation/grafana-alert/#3","title":"3.\u901a\u77e5\u5148\u30a2\u30d7\u30ea\u306e\u8a2d\u5b9a","text":"

\u901a\u77e5\u5148\u30a2\u30d7\u30ea\u306e\u8a2d\u5b9a

\u30a2\u30e9\u30fc\u30c8\u306e\u901a\u77e5\u5148\u306fLINE/Discord/Telegram/Slack\u3092\u8907\u6570\u6307\u5b9a\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002 \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u306e\u901a\u77e5\u30a2\u30d7\u30ea\u8a2d\u5b9a\u3067\u8a2d\u5b9a\u3057\u305f\u624b\u9806\u3068\u540c\u69d8\u306b\u3001\u901a\u77e5\u5148\u540d\u306a\u3069\u3092\u5909\u3048\u3066\u30c8\u30fc\u30af\u30f3\u3092\u767a\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/grafana-alert/#4","title":"4.\u901a\u77e5\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u8a2d\u5b9a","text":"
  • \u300cContact points\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u300cAdd template\u300d\u3092\u30af\u30ea\u30c3\u30af

  • \u4efb\u610f\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u540dSJG\u3092\u5165\u529b\u3057\u3001\u4ee5\u4e0b\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30c7\u30fc\u30bf\u3092\u5165\u529b

    {{ define \"myalert\" }}\n{{ if gt (len .Annotations) 0 }}{{ range .Annotations.SortedPairs }}{{ .Name }}: {{ .Value }}{{ end }}\n{{ end }}{{ end }}\n\n\n{{ define \"mymessage\" }}\n{{ if gt (len .Alerts.Firing) 0 }} \u3010 \u274c\u969c\u5bb3\u767a\u751f\u274c \u3011{{len .Alerts.Firing}}\u4ef6 {{ range .Alerts.Firing }}\n{{ template \"myalert\" .}} {{ end }}{{ end }}\n{{ if gt (len .Alerts.Resolved) 0 }}\u2705\u4ee5\u4e0b\u306e\u969c\u5bb3\u306f\u5fa9\u65e7\u3057\u307e\u3057\u305f\u2705{{len .Alerts.Resolved}}\u4ef6{{ range .Alerts.Resolved }}\n{{ template \"myalert\" .}} {{ end }}{{ end }}\n{{ end }}\n

  • \u300cSave tempelate\u300d\u3092\u30af\u30ea\u30c3\u30af

"},{"location":"operation/grafana-alert/#5","title":"5.\u901a\u77e5\u5148\u8a2d\u5b9a","text":"
  • \u300cAdd contact point\u300d\u3092\u30af\u30ea\u30c3\u30af

\u901a\u77e5\u5148\u3092\u6307\u5b9a\u3059\u308b

  • \u4efb\u610f\u306e\u901a\u77e5\u540dSelf-Alert\u3092\u5165\u529b
  • \u901a\u77e5\u5148\u3092\u9078\u629e\u3057\u60c5\u5831\u3092\u5165\u529b
  • [3.\u901a\u77e5\u5148\u30a2\u30d7\u30ea\u306e\u8a2d\u5b9a]\u3067\u53d6\u5f97\u3057\u305f\u901a\u77e5\u30a2\u30d7\u30ea\u3054\u3068\u306e\u30c8\u30fc\u30af\u30f3ID\u3084WebhookURL\u3092\u5165\u529b\u3059\u308b
  • Option *** Settings\u3092\u30af\u30ea\u30c3\u30af\u3057Discription\u306b\u4ee5\u4e0b\u306e\u30bf\u30b0\u3092\u5165\u529b
    {{ template \"mymessage\" . }}\n

\u901a\u77e5\u5148\u3054\u3068\u306e\u30bf\u30b0\u5165\u529b\u6b04\u8868\u8a18\u9055\u3044

  • LINE\u2192Description
  • Discord\u2192Message Content
  • Slack\u2192Text Body
  • Telegram\u2192Message

  • \u300cSave contact point\u300d\u3092\u30af\u30ea\u30c3\u30af

\u8907\u6570\u306e\u901a\u77e5\u5148\u3092\u8a2d\u5b9a\u53ef\u80fd

\u300cAdd contact point integration\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308c\u3070\u3001\u8907\u6570\u306e\u901a\u77e5\u5148\u3092\u8a2d\u5b9a\u53ef\u80fd

  • \u300cNotification policies\u300d\u2192\u300cEdit\u300d\u3092\u30af\u30ea\u30c3\u30af

  • Self-Alert\u3092\u9078\u629e

  • Group by\u306bgrafana_folder\u3068alertname\u3092\u6307\u5b9a
  • Group interval\u2192 1 Minutes\u306b\u8a2d\u5b9a
  • Repeat interval\u2192 10 Minutes\u306b\u8a2d\u5b9a
  • \u300cUpdate default policy\u300d\u3092\u30af\u30ea\u30c3\u30af
"},{"location":"operation/grafana-alert/#6url","title":"6.\u901a\u77e5\u5185\u5bb9URL\u30ab\u30b9\u30bf\u30de\u30a4\u30ba","text":"

\u6ce8\u610f

  • \u4e8b\u524d\u306bGrafana\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044
  • \u4ee5\u4e0b\u306fGrafana\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30b5\u30fc\u30d0\u30fc\u3067\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044

xxxx.bbb.com\u3092[Grafana\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a]\u3067\u53d6\u5f97\u3057\u305f\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u306b\u7f6e\u304d\u63db\u3048\u3066\u5b9f\u884c\u3059\u308b https://\u306f\u4e0d\u8981

domain=xxxx.bbb.com\n

\u4ee5\u4e0b\u30b3\u30de\u30f3\u30c9\u3092\u3059\u3079\u3066\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3059\u308b

sudo sed -i /etc/grafana/grafana.ini \\\n    -e 's!;domain = localhost!domain = '${domain}'!' \\\n    -e 's!;root_url = %(protocol)s://%(domain)s:%(http_port)s/!root_url = https://%(domain)s/!'\n

Grafana\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl restart grafana-server.service\n

"},{"location":"operation/grafana-repo/","title":"Grafana\u30ea\u30dd\u30b8\u30c8\u30ea\u8a2d\u5b9a\u5909\u66f4\u624b\u9806","text":"

\u6982\u8981

  • \u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u3067\u306f\u65e7\u5f0f\u306eGrafana\u66f4\u65b0\u7528APT\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u66f4\u65b0\u3057\u307e\u3059\u3002
  • Grafana\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u30b5\u30fc\u30d0\u30fc(Relay1)\u306e\u307f\u5bfe\u8c61\u3067\u3059\u3002

  • \u8a2d\u5b9a\u6e08\u307f\u306eAPT\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u78ba\u8a8d\u3059\u308b

    cat /etc/apt/sources.list.d/grafana.list | grep \"https://packages.grafana.com/oss/deb\"\n

    deb https://packages.grafana.com/oss/deb stable main\u306e\u623b\u308a\u5024\u304c\u3042\u308b\u5834\u5408\u3001\u4ee5\u4e0b\u306e\u4f5c\u696d\u5bfe\u8c61\u3067\u3059\u3002

"},{"location":"operation/grafana-repo/#1gpg","title":"1.GPG\u30ad\u30fc\u306e\u78ba\u8a8d","text":"

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u306eGPG\u7f72\u540d\u30ad\u30fc\u3092\u78ba\u8a8d\u3059\u308b

sudo apt-key list | grep -B 1 Grafana\n

Ubuntu22.04\u306e\u5834\u5408\u306f\u300cWarning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).\u300d\u3068\u3044\u3046\u6587\u5b57\u304c\u51fa\u307e\u3059\u304c\u7121\u8996\u3067\u5927\u4e08\u592b\u3067\u3059\u3002

\u623b\u308a\u5024 \u4f8b\uff09

       4E40 DDF6 D76E 284A 4A67  80E4 8C8C 34C5 2409 8CB6\n uid           [ unknown] Grafana <info@grafana.com>\n

"},{"location":"operation/grafana-repo/#2gpg","title":"2.\u65e7GPG\u7f72\u540d\u30ad\u30fc\u524a\u9664","text":"

\u30ad\u30fc\u3092\u30b3\u30d4\u30fc\u3057\u3066\u524a\u9664\u30b3\u30de\u30f3\u30c9\u3092\u4f5c\u6210\u3057\u3066\u5b9f\u884c\u3059\u308b\u3002

\u524a\u9664\u30b3\u30de\u30f3\u30c9 \u4f8b\uff09

sudo apt-key del \"4E40 DDF6 D76E 284A 4A67  80E4 8C8C 34C5 2409 8CB6\"\n

\u78ba\u8a8d

  • \"\"\u5185\u306e\u30ad\u30fc\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3082\u306e\u306b\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u623b\u308a\u5024\u306b\u30ad\u30fc\u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306f\u3001\u5168\u3066\u306e\u30ad\u30fc\u3092\u524a\u9664\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • Ubuntu22.04\u306e\u5834\u5408\u306f\u300cWarning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).\u300d\u3068\u3044\u3046\u6587\u5b57\u304c\u51fa\u307e\u3059\u304c\u7121\u8996\u3067\u5927\u4e08\u592b\u3067\u3059\u3002
"},{"location":"operation/grafana-repo/#3","title":"3.\u65b0\u30ea\u30dd\u30b8\u30c8\u30ea\u8ffd\u52a0","text":"
echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main\" | sudo tee -i /etc/apt/sources.list.d/grafana.list\n

Ubuntu22.04\u306e\u5834\u5408\u306f\u3053\u3061\u3089\u3082\u5b9f\u884c

sudo apt update -y && sudo apt install -y needrestart\n
echo \"\\$nrconf{restart} = 'a';\" | sudo tee /etc/needrestart/conf.d/50local.conf\n
echo \"\\$nrconf{blacklist_rc} = [qr(^cardano-node\\\\.service$) => 0,];\" | sudo tee -a /etc/needrestart/conf.d/50local.conf\n

\u4f9d\u5b58\u95a2\u4fc2\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

sudo apt install -y apt-transport-https software-properties-common\n

\u65b0GPG\u30ad\u30fc\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key\n

\u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8

sudo apt update -y && sudo apt upgrade -y\n

Grafana\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

grafana-server -v\n

Version 10.1.2 (commit: 8e428858dd, branch: HEAD) \u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u5b9f\u65bd\u6642\u671f\u306b\u3088\u3063\u3066\u5909\u52d5\u3057\u307e\u3059\u3002

\u4ee5\u4e0a\u3067\u3059\u3002

"},{"location":"operation/grafana-security/","title":"Grafana\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u8a2d\u5b9a","text":"

\u6982\u8981

\u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u3067\u306fGrafana\u306e\u30ea\u30e2\u30fc\u30c8\u30a2\u30af\u30bb\u30b9\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5f37\u5316\u3059\u308b\u305f\u3081HTTPS\u5316\u3068\u30ea\u30d0\u30fc\u30b9\u30d7\u30ed\u30ad\u30b7\u306e\u5c0e\u5165\u8a2d\u5b9a\u3092\u884c\u3044\u307e\u3059\u3002

"},{"location":"operation/grafana-security/#_1","title":"\u25a0\u4e8b\u524d\u78ba\u8a8d","text":"

\u4ee5\u4e0b\u306e\u624b\u9806\u306f\u30019.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3067Grafana\u3092\u5c0e\u5165\u3057\u305f\u65e2\u5b58\u306e\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u3067\u5b9f\u65bd\u53ef\u80fd\u3067\u3059\u3002

\uff5e\u4f5c\u696d\u306e\u6d41\u308c\uff5e

  1. \u72ec\u81ea\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u3092\u53d6\u5f97 \u3000 \u203b\u7121\u6599\u30c9\u30e1\u30a4\u30f3\u53d6\u5f97\u624b\u9806\u3082\u63b2\u8f09
  2. WEB\u30b5\u30fc\u30d0\u30fcnginx\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30fb\u30ea\u30d0\u30fc\u30b9\u30d7\u30ed\u30ad\u30b7\u8a2d\u5b9a
  3. certbot\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb
  4. \u7121\u6599SSL\u8a3c\u660e\u66f8(Let\u2019s Encrypt)\u3092\u53d6\u5f97
  5. nginx\u8a2d\u5b9a\u5909\u66f4
  6. SSL\u8a3c\u660e\u66f8\u81ea\u52d5\u66f4\u65b0\u3092\u8a2d\u5b9a

\u4f5c\u696d\u524d\u306e\u6ce8\u610f\u4e8b\u9805

\u4ee5\u4e0b\u306e\u6587\u7ae0\u3092\u3088\u304f\u8aad\u307f\u306a\u304c\u3089\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002\u30b3\u30de\u30f3\u30c9\u306e\u5b9f\u884c\u5fd8\u308c\u30fb\u30b3\u30de\u30f3\u30c9\u30b3\u30d4\u30fc\u30df\u30b9\u306a\u3069\u306b\u5341\u5206\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/grafana-security/#1","title":"1.\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u3092\u53d6\u5f97\u3059\u308b","text":"

\u78ba\u8a8d

\u30db\u30fc\u30e0\u30da\u30fc\u30b8\u306a\u3069\u306e\u904b\u7528\u3067\u3059\u3067\u306b\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u53d6\u5f97\u6e08\u307f\u306e\u5834\u5408\u306f\u305d\u3061\u3089\u3092\u4f7f\u7528\u51fa\u6765\u307e\u3059\u3002\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u304a\u6301\u3061\u3067\u306a\u3044\u65b9\u306f\u7121\u6599\u30c0\u30a4\u30ca\u30df\u30c3\u30afDNS\u3067\u30c9\u30e1\u30a4\u30f3\u3092\u53d6\u5f97\u3067\u304d\u307e\u3059\u3002

\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u304a\u6301\u3061\u306e\u65b9\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u6301\u3063\u3066\u3044\u306a\u3044\u65b9

\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u304a\u6301\u3061\u306e\u65b9\u306f\u3001\u767b\u9332\u30ec\u30b8\u30b9\u30c8\u30e9\u306eDNS\u8a2d\u5b9a\u3067Grafana\u7528\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u53c2\u8003\uff09 \u30db\u30b9\u30c8\u540d\uff1a\u4efb\u610f\u306e\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u540d TYPE\uff1aA VALUE(\u5024):\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fcIP\u30a2\u30c9\u30ec\u30b9

DDNS Now\u3067\u7121\u6599\u306e\u30c9\u30e1\u30a4\u30f3\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002 DDNS Now\u306f\u5b8c\u5168\u7121\u6599\u30fb\u5b9a\u671f\u901a\u77e5\u4e0d\u8981\u30fb\u30b5\u30fc\u30d3\u30b9\u4fdd\u969c\u7a3c\u50cd\u7387100%\u306a\u3069\u3001\u4f7f\u3044\u3084\u3059\u3044DDNS\u30b5\u30fc\u30d3\u30b9\u3067\u3059\u3002\u305f\u3060\u3057\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u306a\u3069\u306f\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093\u30021\u30a2\u30ab\u30a6\u30f3\u30c81\u30c9\u30e1\u30a4\u30f3

\u30c9\u30e1\u30a4\u30f3(\u30a2\u30ab\u30a6\u30f3\u30c8)\u3092\u53d6\u5f97\u3059\u308b \u3053\u3053\u3067\u53d6\u5f97\u3057\u305f\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3\u304cGrafana\u306eURL\u306b\u306a\u308a\u307e\u3059\u3002

\u4f8b\uff09grafana-abc.f5.si

\u8a73\u7d30\u8a2d\u5b9a\u304b\u3089DNS\u306eA\u30ec\u30b3\u30fc\u30c9\u3092\u8a2d\u5b9a\u3059\u308b \u300cA\u30ec\u30b3\u30fc\u30c9(IPv4\u30a2\u30c9\u30ec\u30b9)\u300d\u6b04\u306bGrafana\u3092\u5c0e\u5165\u3057\u3066\u3044\u308b\u30b5\u30fc\u30d0\u30fc\u306eIP\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3057\u3066\u300c\u8a2d\u5b9a\u3092\u5909\u66f4\u3059\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044

\u767b\u9332\u60c5\u5831\u78ba\u8a8d

"},{"location":"operation/grafana-security/#2nginx","title":"2.nginx\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b","text":"

sudo apt install nginx -y\n
\u30b9\u30c6\u30fc\u30bf\u30b9\u78ba\u8a8d
sudo systemctl --no-pager status nginx\n

\u7dd1\u8272\u3067\u300cactive (running)\u300d\u306b\u306a\u3063\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002

HTTP/HTTPS\u7528\u30dd\u30fc\u30c8\u3092\u958b\u653e\u3059\u308b

sudo ufw allow 80/tcp\nsudo ufw allow 443/tcp\n

\u958b\u653e\u4e2d\u306eGrafana\u75283000\u30dd\u30fc\u30c8\u3092\u524a\u9664\u3059\u308b numbered \u3067\u8868\u793a\u3055\u308c\u305f3000\u30dd\u30fc\u30c8\u306e\u756a\u53f7\u3092\u6307\u5b9a\u3057\u3066\u524a\u9664\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo ufw status numbered\nsudo ufw delete \u756a\u53f7\n

ufw\u3092\u30ea\u30ed\u30fc\u30c9\u3059\u308b

sudo ufw reload\n

\u78ba\u8a8d

\u30ed\u30fc\u30ab\u30eb\u30d6\u30e9\u30a6\u30b6\u304b\u3089 http://\u30ea\u30ec\u30fcIP\u30a2\u30c9\u30ec\u30b9 \u306b\u30a2\u30af\u30bb\u30b9\u3057\u3066 Nginx Welcome\u30da\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308c\u3070OK\uff01

xxxx.bbb.com\u3092[1.\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u3092\u53d6\u5f97\u3059\u308b]\u3067\u53d6\u5f97\u3057\u305f\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u306b\u7f6e\u304d\u63db\u3048\u3066\u5b9f\u884c\u3059\u308b

domain=xxxx.bbb.com\n

\u4eee\u60f3\u30db\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

sudo cat > $HOME/$domain.conf << EOF\nserver { \n    listen 80;\n    server_name $domain;\n\n    location / {\n    proxy_set_header Host \\$http_host;\n    proxy_pass http://localhost:3000;\n    } \n}\nEOF\n

\u4eee\u60f3\u30db\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092nginx\u30d5\u30a9\u30eb\u30c0\u3078\u79fb\u52d5\u3059\u308b

sudo mv $HOME/$domain.conf /etc/nginx/sites-enabled/\n

nginx\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl restart nginx\n

\u78ba\u8a8d

\u30ed\u30fc\u30ab\u30eb\u30d6\u30e9\u30a6\u30b6\u304b\u3089http://\u30c9\u30e1\u30a4\u30f3\u540d\u3067\u30a2\u30af\u30bb\u30b9\u3057\u3001Grafana\u30ed\u30b0\u30a4\u30f3\u753b\u9762\u304c\u8868\u793a\u3055\u308c\u308c\u3070\u30ea\u30d0\u30fc\u30b9\u30d7\u30ed\u30ad\u30b7\u8a2d\u5b9a\u306b\u6210\u529f\u3057\u307e\u3057\u305f\uff01

\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30db\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3059\u308b

sudo rm /etc/nginx/sites-enabled/default\n

"},{"location":"operation/grafana-security/#3certbot","title":"3.certbot\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b","text":"
sudo snap install core; sudo snap refresh core\n

\u300cDownload snap \"core\" (14784) from channel \"stable\"\u300d\u3068\u8868\u793a\u3055\u308c\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306b\u6570\u5206\u304b\u304b\u308a\u307e\u3059\u3002

\u623b\u308a\u5024\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u7570\u306a\u308b\u5834\u5408(\u30af\u30ea\u30c3\u30af\u3057\u3066\u958b\u304f) \u30d1\u30bf\u30fc\u30f31\u30d1\u30bf\u30fc\u30f32
snap \"core\" is already installed, see 'snap help refresh'\nsnap \"core\" has no updates available\n

\u3053\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u3067\u3059\u3002\u6b21\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002

sudo: snap: command not found \nsudo: snap: command not found\n
\u3053\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u306fsnap\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 \u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo apt update -y\nsudo apt install snapd -y\n

snap\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304c\u5b8c\u4e86\u3057\u305f\u3089\u4ee5\u4e0b\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo snap install core; sudo snap refresh core\n

\uff1c\u623b\u308a\u5024\uff1e

\u300cDownload snap \"core\" (14784) from channel \"stable\"\u300d \n\n2023-02-24T10:18:49+01:00 INFO Waiting for automatic snapd restart...\ncore 16-2.58.2 from Canonical\u2713 installed\nsnap \"core\" has no updates available\n

\u3068\u8868\u793a\u3055\u308c\u305f\u3089\u6b21\u306b\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002

sudo snap install --classic certbot\n

\u300cDownload snap \"core20\" (1822) from channel \"stable\u300d\u3068\u8868\u793a\u3055\u308c\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306b\u6570\u5206\u304b\u304b\u308a\u307e\u3059

certbot\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u3078\u30b3\u30d4\u30fc\u3059\u308b

sudo ln -s /snap/bin/certbot /usr/bin/certbot\n

"},{"location":"operation/grafana-security/#4ssllets-encrypt","title":"4.\u7121\u6599SSL\u8a3c\u660e\u66f8(Let\u2019s Encrypt)\u3092\u53d6\u5f97\u3059\u308b","text":"
sudo certbot --nginx\n

\u753b\u9762\u4e0a\u306e\u8cea\u554f\u306b\u56de\u7b54\u3057\u307e\u3059\u3002

  1. \u4efb\u610f\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u767b\u9332 \u3053\u3053\u3067\u767b\u9332\u3057\u305f\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306bSSL\u8a3c\u660e\u66f8\u66f4\u65b0\u524d\u30fb\u671f\u9650\u5207\u308c\u60c5\u5831\u306e\u901a\u77e5\u304c\u5c4a\u304d\u307e\u3059\u3002

  2. Let's Encrypt\u30b5\u30fc\u30d3\u30b9\u5229\u7528\u898f\u7d04\u3078\u306e\u540c\u610f\u78ba\u8a8d

  3. \u30ad\u30e3\u30f3\u30da\u30fc\u30f3\u30e1\u30fc\u30eb\u767b\u9332\u78ba\u8a8d(\u4e0d\u8981\u306a\u3089N)

  4. SSL\u8a3c\u660e\u66f8\u767b\u9332\u30c9\u30e1\u30a4\u30f3\u306e\u78ba\u8a8d 1:\u306b\u3054\u81ea\u8eab\u306e\u30c9\u30e1\u30a4\u30f3\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u30011\u3092\u5165\u529b

  5. SSL\u8a3c\u660e\u66f8\u53d6\u5f97\u78ba\u8a8d This certificate expires on\u306f\u53d6\u5f97\u3057\u305fSSL\u8a3c\u660e\u66f8\u306e\u6709\u52b9\u671f\u9650\u306a\u306e\u3067\u899a\u3048\u3066\u304a\u304d\u307e\u3057\u3087\u3046\uff01 Congratulations!\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308c\u3070\u7f72\u540d\u66f8\u53d6\u5f97\u6210\u529f\u3067\u3059\uff01

\u78ba\u8a8d

\u30ed\u30fc\u30ab\u30eb\u30d6\u30e9\u30a6\u30b6\u304b\u3089https://\u30c9\u30e1\u30a4\u30f3\u540d\u3067\u30a2\u30af\u30bb\u30b9\u3057\u3001Grafana\u30ed\u30b0\u30a4\u30f3\u753b\u9762\u304c\u8868\u793a\u3055\u308c\u308c\u3070HTTPS\u5316\u306b\u6210\u529f\u3057\u307e\u3057\u305f\uff01 \u30c9\u30e1\u30a4\u30f3\u3067\u30a2\u30af\u30bb\u30b9\u3057\u305f\u969b\u306eURL\u6b04\u306b\u304a\u3044\u3066\u3001http\u306e\u5f8c\u306bs\u304c\u3064\u3044\u3066\u3044\u308b\u304b\u3069\u3046\u304b\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/grafana-security/#5nginx","title":"5.nginx\u8a2d\u5b9a\u5909\u66f4","text":"

1.websocket\u3092\u6709\u52b9\u306b\u3059\u308b xxxx.bbb.com\u3092[1.\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u3092\u53d6\u5f97\u3059\u308b]\u3067\u53d6\u5f97\u3057\u305f\u30c9\u30e1\u30a4\u30f3(\u30b5\u30d6\u30c9\u30e1\u30a4\u30f3)\u306b\u7f6e\u304d\u63db\u3048\u3066\u5b9f\u884c\u3059\u308b

domain=xxxx.bbb.com\n

\u4eee\u60f3\u30db\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f

sudo nano /etc/nginx/sites-enabled/$domain.conf\n

location /\u30d6\u30ed\u30c3\u30af\u3092\u4ee5\u4e0b\u306e\u5185\u5bb9\u306b\u66f8\u304d\u63db\u3048\u308b

    location / {\n    proxy_set_header Host $http_host;\n    proxy_pass http://localhost:3000;\n    }\n\n    location /api/live {\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $connection_upgrade;\n    proxy_set_header Host $http_host;\n    proxy_pass http://localhost:3000;\n    }\n

\u7de8\u96c6\u5f8c\u53c2\u8003\uff09

\u8ffd\u8a18\u3057\u305f\u3089\u4fdd\u5b58\u3057\u3066\u9589\u3058\u308b

2.nginx \u69cb\u6210\u30d5\u30a1\u30a4\u30eb\u306e\u5f37\u5316 \u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f

sudo nano /etc/nginx/nginx.conf\n

SSL Settings\u306e TLSv1\u3068TLSv1.1\u3092\u524a\u9664\u3059\u308b \u7de8\u96c6\u5f8c\u53c2\u8003\uff09

\u7d9a\u3051\u3066\u3001\u4ee5\u4e0b\u306e\u6587\u3092\u5168\u3066\u30b3\u30d4\u30fc\u3057\u3066include /etc/nginx/site-enabled/*;\u306e\u5f8c\u306b\u8ffd\u8a18\u3059\u308b

        ## Start: Size Limits & Buffer Overflows ##\n        client_body_buffer_size  3K;\n        client_header_buffer_size 3k;\n        client_max_body_size 80k;\n        large_client_header_buffers 2 10k;\n        ## END: Size Limits & Buffer Overflows ##\n\n        ### Directive describes the zone, in which the session states are stored i.e. store in slimits. ###\n        ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ###\n        limit_conn_zone $binary_remote_addr zone=addr:5m;\n\n        ### Control maximum number of simultaneous connections for one session i.e. ###\n        ### restricts the amount of connections from a single ip address ###\n        limit_conn addr 10;\n\n        map $http_upgrade $connection_upgrade {\n            default upgrade;\n            ''      close;\n        }\n

\u8d64\u67a0\u306e } \u306e\u4f4d\u7f6e\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u7de8\u96c6\u5f8c\u53c2\u8003\uff09

\u8ffd\u8a18\u3057\u305f\u3089\u4fdd\u5b58\u3057\u3066\u9589\u3058\u308b

nginx\u30a8\u30e9\u30fc\u30c1\u30a7\u30c3\u30af

sudo nginx -t\n

\u623b\u308a\u5024

\u6b63\u5e38\u306a\u5834\u5408\u30a8\u30e9\u30fc\u304c\u3042\u308b\u5834\u5408(\u4f8b)
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nnginx: configuration file /etc/nginx/nginx.conf test is successful\n

nginx: [emerg] unexpected \"}\" in /etc/nginx/sites-enabled/******.conf:8\nnginx: configuration file /etc/nginx/nginx.conf test failed\n
\u30a8\u30e9\u30fc\u7b87\u6240\u3092\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044\u3002

nginx\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl restart nginx\n

"},{"location":"operation/grafana-security/#6ssl","title":"6.SSL\u8a3c\u660e\u66f8\u81ea\u52d5\u66f4\u65b0","text":"

1.SSL\u8a3c\u660e\u66f8\u81ea\u52d5\u66f4\u65b0\u30bf\u30a4\u30de\u30fc\u78ba\u8a8d \u3053\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3067SSL\u8a3c\u660e\u66f8\u304c\u81ea\u52d5\u66f4\u65b0\u3055\u308c\u307e\u3059\u3002

systemctl status snap.certbot.renew.timer\n

\u7dd1\u8272\u3067\u300cactive(wating)\u300d\u306b\u306a\u3063\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002

2.nginx\u81ea\u52d5\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8 \u81ea\u52d5\u66f4\u65b0\u3055\u308c\u305fSSL\u8a3c\u660e\u66f8\u3092\u6709\u52b9\u306b\u3059\u308b\u305f\u3081\u3001nginx\u518d\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002

cat > $HOME/nginx-reload.sh << EOF\n#!/bin/bash \nsudo systemctl reload nginx\nEOF\n
sudo mv $HOME/nginx-reload.sh /etc/letsencrypt/renewal-hooks/deploy/\n
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/nginx-reload.sh\n

3.\u6307\u5b9a\u30e6\u30fc\u30b6\u30fc\u3068\u6307\u5b9a\u30b3\u30de\u30f3\u30c9\u3067sudo\u30d1\u30b9\u30ef\u30fc\u30c9\u8981\u6c42\u3092\u7121\u52b9\u306b\u3059\u308b \u30b7\u30a7\u30eb\u30b9\u30af\u30ea\u30d7\u30c8\u5185\u3067sudo\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u305f\u3081\u3001\u30b9\u30af\u30ea\u30d7\u30c8\u81ea\u52d5\u5b9f\u884c\u306b\u30d1\u30b9\u30ef\u30fc\u30c9\u8981\u6c42\u3092\u30b9\u30eb\u30fc\u51fa\u6765\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3059\u3002

\u30ed\u30b0\u30a4\u30f3\u30e6\u30fc\u30b6\u30fc\u540d\u3092\u78ba\u8a8d\u3059\u308b(\u63a7\u3048\u308b)

whoami\n
sudo\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f
sudo visudo\n
\u4ee5\u4e0b\u30b3\u30de\u30f3\u30c9\u306exxxx\u3092\u3001\u4e0a\u8a18\u3067\u8abf\u3079\u305f\u30ed\u30b0\u30a4\u30f3\u30e6\u30fc\u30b6\u30fc\u540d\u306b\u66f8\u304d\u63db\u3048\u3066\u8ffd\u8a18\u3059\u308b
xxxx ALL=NOPASSWD: /bin/systemctl\n

\u3053\u306e\u307e\u307e\u8ffd\u8a18\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002xxxx\u3092\u30e6\u30fc\u30b6\u30fc\u540d\u306b\u66f8\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044

\u7de8\u96c6\u5f8c\u53c2\u8003\uff09

\u8ffd\u8a18\u3057\u305f\u3089\u4fdd\u5b58\u3057\u3066\u9589\u3058\u308b

"},{"location":"operation/kes-update/","title":"KES\u306e\u66f4\u65b0","text":"

\u6982\u8981

(KES=Key Evolving Signature)\u306e\u7565 \u30ad\u30fc\u3092\u60aa\u7528\u3059\u308b\u30cf\u30c3\u30ab\u30fc\u304b\u3089\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u4fdd\u8b77\u3059\u308b\u305f\u3081\u306b\u4f5c\u6210\u3055\u308c\u300190\u65e5\u3054\u3068\u306b\u518d\u751f\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u308b\u524d\u306b\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u671f\u9650\u5185\u306a\u3089\u3044\u3064\u66f4\u65b0\u3057\u3066\u3082\u554f\u984c\u3042\u308a\u307e\u305b\u3093\u3002

\u4ee5\u4e0b\u306e\u624b\u9806\u306f\u3001\u5168\u3066\u624b\u4f5c\u696d\u3067\u66f4\u65b0\u3059\u308b\u65b9\u6cd5\u3067\u3059\u3002

KES\u66f4\u65b0\u306f\u3001\u534a\u81ea\u52d5\u66f4\u65b0\u304c\u53ef\u80fd\u306aSJG TOOL\u3092\u63a8\u5968\u3057\u307e\u3059\u3002

\u6ce8\u610f

  • KES\u306e\u6709\u52b9\u671f\u9650\u304c\u5207\u308c\u308b\u3068\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u304c\u51fa\u6765\u306a\u304f\u306a\u308a\u307e\u3059\u306e\u3067\u671f\u9650\u304c\u5207\u308c\u308b\u524d\u306b\u4ee5\u4e0b\u306e\u624b\u9806\u3067\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • 1.35.x\u304b\u3089\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u66f4\u65b0\u306e\u30ec\u30ae\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\u304c\u5909\u66f4\u306b\u306a\u308a\u307e\u3057\u305f\u3002 --\u5fc5\u305a\u81ea\u30d7\u30fc\u30eb\u306e\u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7+1 \u3067\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 --\u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u306b\u307e\u3060\u81ea\u30d7\u30fc\u30eb\u304c\u751f\u6210\u3057\u305f\u30d6\u30ed\u30c3\u30af\u304c\u306a\u3044\u5834\u5408\u306f\u6bce\u56de0\u3067\u66f4\u65b0\u3057\u307e\u3059\u3002

\u25a0KES\u66f4\u65b0\u306e\u6d41\u308c 0.BP\uff1aKES\u66f4\u65b0\u30bf\u30a4\u30df\u30f3\u30b0\u3092\u78ba\u8a8d\u3059\u308b 1.BP\uff1a\u65b0\u3057\u3044KES\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\u3059\u308b 2.BP\uff1aKES\u30d5\u30a1\u30a4\u30eb(kes.skey/kes.vkey)\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc\u3059\u308b 3.BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067kes.vkey\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b 4.BP:\u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u3092\u7b97\u51fa\u3059\u308b\u3002 5.\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7: node.counter\u3092\u751f\u6210\u3059\u308b 6.BP\uff1a\u73fe\u5728\u306eKesPeriod\u3092\u7b97\u51fa\u3059\u308b 7.\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\uff1anode.cert\u3092\u751f\u6210\u3059\u308b (1\u3067\u7b97\u51fa\u3057\u305fKesPeriod\u3092\u4f7f\u3046\u3053\u3068) 8.\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\uff1anode.cert\u30d5\u30a1\u30a4\u30eb\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc\u3059\u308b 9.BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067node.cert\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b 10.BP\uff1a\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b

"},{"location":"operation/kes-update/#0kes","title":"0.KES\u66f4\u65b0\u30bf\u30a4\u30df\u30f3\u30b0\u30c1\u30a7\u30c3\u30af","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
slotNumInt=`curl -s http://localhost:12798/metrics | grep cardano_node_metrics_slotNum_int | awk '{ print $2 }'`\necho \"scale=6; ${slotNumInt} / 129600\" | bc | awk '{printf \"%.5f\\n\", $0}'\n

\u623b\u308a\u5024\u306e\u5c0f\u6570\u70b9\u4ee5\u4e0b\u304c.99800\u4ed8\u8fd1\u306e\u5834\u5408\u3001startKesPeriod\u306e\u5207\u308a\u66ff\u308f\u308a\u304c\u8fd1\u3044\u305f\u3081\u3001\u5207\u308a\u66ff\u308f\u3063\u3066\u304b\u3089\u4ee5\u4e0b\u306e\u4f5c\u696d\u3092\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/kes-update/#1kes","title":"1.KES\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210","text":"

\u65e2\u5b58\u30d5\u30a1\u30a4\u30eb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cp $NODE_HOME/kes.vkey $NODE_HOME/kes-bk.vkey\ncp $NODE_HOME/kes.skey $NODE_HOME/kes-bk.skey\ncp $NODE_HOME/node.cert $NODE_HOME/node-bk.cert\n

KES\u30d5\u30a1\u30a4\u30eb\u65b0\u898f\u4f5c\u6210

cardano-cli node key-gen-KES \\\n    --verification-key-file $NODE_HOME/kes.vkey \\\n    --signing-key-file $NODE_HOME/kes.skey\n

"},{"location":"operation/kes-update/#2kesag","title":"2.KES\u30d5\u30a1\u30a4\u30eb\u3092AG\u306b\u30b3\u30d4\u30fc","text":"

KES\u30d5\u30a1\u30a4\u30eb(kes.skey/kes.vkey)\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc\u3059\u308b

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306b\u3042\u308bkes.skey/kes.vkey\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|kes.skey / kes.vkey| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

"},{"location":"operation/kes-update/#3","title":"3.\u30cf\u30c3\u30b7\u30e5\u5024\u78ba\u8a8d","text":"

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067kes.vkey\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nsha256sum kes.vkey\n
\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nsha256sum kes.vkey\n

\u78ba\u8a8d

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u8868\u793a\u3055\u308c\u305f\u623b\u308a\u5024\u3092\u6bd4\u8f03\u3057\u3066\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070OK

"},{"location":"operation/kes-update/#4","title":"4.\u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u30ab\u30a6\u30f3\u30bf\u30fc\u53d6\u5f97","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
kesperiodinfo=$(cardano-cli query kes-period-info $NODE_NETWORK --op-cert-file $NODE_HOME/node.cert --out-file kesperiod.json)\nlastBlockCnt=`cat kesperiod.json | jq -r '.qKesNodeStateOperationalCertificateNumber'`\n\nif expr \"$lastBlockCnt\" : \"[0-9]*$\" >&/dev/null; then\necho '----------------------------------------------'\necho \u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u306f: $lastBlockCnt \u3067\u3059\u3002\necho \u66f4\u65b0\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u306f $(($lastBlockCnt+1)) \u3067\u3059\u3002\necho '---------------------------------------------'\nelse\necho '----------------------------'\necho \u307e\u3060\u30d6\u30ed\u30c3\u30af\u3092\u751f\u6210\u3057\u3066\u3044\u307e\u305b\u3093\u3002\necho \u66f4\u65b0\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u306f: \"0\" \u3067\u3059\u3002\necho '----------------------------'\nfi\nrm kesperiod.json\n

\u2191\u3053\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3057\u3066\u30b3\u30de\u30f3\u30c9\u306b\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044

"},{"location":"operation/kes-update/#5","title":"5.\u30ab\u30a6\u30f3\u30bf\u30fc\u30d5\u30a1\u30a4\u30eb\u751f\u6210","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nread -p \"BP\u3067\u7b97\u51fa\u3057\u305f\u66f4\u65b0\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044:\" cnt_No\n

\u2191\u3053\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3057\u3066\u30b3\u30de\u30f3\u30c9\u306b\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 \u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u5f8c\u306b\u3001\u6570\u5b57\u5165\u529b\u30e2\u30fc\u30c9\u306b\u306a\u308a\u307e\u3059\u306e\u3067 \u9805\u76ee5\u3067\u78ba\u8a8d\u3057\u305f\u3001\u66f4\u65b0\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u3092\u5165\u529b\u3057\u307e\u3059

chmod u+rwx $HOME/cold-keys\ncardano-cli node new-counter \\\n  --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n  --counter-value $cnt_No \\\n  --operational-certificate-issue-counter-file $HOME/cold-keys/node.counter\n

\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u304c\u6b63\u3057\u304f\u751f\u6210\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

cardano-cli text-view decode-cbor \\\n --in-file  $HOME/cold-keys/node.counter \\\n  | grep int | head -1 | cut -d\"(\" -f2 | cut -d\")\" -f1\n

\u4e0a\u8a18\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u306e\u623b\u308a\u5024\u304c\u300c\u5165\u529b\u3057\u305f\u66f4\u65b0\u30ab\u30a6\u30f3\u30bf\u30fc\u756a\u53f7\u300d\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

"},{"location":"operation/kes-update/#6bpkesperiod","title":"6.BP\u3067\u73fe\u5728\u306eKesPeriod\u7b97\u51fa","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nslotNo=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\nslotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')\nkesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))\nstartKesPeriod=${kesPeriod}\necho startKesPeriod: ${startKesPeriod}\n
"},{"location":"operation/kes-update/#7nodecert","title":"7.node.cert\u751f\u6210","text":"

\u6b21\u306e\u30b3\u30de\u30f3\u30c9\u3067\u3001\u65b0\u3057\u3044 node.cert\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nread -p \"BP\u3067\u7b97\u51fa\u3057\u305fstartKesPeriod\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044:\" kes\n

\u2191\u3053\u306e\u307e\u307e\u30b3\u30d4\u30fc\u3057\u3066\u30b3\u30de\u30f3\u30c9\u306b\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 \u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u5f8c\u306b\u3001\u6570\u5b57\u5165\u529b\u30e2\u30fc\u30c9\u306b\u306a\u308a\u307e\u3059\u306e\u3067 \u305d\u3053\u30671\u3067\u7b97\u51fa\u3057\u305fstartKesPeriod\u306e\u6570\u5b57\u3092\u5165\u529b\u3057\u307e\u3059

echo \"\u5165\u529b\u3057\u305f\u6570\u5b57\u306f$kes\u3067\u3059\"\n

\u5165\u529b\u3057\u305f\u6570\u5b57\u304c\u623b\u308a\u5024\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u304b\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044

chmod u+rwx $HOME/cold-keys\ncardano-cli node issue-op-cert \\\n    --kes-verification-key-file $NODE_HOME/kes.vkey \\\n    --cold-signing-key-file $HOME/cold-keys/node.skey \\\n    --operational-certificate-issue-counter $HOME/cold-keys/node.counter \\\n    --kes-period $kes \\\n    --out-file $NODE_HOME/node.cert\nchmod a-rwx $HOME/cold-keys\n

\u30d2\u30f3\u30c8

\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u3078\u306e\u30a2\u30af\u30bb\u30b9\u6a29\u9650\u3092\u5909\u66f4\u3057\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u5411\u4e0a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u3053\u308c\u306b\u3088\u3063\u3066\u8aa4\u524a\u9664\u3001\u8aa4\u3063\u305f\u7de8\u96c6\u306a\u3069\u304b\u3089\u4fdd\u8b77\u3067\u304d\u307e\u3059\u3002

\u30ed\u30c3\u30af\u3059\u308b\u306b\u306f

chmod a-rwx $HOME/cold-keys\n

\u30ed\u30c3\u30af\u3092\u89e3\u9664\u3059\u308b\u306b\u306f

chmod u+rwx $HOME/cold-keys\n

"},{"location":"operation/kes-update/#8nodecertbp","title":"8.node.cert\u3092BP\u3078\u30b3\u30d4\u30fc","text":"

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\uff1anode.cert\u30d5\u30a1\u30a4\u30eb\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3078\u30b3\u30d4\u30fc\u3059\u308b

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306b\u3042\u308bnode.cert\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|node.cert| B[BP];

"},{"location":"operation/kes-update/#9","title":"9.\u30cf\u30c3\u30b7\u30e5\u5024\u78ba\u8a8d","text":"

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067node.cert\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nsha256sum node.cert\n
cd $NODE_HOME\nsha256sum node.cert\n

\u30ce\u30fc\u30c9

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u8868\u793a\u3055\u308c\u305f\u623b\u308a\u5024\u3092\u6bd4\u8f03\u3057\u3066\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070OK

"},{"location":"operation/kes-update/#10","title":"10.\u30ce\u30fc\u30c9\u518d\u8d77\u52d5","text":"

\u3053\u306e\u624b\u9806\u3092\u5b8c\u4e86\u3059\u308b\u306b\u306f\u3001\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3057\u3066\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
sudo systemctl reload-or-restart cardano-node\n

gLiveview\u3067\u30ce\u30fc\u30c9\u540c\u671f\u3092\u78ba\u8a8d\u3059\u308b

glive\n

10\u5206\u4ee5\u4e0a\u7d4c\u904e\u3057\u3066\u3082\u540c\u671f\u3057\u306a\u3044\u5834\u5408\u306f\u3053\u3061\u3089

KES\u66f4\u65b0\u306b\u5931\u6557\u3057\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u3001\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u5fa9\u5143\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30ce\u30fc\u30c9\u505c\u6b62

sudo systemctl stop cardano-node\n
\u30d5\u30a1\u30a4\u30eb\u5fa9\u5143
mv $NODE_HOME/kes-bk.vkey $NODE_HOME/kes.vkey\nmv $NODE_HOME/kes-bk.skey $NODE_HOME/kes.skey\nmv $NODE_HOME/node-bk.cert $NODE_HOME/node.cert\n
\u30ce\u30fc\u30c9\u8d77\u52d5
sudo systemctl start cardano-node\n
\u540c\u671f\u72b6\u6cc1\u78ba\u8a8d
glive\n

"},{"location":"operation/kes-update/#11","title":"11.\u30c1\u30a7\u30c3\u30af\u30d7\u30ed\u30b0\u30e9\u30e0\u5b9f\u884c","text":"

SPO JAPAN GUILD TOOL\u3092\u5b9f\u884c\u3059\u308b

gtool\n

[2] \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af \u3092\u9078\u629e\u3059\u308b

SPO JAPAN GUILD TOOL\u306e\u5c0e\u5165\u306f\u3053\u3061\u3089\u3092\u3054\u53c2\u7167\u304f\u3060\u3055\u3044

"},{"location":"operation/kes-update/#12","title":"12.\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30d5\u30a1\u30a4\u30eb\u524a\u9664","text":"

\u4e0a\u8a18\u3067\u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u306e\u78ba\u8a8d\u304c\u3059\u3079\u3066OK\u3060\u3063\u305f\u5834\u5408\u3001KES\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664\u3057\u3066\u304f\u3060\u3055\u3044

rm $NODE_HOME/kes-bk.vkey\nrm $NODE_HOME/kes-bk.skey\nrm $NODE_HOME/node-bk.cert\n
"},{"location":"operation/mithril-client/","title":"DB\u540c\u671f\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7(Mithril\u30d9\u30fc\u30bf\u7248)","text":"

\u6982\u8981

  • \u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u3067\u306fMithril-Client\u3092\u4f7f\u7528\u3057\u305fcardano-node DB\u540c\u671f\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002
  • \u30ce\u30fc\u30c9\u521d\u56de\u8d77\u52d5\u6642\u306eDB\u540c\u671f\u6642\u9593\u3092\u7d042\u65e5\u304b\u3089\u7d0430\u5206\u4ee5\u5185\u306b\u307e\u3067\u77ed\u7e2e\u3067\u304d\u307e\u3059\u3002
  • Mithril\u30d7\u30ed\u30c8\u30b3\u30eb\u306f\u307e\u3060\u30d9\u30fc\u30bf\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u305f\u3081\u3001\u3054\u81ea\u8eab\u306e\u8cac\u4efb\u3067\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u3053\u306e\u4f5c\u696d\u306f 2.\u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306e2-1\uff5e2-7\u307e\u3067\u5b9f\u65bd\u3057\u3066\u304b\u3089\u884c\u3063\u3066\u4e0b\u3055\u3044\u3002
  • \u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u3068\u30b5\u30fc\u30d0\u30fc\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u7570\u306a\u308b\u5834\u5408\u3001DB\u518d\u69cb\u7bc9\u51e6\u7406\u304c\u5165\u308b\u5834\u5408\u304c\u3042\u308aDB\u540c\u671f\u307e\u3067\u306b\u6570\u6642\u9593\u304b\u304b\u308a\u307e\u3059\u3002
"},{"location":"operation/mithril-client/#1","title":"1.\u4f9d\u5b58\u74b0\u5883\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":""},{"location":"operation/mithril-client/#1-1","title":"1-1. \u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"

\u30ce\u30fc\u30c9\u505c\u6b62

sudo systemctl stop cardano-node\n
\u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8
sudo apt update -y && sudo apt upgrade -y\n
\u4f9d\u5b58\u74b0\u5883\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb
sudo apt install -y libssl-dev build-essential m4 jq\n

"},{"location":"operation/mithril-client/#1-2-rust","title":"1-2. Rust\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u78ba\u8a8d

Rust\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u3001\u3053\u306e\u9805\u76ee\u306f\u5b9f\u65bd\u4e0d\u8981\u3067\u3059\u3002

rustc -V\n

Command 'rustc' not found, but can be installed with:\u306e\u623b\u308a\u5024\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u4f5c\u696d\u3092\u5b9f\u65bd\u3057\u3066\u4e0b\u3055\u3044\u3002

RUST\u74b0\u5883\u3092\u6e96\u5099\u3057\u307e\u3059

mkdir $HOME/.cargo && mkdir $HOME/.cargo/bin\nchown -R $USER $HOME/.cargo\ntouch $HOME/.profile\nchown $USER $HOME/.profile\n

rustup\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n

1) Proceed with installation (default) 1\u3092\u5165\u529b\u3057\u3066Enter

source $HOME/.cargo/env\n
rustup install stable\nrustup default stable\nrustup update\nrustup component add clippy rustfmt\nrustup target add x86_64-unknown-linux-musl\n
"},{"location":"operation/mithril-client/#2mithril-client","title":"2.Mithril-Client\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
cd $HOME/git\ngit clone https://github.com/input-output-hk/mithril.git\n
cd mithril\ngit fetch --all --prune\ngit checkout tags/2347.0\n

\u30d3\u30eb\u30c9

cd mithril-client-cli\nmake build\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

./mithril-client -V\n

mithril-client 0.5.5

\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u3078\u30b3\u30d4\u30fc

sudo mv mithril-client /usr/local/bin/mithril-client\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

mithril-client -V\n

mithril-client 0.5.5

"},{"location":"operation/mithril-client/#3db","title":"3.DB\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7","text":""},{"location":"operation/mithril-client/#3-1","title":"3-1.\u5909\u6570\u30bb\u30c3\u30c8","text":"
export NETWORK=mainnet\nexport AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator\nexport GENESIS_VERIFICATION_KEY=$(wget -q -O - https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/release-mainnet/genesis.vkey)\nexport SNAPSHOT_DIGEST=latest\n
"},{"location":"operation/mithril-client/#3-2dl","title":"3-2.\u6700\u65b0\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8DL","text":"

\u65e2\u5b58DB\u30d5\u30a9\u30eb\u30c0\u524a\u9664

rm -rf $NODE_HOME/db\n

tmux\u4f5c\u696d\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u4f5c\u6210\u3059\u308b

tmux new -s mithril\n

\u6700\u65b0\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u53ca\u3073\u89e3\u51cd

mithril-client snapshot download --download-dir $NODE_HOME latest\n

\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff5e\u89e3\u51cd\u307e\u3067\u81ea\u52d5\u7684\u306b\u884c\u308f\u308c\u307e\u3059\u30021/6\uff5e6/6\u304c\u7d42\u4e86\u3059\u308b\u307e\u3067\u5f85\u3061\u307e\u3057\u3087\u3046

tmux\u4f5c\u696d\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u7d42\u4e86\u3059\u308b

exit\n

\u305d\u306e\u4ed6\u306emithril-client\u30b3\u30de\u30f3\u30c9

Cardano\u30ce\u30fc\u30c9\u3092\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u3067\u304d\u308b\u5229\u7528\u53ef\u80fd\u306a\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u3092\u4e00\u89a7\u8868\u793a

mithril-client snapshot list\n

\u623b\u308a\u5024

+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| Epoch | Immutable | Network | Digest                                                           | Size        | Locations | Created                           |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4822      | mainnet | dfc05780e0aaefc0e0466cbf69f3c82561e99f8b208626b9870a2e69344199dc | 40337208527 |         1 | 2023-09-27 05:21:39.339429454 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4821      | mainnet | bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3 | 40328088621 |         1 | 2023-09-26 23:13:39.908538941 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4820      | mainnet | d993a6267fefa1c34c0f270337dc3fa5324bc399f908e4a38ec80bb3348e8fe1 | 40320340866 |         1 | 2023-09-26 17:31:56.927673920 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4819      | mainnet | f8dd9c7ee08c6dffebe851a19af44bcb82990d4c174dc366dfaa18e40c20b842 | 40316728370 |         1 | 2023-09-26 11:50:50.123658352 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4818      | mainnet | 70c5c6847116d0a4ca93f81ac193db9d2a17084065963ae298646a157825ab7e | 40314024073 |         1 | 2023-09-26 05:44:57.236767751 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4817      | mainnet | 0597ca3e7d699155ce73aaae53805ea32a981ff213f772dd70e9dbead626acf2 | 40299093577 |         1 | 2023-09-25 23:13:32.500760943 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n| 438   | 4816      | mainnet | 074a576bce34006369837899ecdaaac69f18e31dd193aaa5527d32a7c36fb10e | 40285275527 |         1 | 2023-09-25 17:33:02.562751472 UTC |\n+-------+-----------+---------+------------------------------------------------------------------+-------------+-----------+-----------------------------------+\n

\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u8a73\u7d30\u8868\u793a

mithril-client snapshot show (Digest\u30cf\u30c3\u30b7\u30e5\u5024\u6307\u5b9a)\n
\u623b\u308a\u5024
+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Info                  | Value                                                                                                                                                                         |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Epoch                 | 438                                                                                                                                                                           |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Immutable File Number | 4821                                                                                                                                                                          |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Network               | mainnet                                                                                                                                                                       |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Digest                | bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3                                                                                                              |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Size                  | 40328088621                                                                                                                                                                   |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Cardano node version  | 8.1.2                                                                                                                                                                         |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Location 1            | https://storage.googleapis.com/cdn.aggregator.release-mainnet.api.mithril.network/mainnet-e438-i4821.bbe08607a326c1d6e52c43897808b8ca4c02cc0fbb3d0248b341fd7bbc81f2e3.tar.zst |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Created               | 2023-09-26 23:13:39.908538941 UTC                                                                                                                                             |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Compression Algorithm | Zstandard                                                                                                                                                                     |\n+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n

"},{"location":"operation/mithril-client/#4","title":"4.\u30ce\u30fc\u30c9\u8d77\u52d5","text":"
sudo systemctl start cardano-node\n

\u30ce\u30fc\u30c9\u540c\u671f\u78ba\u8a8d

gliveview\u3092\u8d77\u52d5\u3057\u3001\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u3068\u540c\u671f\u3057\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

glive\n

"},{"location":"operation/node-update/","title":"\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30de\u30cb\u30e5\u30a2\u30eb","text":"

\u6982\u8981

\u3053\u306e\u30ac\u30a4\u30c9\u306f \u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f38.7.3\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002\u6700\u7d42\u66f4\u65b0\u65e5\uff1a2024\u5e741\u670826\u65e5

Node CLI GHC Cabal CNCLI 8.7.3 8.17.0.0 8.10.7 3.8.1.0 6.0.1
  • \u3088\u304f\u304a\u8aad\u307f\u306b\u306a\u3063\u3066\u9032\u3081\u3066\u304f\u3060\u3055\u3044
  • \u8907\u6570\u884c\u306e\u30b3\u30fc\u30c9\u3092\u30b3\u30fc\u30c9\u30dc\u30c3\u30af\u30b9\u306e\u30b3\u30d4\u30fc\u30dc\u30bf\u30f3\u3092\u4f7f\u7528\u3057\u3066\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u306b\u8cbc\u308a\u4ed8\u3051\u308b\u5834\u5408\u306f\u3001\u6700\u5f8c\u306e\u884c\u304c\u81ea\u52d5\u5b9f\u884c\u3055\u308c\u306a\u3044\u305f\u3081\u78ba\u8a8d\u306e\u4e0aEnter\u3092\u62bc\u3057\u3066\u30b3\u30fc\u30c9\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u4e3b\u306a\u5909\u66f4\u70b9\u3068\u65b0\u6a5f\u80fd

\u25a0cardano-node v8.7.3

  • 8.1.2\u4ee5\u524d\u304b\u3089\u306e\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u306e\u6f5c\u5728\u7684\u306a\u30d0\u30b0\u304c\u89e3\u6d88\u3055\u308c\u3066\u3044\u307e\u3059\u3002
  • RAM 24GB\u4ee5\u4e0a\u5fc5\u9808

\u25a0\u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u306e\u4f7f\u7528

  • SJG\u3067\u306f\u3053\u308c\u307e\u3067\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3057\u3066\u304d\u307e\u3057\u305f\u304c\u3001\u691c\u8a3c\u4f53\u5236\u304c\u6574\u3063\u305f\u3053\u3068\u3067\u5b89\u5168\u6027\u30fb\u5b89\u5b9a\u6027\u3092\u5341\u5206\u306b\u78ba\u8a8d\u3067\u304d\u308b\u305f\u3081\u30d3\u30eb\u30c9\u6642\u9593\u5de5\u6570\u524a\u6e1b\u3092\u76ee\u7684\u306bIntersectMBO(\u65e7IOG)\u767a\u884c\u306e\u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u3092\u4f7f\u7528\u3057\u305f\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u63a1\u7528\u3092\u63a1\u7528\u3057\u307e\u3059\u3002 \u3053\u308c\u306b\u3088\u308a\u3001\u3053\u308c\u307e\u3067\u7d0430\u5206\u524d\u5f8c\u304b\u304b\u3063\u3066\u3044\u305f\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210\u306e\u30d3\u30eb\u30c9\u6642\u9593\u3092\u7701\u7565\u3067\u304d\u307e\u3059\u3002

\u25a0Mithril\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u306e\u5c0e\u5165

  • Mithril\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u7528\u3044\u3066DB\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u304b\u3089\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u3057\u307e\u3059\u3002 8.1.2\u4ee5\u524d\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304b\u30898.7.3\u3078\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u306fDB\u518d\u69cb\u7bc9\u51e6\u7406\u304c\u5165\u308b\u305f\u3081\u3001\u30ce\u30fc\u30c9\u540c\u671f\u307e\u3067\u306b6\u6642\u9593\uff5e7\u6642\u9593\u304b\u304b\u308a\u307e\u3059\u304c\u3053\u306e\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u3092\u5c0e\u5165\u3059\u308b\u3053\u3068\u3067\u7d0420\u5206\u3067\u540c\u671f\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002

  • \u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u306e\u4f7f\u7528\uff0bMithril\u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u3092\u4f7f\u7528\u3057\u305f\u5834\u5408\u3001\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u5168\u5de5\u7a0b\u6240\u8981\u6642\u9593\u306f1\u30b5\u30fc\u30d0\u30fc\u306b\u3064\u304d\u7d0430\u5206\uff5e40\u5206\u3067\u3059\u3079\u3066\u5b8c\u4e86\u3057\u307e\u3059\u3002

"},{"location":"operation/node-update/#1","title":"1.\u4f9d\u5b58\u74b0\u5883\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":""},{"location":"operation/node-update/#1-1","title":"1-1. \u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"

\u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8

sudo apt update -y && sudo apt upgrade -y\n

"},{"location":"operation/node-update/#1-2-cabalghc","title":"1-2. cabal/GHC\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d","text":"

cabal\u30d1\u30b9\u78ba\u8a8d

which cabal\n

/home/user/.ghcup/bin/cabal \u306a\u3089\u6b63\u5e38

cabal\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

cabal --version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u306a\u3089OK cabal-install version 3.8.1.0 compiled using version 3.8.1.0 of the Cabal library

GHC\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

ghc --version\n

\u73fe\u5728\u306eGHC\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u300c8.10.7\u300d GHC9\u306f\u30d9\u30f3\u30c1\u30de\u30fc\u30af\u30c6\u30b9\u30c8\u304c\u7d42\u308f\u3063\u3066\u306a\u3044\u305f\u3081\u4eca\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u306f\u975e\u63a8\u5968

libsodium\u30b3\u30df\u30c3\u30c8\u78ba\u8a8d

cd $HOME/git/libsodium\ngit branch --contains | grep -m1 HEAD | cut -c 21-28\n

\u623b\u308a\u5024\u304c dbb48cce \u306a\u3089OK

\u5404\u30a2\u30d7\u30ea\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u7570\u306a\u308b\u5834\u5408 \u623b\u308a\u5024\u304c[/home/user/.local/bin/cabal]\u3060\u3063\u305f\u5834\u5408

\u623b\u308a\u5024\u304c[/home/user/.local/bin/cabal]\u3060\u3063\u305f\u5834\u5408\u306e\u307f\u4ee5\u4e0b\u3092\u5b9f\u884c

\u30d1\u30b9\u3092\u8ffd\u52a0\u3059\u308b

echo PATH=$PATH:$HOME/.ghcup/bin >> $HOME/.bashrc\nsource $HOME/.bashrc\n

\u65e7cabal\u30ea\u30cd\u30fc\u30e0

cd $HOME/.local/bin/\nmv cabal cabal_bk\n

cabal 3.6.2.0\u4ee5\u4e0b\u3060\u3063\u305f\u5834\u5408

cabal 3.6.2.0\u4ee5\u4e0b\u3060\u3063\u305f\u5834\u5408\u306e\u307f\u5b9f\u884c cabal\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7

ghcup upgrade\nghcup install cabal 3.8.1.0\nghcup set cabal 3.8.1.0\n
cabal\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d
cabal --version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u306a\u3089OK cabal-install version 3.8.1.0 compiled using version 3.8.1.0 of the Cabal library

GHC 8.10.4\u4ee5\u4e0b\u3060\u3063\u305f\u5834\u5408

GHC 8.10.4\u4ee5\u4e0b\u3060\u3063\u305f\u5834\u5408\u306e\u307f\u5b9f\u884c

ghcup upgrade\nghcup install ghc 8.10.7\nghcup set ghc 8.10.7\n
ghc --version\n

GHC\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u300c8.10.7\u300d\u3067\u3042\u308c\u3070OK

libsodium\u30b3\u30df\u30c3\u30c8\u5024\u304c\u9055\u3046\u5834\u5408
cd ~/git/libsodium\ngit fetch --all --prune\ngit checkout dbb48cc\n./autogen.sh\n./configure\nmake\nmake check\nsudo make install\n

make\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u5f8c\u534a\u306b\u51fa\u73fe\u3059\u308b warning \u306f\u7121\u8996\u3057\u3066\u5927\u4e08\u592b\u3067\u3059\u3002

"},{"location":"operation/node-update/#1-3blst","title":"1-3.blst\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

blst\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

cd $HOME/git\ngit clone https://github.com/supranational/blst\ncd blst\ngit checkout v0.3.10\n./build.sh\n

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210

\u3053\u306e\u30dc\u30c3\u30af\u30b9\u306f\u3059\u3079\u3066\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cat > libblst.pc << EOF\nprefix=/usr/local\nexec_prefix=\\${prefix}\nlibdir=\\${exec_prefix}/lib\nincludedir=\\${prefix}/include\n\nName: libblst\nDescription: Multilingual BLS12-381 signature library\nURL: https://github.com/supranational/blst\nVersion: 0.3.10\nCflags: -I\\${includedir}\nLibs: -L\\${libdir} -lblst\nEOF\n

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u30b3\u30d4\u30fc

\u3053\u306e\u30dc\u30c3\u30af\u30b9\u306f1\u884c\u305a\u3064\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

sudo cp libblst.pc /usr/local/lib/pkgconfig/\nsudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp  /usr/local/include/\nsudo cp libblst.a /usr/local/lib\nsudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}\n
"},{"location":"operation/node-update/#1-4cnclibp","title":"1-4.CNCLI\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d(BP\u306e\u307f)","text":"

CNCLI\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

cncli --version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u306a\u3089OK cncli 6.0.1

cncli v6.0.0\u4ee5\u4e0b\u3060\u3063\u305f\u5834\u5408(\u30af\u30ea\u30c3\u30af\u3057\u3066\u958b\u304f)

CNCLI\u3092\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3059\u308b

rustup update\ncd $HOME/git/cncli\ngit fetch --all --prune\ngit checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)\ncargo install --path . --force\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

cncli --version\n

cncli 6.0.1\u306b\u306a\u3063\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

"},{"location":"operation/node-update/#2","title":"2.\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"

\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5\u306e\u9055\u3044\u306b\u3064\u3044\u3066

  • \u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u30fb\u30fb\u30fbIntersectMBO(\u65e7IOG)\u30ea\u30dd\u30b8\u30c8\u30ea\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3055\u308c\u305f\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u30d3\u30eb\u30c9\u4e0d\u8981\u306e\u305f\u3081\u30d3\u30eb\u30c9\u6642\u9593\u3092\u77ed\u7e2e\u3067\u304d\u307e\u3059\u3002
  • \u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u30fb\u30fb\u30fb\u3054\u81ea\u8eab\u306e\u30b5\u30fc\u30d0\u30fc\u3067\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3057\u3066\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002\u691c\u8a3c\u76ee\u7684\u3084\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3057\u305f\u3044\u5834\u5408\u306b\u5229\u7528\u3067\u304d\u307e\u3059\u3002\u30d3\u30eb\u30c9\u306b30\u5206\u524d\u5f8c\u304b\u304b\u308a\u307e\u3059\u3002

\u3069\u3061\u3089\u3082\u540c\u3058\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3055\u308c\u305f\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u306a\u306e\u3067\u5b89\u5b9a\u6027\u30fb\u5b89\u5168\u9762\u306b\u5dee\u7570\u306f\u3054\u3056\u3044\u307e\u305b\u3093\u3002\u304a\u597d\u307f\u306e\u65b9\u6cd5\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u9802\u3051\u307e\u3059\u3002

\u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3059\u308b\u5834\u5408\u306f\u3053\u3061\u3089

2-1.\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

\u65b0\u3057\u3044TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u958b\u304f

tmux new -s build\n

\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u4f5c\u696d\u4e2d\u306bSSH\u304c\u4e2d\u65ad\u3057\u305f\u5834\u5408\u306f\u3001tmux a -t build\u3067\u518d\u958b\u3067\u304d\u307e\u3059\u3002

\u65e7\u30d3\u30eb\u30c9\u3092\u524a\u9664\u3059\u308b

rm -rf $HOME/git/cardano-node-old/\n

\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

cd $HOME/git\ngit clone https://github.com/IntersectMBO/cardano-node.git cardano-node2\ncd cardano-node2/\n

2-2.\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9

cabal clean\ncabal update\n
git fetch --all --recurse-submodules --tags\ngit checkout tags/8.7.3\ncabal configure --with-compiler=ghc-8.10.7\n
cabal build cardano-node cardano-cli\n

\u30d2\u30f3\u30c8

  • \u30d3\u30eb\u30c9\u5b8c\u4e86\u307e\u3067\u306b\u6570\u5341\u5206\u307b\u3069\u304b\u304b\u308a\u307e\u3059\u3002
  • SSH\u63a5\u7d9a\u304c\u9014\u4e2d\u3067\u5207\u65ad\u3055\u308c\u305f\u5834\u5408\u3001\u518d\u5ea6\u63a5\u7d9a\u3057\u3066tmux a -t build\u3067\u518d\u958b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30d3\u30eb\u30c9\u4e2d\u306b\u30c7\u30bf\u30c3\u30c1(Ctrl+B D)\u3057\u3066\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u51e6\u7406\u3078\u5207\u308a\u66ff\u3048\u3089\u308c\u307e\u3059\u3002

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

$(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name \"cardano-cli\") version  \n$(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name \"cardano-node\") version  \n
\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

\u30d3\u30eb\u30c9\u7528TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u7d42\u4e86\u3059\u308b

exit\n

\u30ce\u30fc\u30c9\u3092\u30b9\u30c8\u30c3\u30d7\u3059\u308b

sudo systemctl stop cardano-node\n

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u30fc\u3078\u30b3\u30d4\u30fc\u3059\u308b

sudo cp $(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name \"cardano-cli\") /usr/local/bin/cardano-cli\n
sudo cp $(find $HOME/git/cardano-node2/dist-newstyle/build -type f -name \"cardano-node\") /usr/local/bin/cardano-node\n

\u30b7\u30b9\u30c6\u30e0\u306b\u53cd\u6620\u3055\u308c\u305f\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli version\ncardano-node version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

"},{"location":"operation/node-update/#2-1","title":"2-1.\u30d0\u30a4\u30ca\u30ea\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9","text":"

\u65e7\u30d0\u30a4\u30ca\u30ea\u3092\u524a\u9664\u3059\u308b

rm -rf $HOME/git/cardano-node-old/\n

\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

mkdir $HOME/git/cardano-node2\ncd $HOME/git/cardano-node2\nwget https://github.com/IntersectMBO/cardano-node/releases/download/8.7.3/cardano-node-8.7.3-linux.tar.gz\n

\u89e3\u51cd\u3059\u308b

tar zxvf cardano-node-8.7.3-linux.tar.gz ./cardano-node ./cardano-cli\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

$(find $HOME/git/cardano-node2 -type f -name \"cardano-cli\") version  \n$(find $HOME/git/cardano-node2 -type f -name \"cardano-node\") version  \n
\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

\u30ce\u30fc\u30c9\u3092\u30b9\u30c8\u30c3\u30d7\u3059\u308b

sudo systemctl stop cardano-node\n

"},{"location":"operation/node-update/#2-2","title":"2-2.\u30d0\u30a4\u30ca\u30ea\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u30fc\u3078\u30b3\u30d4\u30fc\u3059\u308b

sudo cp $(find $HOME/git/cardano-node2 -type f -name \"cardano-cli\") /usr/local/bin/cardano-cli\n
sudo cp $(find $HOME/git/cardano-node2 -type f -name \"cardano-node\") /usr/local/bin/cardano-node\n
"},{"location":"operation/node-update/#2-3","title":"2-3.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u8ffd\u52a0\u3068\u66f4\u65b0","text":"

\u65e2\u5b58\u30d5\u30a1\u30a4\u30eb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7

mkdir $NODE_HOME/backup\ncp $NODE_HOME/${NODE_CONFIG}-config.json $NODE_HOME/backup/${NODE_CONFIG}-config.json\ncp $NODE_HOME/${NODE_CONFIG}-conway-genesis.json $NODE_HOME/backup/${NODE_CONFIG}-conway-genesis.json\\n\n

\u65b0\u30d5\u30a1\u30a4\u30eb\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

cd $NODE_HOME\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/conway-genesis.json -O ${NODE_CONFIG}-conway-genesis.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/config.json -O ${NODE_CONFIG}-config.json\n

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304d\u63db\u3048\u308b

\u904b\u7528\u4e2d\u306eP2P\u5f62\u5f0f\u3092\u8abf\u3079\u308b\u65b9\u6cd5

cat mainnet-topology.json | grep localRoots\n
  • \u623b\u308a\u5024\u304c\u306a\u3044\u5834\u5408\u30fb\u30fb\u30fb\u624b\u52d5P2P\u904b\u7528
  • \"localRoots\": [\u306e\u623b\u308a\u5024\u304c\u3042\u308b\u5834\u5408\u30fb\u30fb\u30fb\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P
\u624b\u52d5P2P\u904b\u7528\u306e\u5834\u5408\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u904b\u7528\u306e\u5834\u5408
sed -i ${NODE_CONFIG}-config.json \\\n    -e '2i \\  \"SnapshotInterval\": 86400,' \\\n    -e 's!\"EnableP2P\": true!\"EnableP2P\": false!' \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e 's!\"rpKeepFilesNum\": 10!\"rpKeepFilesNum\": 30!' \\\n    -e 's!\"rpMaxAgeHours\": 24!\"rpMaxAgeHours\": 48!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n
sed -i ${NODE_CONFIG}-config.json \\\n    -e '2i \\  \"SnapshotInterval\": 86400,' \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e 's!\"rpKeepFilesNum\": 10!\"rpKeepFilesNum\": 30!' \\\n    -e 's!\"rpMaxAgeHours\": 24!\"rpMaxAgeHours\": 48!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n
\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u306e\u5834\u5408\u306f\u3053\u3061\u3089 \u624b\u52d5P2P\u904b\u7528\u306e\u5834\u5408\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u904b\u7528\u306e\u5834\u5408
sed -i ${NODE_CONFIG}-config.json \\\n    -e 's!\"EnableP2P\": true!\"EnableP2P\": false!' \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n
sed -i ${NODE_CONFIG}-config.json \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n
"},{"location":"operation/node-update/#3mithril","title":"3.Mithril\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u8a2d\u5b9a","text":""},{"location":"operation/node-update/#3-1","title":"3-1. \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
cd $HOME/git\nmithril_release=\"$(curl -s https://api.github.com/repos/input-output-hk/mithril/releases/latest | jq -r '.tag_name')\"\nwget https://github.com/input-output-hk/mithril/releases/download/${mithril_release}/mithril-${mithril_release}-linux-x64.tar.gz -O mithril.tar.gz\n

\u8a2d\u5b9a

tar zxvf mithril.tar.gz mithril-client\nsudo cp mithril-client /usr/local/bin/mithril-client\n
\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u8a2d\u5b9a
sudo chmod +x /usr/local/bin/mithril-client\n

DL\u30d5\u30a1\u30a4\u30eb\u524a\u9664

rm mithril.tar.gz mithril-client\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

mithril-client -V\n

mithril-client 0.5.17+254d266

"},{"location":"operation/node-update/#3-2","title":"3-2.\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u5fa9\u5143","text":"

\u4f5c\u696d\u7528TMUX\u8d77\u52d5

tmux new -s mithril\n

\u5909\u6570\u30bb\u30c3\u30c8

export NETWORK=mainnet\nexport AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator\nexport GENESIS_VERIFICATION_KEY=$(wget -q -O - https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/release-mainnet/genesis.vkey)\nexport SNAPSHOT_DIGEST=latest\n

\u65e7db\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3057\u305f\u3044\u65b9\u306f\u3053\u3061\u3089

\u7a7a\u304d\u5bb9\u91cf\u306b\u95a2\u3057\u3066\u306e\u6ce8\u610f\u4e8b\u9805

DB\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3059\u308b\u5834\u5408\u3001\u30b5\u30fc\u30d0\u30fc\u30c7\u30a3\u30b9\u30af\u306e\u7a7a\u304d\u5bb9\u91cf\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002 \u5b89\u5b9a\u7a3c\u50cd\u306e\u305f\u3081\u306b\u306f250GB\u4ee5\u4e0a\u306e\u7a7a\u304d\u5bb9\u91cf\u304c\u5fc5\u8981\u3067\u3059\u3002

df -h /usr | awk '{print $4}'\n
Avail\u304c250GB\u4ee5\u4e0a\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

db\u3092\u30ea\u30cd\u30fc\u30e0\u3059\u308b

mv $NODE_HOME/db/ $NODE_HOME/backup/db8-1-2/\n

\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u5f8c\u3001\u7a3c\u50cd\u306b\u554f\u984c\u304c\u306a\u3044\u3053\u3068\u304c\u78ba\u8a8d\u3067\u304d\u308c\u3070\u524a\u9664\u3059\u308b\u3053\u3068\u3092\u304a\u52e7\u3081\u307e\u3059

rm -rf $NODE_HOME/backup/db8-1-2/\n

\u65e2\u5b58DB\u524a\u9664

rm -rf $NODE_HOME/db\n

\u6700\u65b0\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8DL

mithril-client snapshot download --download-dir $NODE_HOME latest\n

\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\uff5e\u89e3\u51cd\u307e\u3067\u81ea\u52d5\u7684\u306b\u884c\u308f\u308c\u307e\u3059\u30021/5\uff5e5/5\u304c\u7d42\u4e86\u3059\u308b\u307e\u3067\u5f85\u3061\u307e\u3057\u3087\u3046 5/5 - Verifying the snapshotsignature\u2026 Snapshot 'xxxxx' has been unpacked and successfully checked against Mithril multi-signature contained in the certificate. ('xxxxx'\u306f\u4f5c\u696d\u6642\u671f\u306b\u3088\u3063\u3066\u5909\u308f\u308a\u307e\u3059\u3002\u4e0b\u306e\u6587\u5b57\u5217\u306f\u7121\u8996\u3057\u3066\u5927\u4e08\u592b\u3067\u3059)

tmux\u4f5c\u696d\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u7d42\u4e86\u3059\u308b

exit\n

"},{"location":"operation/node-update/#3-3","title":"3-3.\u30b5\u30fc\u30d0\u30fc\u518d\u8d77\u52d5","text":"

\u4f5c\u696d\u30d5\u30a9\u30eb\u30c0\u30ea\u30cd\u30fc\u30e0

\u524d\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u4f7f\u7528\u3057\u3066\u3044\u305f\u30d0\u30a4\u30ca\u30ea\u30d5\u30a9\u30eb\u30c0\u3092\u30ea\u30cd\u30fc\u30e0\u3057\u3001\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3068\u3057\u3066\u4fdd\u6301\u3057\u307e\u3059\u3002\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u69cb\u7bc9\u3057\u305f\u30d5\u30a9\u30eb\u30c0\u3092cardano-node\u3068\u3057\u3066\u4f7f\u7528\u3057\u307e\u3059\u3002

cd $HOME/git\nmv cardano-node/ cardano-node-old/\nmv cardano-node2/ cardano-node/\n

\u30b5\u30fc\u30d0\u30fc\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo reboot\n

SSH\u63a5\u7d9a\u3057\u3066DB\u518d\u69cb\u7bc9\u9032\u6357\u3092\u78ba\u8a8d\u3059\u308b

journalctl --unit=cardano-node --follow\n

\u6570\u5206\u7d4c\u904e\u3057\u3066\u3082Progress: xx.xx%\u304c\u8868\u793a\u3055\u308c\u306a\u3044\u5834\u5408\u3001\u4f55\u304b\u304c\u4e0d\u5099\u3067\u30a8\u30e9\u30fc\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002

"},{"location":"operation/node-update/#4-bp","title":"4. \u30b5\u30fc\u30d3\u30b9\u8d77\u52d5\u78ba\u8a8d(BP\u306e\u307f)","text":"

BP\u30ce\u30fc\u30c9\u304c\u5b8c\u5168\u306b\u540c\u671f\u3057\u305f\u5f8c\u3001\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3057\u8d77\u52d5\u72b6\u614b\u3092\u78ba\u8a8d\u3059\u308b

sudo systemctl restart cnode-cncli-sync.service\n

\u30d2\u30f3\u30c8

\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u3066\u304b\u3089\u3001\u7d0420\u79d2\u5f8c\u306b5\u30d7\u30ed\u30b0\u30e9\u30e0\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u8d77\u52d5\u4e2d\u3067\u3042\u308c\u3070OK\u3067\u3059

tmux ls\n
  • cncli
  • leaderlog
  • validate
  • logmonitor
  • blockcheck(\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u3092\u5c0e\u5165\u3057\u3066\u3044\u308b\u5834\u5408)
tmux a -t cncli\n

\u300c100.00% synced\u300d\u306b\u306a\u3063\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059 100%\u306b\u306a\u3063\u305f\u3089\u3001Ctrl+b\u3092\u62bc\u3057\u305f\u5f8c\u306b d \u3092\u62bc\u3057\u5143\u306e\u753b\u9762\u306b\u623b\u308a\u307e\u3059 (\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5b9f\u884c\u306b\u5207\u308a\u66ff\u3048)

Missing eta_v for block xxxxxx \u30a8\u30e9\u30fc\u304c\u51fa\u308b\u5834\u5408\u306e\u5bfe\u51e6\u6cd5

cncli\u3092\u518d\u540c\u671f\u3057\u3066\u304f\u3060\u3055\u3044

rm $NODE_HOME/guild-db/cncli/*\n
sudo systemctl restart cnode-cncli-sync.service\n
tmux a -t cncli\n
100% sync'd\u306b\u306a\u308b\u307e\u3067\u304a\u5f85\u3061\u4e0b\u3055\u3044

"},{"location":"operation/node-update/#5","title":"5. \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"

SFTP\u6a5f\u80fd\u30bd\u30d5\u30c8\u5c0e\u5165

R-login\u306e\u8ee2\u9001\u6a5f\u80fd\u304c\u9045\u3044\u306e\u3067\u3001\u5927\u5bb9\u91cf\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30fb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u5834\u5408\u306f\u3001SFTP\u63a5\u7d9a\u53ef\u80fd\u306a\u30bd\u30d5\u30c8\u3092\u4f7f\u7528\u3059\u308b\u3068\u52b9\u7387\u7684\u3067\u3059\u3002\uff08FileZila\u306a\u3069\uff09 \u30d5\u30a1\u30a4\u30eb\u8ee2\u9001\u306b\u4fbf\u5229\u306aSFTP\u6a5f\u80fd\u30bd\u30d5\u30c8\u306e\u5c0e\u5165\u624b\u9806\u306f\u3053\u3061\u3089

"},{"location":"operation/node-update/#5-1","title":"5-1.\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u30b3\u30d4\u30fc","text":"\u30d3\u30eb\u30c9\u6e08\u307f\u30d0\u30a4\u30ca\u30ea\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u5834\u5408\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3057\u305f\u5834\u5408

\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u3067\u4ee5\u4e0b\u3092\u5b9f\u884c\u3059\u308b

sudo cp $(find $HOME/git/cardano-node -type f -name \"cardano-cli\") ~/cardano-cli\n

\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u3067\u4ee5\u4e0b\u3092\u5b9f\u884c\u3059\u308b

sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name \"cardano-cli\") ~/cardano-cli\n

SFTP\u6a5f\u80fd\u30bd\u30d5\u30c8(Filezilla\u306a\u3069)\u3067\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3057\u3001\u4ee5\u4e0b\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

  • /home/usr/cardano-cli

\u3092\u30ed\u30fc\u30ab\u30eb\u30d1\u30bd\u30b3\u30f3\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059 (\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7Ubuntu\u3068\u306e\u5171\u6709\u30d5\u30a9\u30eb\u30c0)

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u5165\u308c\u308b

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7
  • $HOME/git/cardano-node2/ \u306bcardano-cli\u3092\u5165\u308c\u308b (cardano-node2\u304c\u7121\u3051\u308c\u3070\u4f5c\u6210\u3059\u308b)
"},{"location":"operation/node-update/#5-2","title":"5-2.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3067\u4ee5\u4e0b\u3092\u5b9f\u884c\u3059\u308b

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7

cardano-cli\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u3078\u30b3\u30d4\u30fc\u3059\u308b

sudo cp $(find $HOME/git/cardano-node2 -type f -name \"cardano-cli\") /usr/local/bin/cardano-cli\n

"},{"location":"operation/node-update/#5-3","title":"5-3.\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d","text":"
cardano-cli version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

\u78ba\u8a8d

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u306fcardano-node\u306f\u4f7f\u7528\u3057\u306a\u3044\u305f\u3081\u8ee2\u9001\u3057\u3066\u3082\u3057\u306a\u304f\u3066\u3082OK\u3067\u3059\u3002

"},{"location":"operation/p2p-settings/","title":"\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u8a2d\u5b9a\u30de\u30cb\u30e5\u30a2\u30eb","text":"

\u4e8b\u524d\u5b66\u7fd2\u306e\u30b9\u30b9\u30e1

\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P(\u4ee5\u4e0b\u3001P2P)\u306f\u30ce\u30fc\u30c9\u540c\u58eb\u306e\u63a5\u7d9a\u65b9\u5f0f\u304c\u5927\u304d\u304f\u5909\u66f4\u306b\u306a\u308a\u307e\u3059\u3002 \u5909\u66f4\u70b9\u3092\u307e\u3068\u3081\u305f\u8cc7\u6599\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u306e\u3067\u4e8b\u524d\u5b66\u7fd2\u3092\u30aa\u30b9\u30b9\u30e1\u3057\u307e\u3059\u3002\u8cc7\u6599\u306f\u3053\u3061\u3089

  • P2P\u306f\u30ab\u30eb\u30c0\u30ce\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30c1\u30a7\u30fc\u30f3\u5bc6\u5ea6\u306e\u7dad\u6301\u3068\u5b89\u5168\u6027\u3092\u62c5\u4fdd\u3059\u308b\u305f\u3081\u3001\u5c11\u3057\u305a\u3064\u5207\u308a\u66ff\u3048\u3066\u3044\u304f\u65b9\u91dd\u3068\u306a\u308a\u307e\u3059\u3002\u305d\u306e\u305f\u30812023\u5e744\u67083\u65e5\u6642\u70b9\u3067\u306f\u8907\u6570\u30ea\u30ec\u30fc\u306e\u3046\u3061\u5358\u4e00\u306e\u30ea\u30ec\u30fc\u3067\u5b9f\u884c\u3057\u975eP2P\u30ea\u30ec\u30fc\u3068\u4e00\u7dd2\u306b\u7a3c\u50cd\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
  • BP\u3078\u306e\u9069\u7528\u306f\u975e\u63a8\u5968\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002

\u6ce8\u610f\u4e8b\u9805

  • P2P\u3078\u306e\u5207\u308a\u66ff\u3048\u306f\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u5909\u66f4\u3059\u308b\u305f\u3081\u3001\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3057\u3066\u304b\u3089\u4f5c\u696d\u3057\u307e\u3059\u3002
  • \u4ee5\u4e0b\u306e\u624b\u9806\u306f\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u7528\u3067\u3059\u3002BP\u306b\u306f\u9069\u7528\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
"},{"location":"operation/p2p-settings/#1","title":"1.\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d","text":"
cardano-node version\n

\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3

P2P\u306f1.35.7\u4ee5\u4e0a\u3067\u5229\u7528\u53ef\u80fd\u3067\u3059\u3002 1.35.6\u4ee5\u4e0b\u306e\u5834\u5408\u306f\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30de\u30cb\u30e5\u30a2\u30eb\u306b\u6dfb\u3063\u3066\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u3092\u304a\u9858\u3044\u3057\u307e\u3059\u3002

\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop cardano-node\n

"},{"location":"operation/p2p-settings/#2","title":"2.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u5909\u66f4","text":"

mainnet-config.json\u306bP2P\u30d5\u30e9\u30b0\u3092\u8ffd\u8a18\u3059\u308b

\u30ce\u30fc\u30c98.1.2\u306e\u5834\u5408\u30ce\u30fc\u30c98.7.2\u306e\u5834\u5408
sed -i -e '2i \\  \"EnableP2P\": true,' $NODE_HOME/mainnet-config.json\n
sed -i -e 's!\"EnableP2P\": false!\"EnableP2P\": true!' $NODE_HOME/mainnet-config.json\n

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b

mv $NODE_HOME/mainnet-topology.json $NODE_HOME/mainnet-topology-non2p2.json\n

"},{"location":"operation/p2p-settings/#3","title":"3.\u65b0\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210","text":"

\u5b9f\u884c\u524d\u306b +\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u6ce8\u91c8\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 localRoots\u306b\u306f\u5e38\u306bHot\u63a5\u7d9a\u306b\u3057\u305f\u3044\u63a5\u7d9a\u5148\u3092\u8a18\u5165\u3057\u307e\u3059\u3002

\u5358\u4e00\u63a5\u7d9a\u306e\u5834\u5408\u8907\u6570\u63a5\u7d9a\u306e\u5834\u5408(IP\u6307\u5b9a)\u8907\u6570\u63a5\u7d9a\u306e\u5834\u5408(DNS\u6307\u5b9a)
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF\n{\n\"localRoots\": [\n    { \"accessPoints\": [\n        {\n        \"address\": \"xxx.xxx.xxx.xx\", #(1)!\n        \"port\": yyyy #(2)!\n        }\n        ],\n        \"advertise\": false,\n        \"valency\": 1\n    }\n],\n\"publicRoots\": [\n  { \"accessPoints\": [\n    {\n      \"address\": \"backbone.cardano-mainnet.iohk.io\",\n      \"port\": 3001\n    },\n    {\n      \"address\": \"backbone.cardano.iog.io\",\n      \"port\": 3001\n    },\n    {\n      \"address\": \"backbone.mainnet.emurgornd.com\",\n      \"port\": 3001\n    }\n    ],\n    \"advertise\": false\n    }\n],\n\"useLedgerAfterSlot\": 87200000\n}\nEOF\n
  1. BP\u306eIP\u307e\u305f\u306fDNS\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  2. BP\u306e\u30dd\u30fc\u30c8\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF\n{\n\"localRoots\": [\n    { \"accessPoints\": [\n        {\n        \"address\": \"xx.xxx.xx.xxx\", #(1)!\n        \"port\": yyyy #(2)!\n        },\n        {\n        \"address\": \"bb.bbb.bb.bbb\", #(3)!\n        \"port\": aaaa #(4)!\n        }\n        ],\n        \"advertise\": false,\n        \"valency\": 2\n    }\n],\n\"publicRoots\": [\n    { \"accessPoints\": [\n        {\n        \"address\": \"backbone.cardano-mainnet.iohk.io\",\n        \"port\": 3001\n        },\n        {\n        \"address\": \"backbone.cardano.iog.io\",\n        \"port\": 3001\n        },\n        {\n        \"address\": \"backbone.mainnet.emurgornd.com\",\n        \"port\": 3001\n        }\n    ],\n    \"advertise\": false\n    }\n],\n\"useLedgerAfterSlot\": 110332824\n}\nEOF\n
  1. BP1\u306eIP\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  2. BP1\u306e\u30dd\u30fc\u30c8\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  3. BP2\u307e\u305f\u306f\u4ed6\u30ea\u30ec\u30fc\u306eIP\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  4. BP2\u307e\u305f\u306f\u4ed6\u30ea\u30ec\u30fc\u306e\u30dd\u30fc\u30c8\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF\n{\n\"localRoots\": [\n    { \"accessPoints\": [\n        {\n        \"address\": \"xxx1.xxx.com\", #(1)!\n        \"port\": yyyy #(2)!\n        }\n        ],\n        \"advertise\": false,\n        \"valency\": 1\n    },\n    { \"accessPoints\": [\n        {\n        \"address\": \"bbb2.ccc.com\", #(3)!\n        \"port\": aaaa #(4)!\n        }\n        ],\n        \"advertise\": false,\n        \"valency\": 1\n    }\n],\n\"publicRoots\": [\n    { \"accessPoints\": [\n    {\n        \"address\": \"relays-new.cardano-mainnet.iohk.io\",\n        \"port\": 3001\n    }\n    ],\n    \"advertise\": false\n    }\n],\n\"useLedgerAfterSlot\": 110332824\n}\nEOF\n
  1. BP1\u306eDNS\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  2. BP1\u306e\u30dd\u30fc\u30c8\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  3. BP2\u307e\u305f\u306f\u4ed6\u30ea\u30ec\u30fc\u306eDNS\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  4. BP2\u307e\u305f\u306f\u4ed6\u30ea\u30ec\u30fc\u306e\u30dd\u30fc\u30c8\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044

\u65b0\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u9805\u76ee\u89e3\u8aac

\u9805\u76ee \u8aac\u660e localRoots \u5e38\u306bHot\u306b\u3057\u305f\u3044\u63a5\u7d9a\u5148\u3092\u8a18\u5165 accessPoints \u63a5\u7d9a\u5148\u30b0\u30eb\u30fc\u30d7 advertise PeerSharing\u5b9f\u88c5\u5f8c\u306b\u4f7f\u7528\u3059\u308b\u30d5\u30e9\u30b0(\u4eca\u306ffalse) valency \u63a5\u7d9a\u6570(\u63a5\u7d9a\u5148\u30b0\u30eb\u30fc\u30d7\u5185\u306b\u8a18\u8f09\u3057\u305f\u6570\u3068\u4e00\u81f4\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059) publicRoots \u30d6\u30fc\u30c8\u30b9\u30c8\u30e9\u30c3\u30d7\u7528\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u63a5\u7d9a\u5148 seLedgerAfterSlot \u521d\u671f\u540c\u671f\u306e\u969b\u306b\u53f0\u5e33Peer\u691c\u7d22\u3092\u6709\u52b9\u306b\u3059\u308b\u30b9\u30ed\u30c3\u30c8\u756a\u53f7

mainnet-topology.json\u69cb\u6587\u30c1\u30a7\u30c3\u30af

cat $NODE_HOME/mainnet-topology.json | jq .\n

\u6b63\u5e38\u30a8\u30e9\u30fc

mainnet-topology.json\u306e\u4e2d\u8eab\u304c\u305d\u306e\u307e\u307e\u8868\u793a\u3055\u308c\u307e\u3059

\u4ee5\u4e0b\u306e\u30a8\u30e9\u30fc\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002mainnet-topology.json\u3092\u958b\u3044\u3066\u9069\u5207\u306a\u8a18\u53f7{} [] , \u306e\u6709\u7121\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002

parse error: Expected another key-value pair at line x, column x\n

"},{"location":"operation/p2p-settings/#4","title":"4. \u30ce\u30fc\u30c9\u8d77\u52d5","text":"
sudo systemctl start cardano-node\n
"},{"location":"operation/p2p-settings/#5","title":"5.\u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u4fee\u6b63","text":"

relay-topology_pull.sh\u5185\u5bb9\u5909\u66f4 mainnet-topology.json\u4e0a\u66f8\u304d\u9632\u6b62\u306e\u305f\u3081\u3001\u751f\u6210\u30d5\u30a1\u30a4\u30eb\u3092\u30ea\u30cd\u30fc\u30e0\u3057\u307e\u3059\u3002

sed -i $NODE_HOME/relay-topology_pull.sh \\\n    -e \"s/mainnet-topology.json/mainnet-topology-nonp2p.json/g\"\n

P2P\u30e2\u30fc\u30c9\u306b\u3057\u305f\u30ea\u30ec\u30fc\u3067\u306f\u5b9a\u671f\u7684\u306brelay-topology_pull.sh\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002

\u751f\u5b58\u901a\u77e5\u306b\u3064\u3044\u3066

Cron\u306b\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u30b5\u30fc\u30d0\u30fc\u3078\u306e\u751f\u5b58\u901a\u77e5\u306f\u3057\u3070\u3089\u304f\u7d99\u7d9a\u3057\u3066\u4e0b\u3055\u3044\u3002 \u5ec3\u6b62\u6642\u671f\u306f\u5225\u9014\u3054\u6848\u5185\u81f4\u3057\u307e\u3059\u3002

"},{"location":"operation/p2p-settings/#6","title":"6.\u30c8\u30dd\u30ed\u30b8\u30fc\u30ea\u30ed\u30fc\u30c9\u8a2d\u5b9a","text":"

\u30ea\u30ed\u30fc\u30c9\u7528\u74b0\u5883\u5909\u6570\u3092\u8ffd\u52a0

echo alias cnreload='\"kill -SIGHUP $(pidof cardano-node)\"' >> $HOME/.bashrc\nsource $HOME/.bashrc\n

P2P\u6709\u52b9\u6642\u306e\u65b0\u6a5f\u80fd

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u6642\u306e\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u304c\u4e0d\u8981\u306b\u306a\u308a\u307e\u3057\u305f\uff01\uff01 mainnet-topology.json\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u305f\u5f8c\u3001cnreload\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067 \u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b\u3053\u3068\u306a\u304f\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u518d\u8aad\u307f\u8fbc\u307f\u304c\u53ef\u80fd\u3067\u3059\u3002

"},{"location":"operation/p2p-settings/#7-gliveview","title":"7. gLiveView\u306e\u898b\u65b9","text":"

P2P\u5c02\u7528\u9805\u76ee\u3092\u89e3\u8aac\u3057\u307e\u3059\u3002

Cold Warm Hot\u304c\u9069\u6b63\u5024\u306b\u843d\u3061\u7740\u304f\u307e\u3067\u306b\u6570\u6642\u9593\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002

\u9805\u76ee \u8aac\u660e \u5099\u8003 Incoming \u4ed6\u30ea\u30ec\u30fc\u304b\u3089\u306e\u63a5\u7d9a\u6570 Out\u3067\u53cc\u65b9\u5411\u306e\u5834\u5408In\u3082\u30ab\u30a6\u30f3\u30c8\u3055\u308c\u308b Outgoing \u81ea\u30ea\u30ec\u30fc\u304b\u3089\u306e\u63a5\u7d9a\u6570 Warm + Hot \u306e\u5408\u8a08\u5024 Cold Peers \u691c\u77e5\u6e08\u307f\u306e\u4e88\u5099Peer(\u672a\u63a5\u7d9a\u30d4\u30a2\u3000\u30d0\u30c3\u30af\u30a2\u30c3\u30d7) \u30c7\u30d5\u30a9\u30eb\u30c8 50 Warm Peers \u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u63a5\u7d9aPeer\u6570(\u30df\u30cb\u30d7\u30ed\u30c8\u30b3\u30eb\u672a\u4f7f\u7528) \u30c7\u30d5\u30a9\u30eb\u30c830 Hot Peers \u30a2\u30af\u30c6\u30a3\u30d6\u63a5\u7d9a\u306ePeer\u6570(\u30df\u30cb\u30d7\u30ed\u30c8\u30b3\u30eb\u4f7f\u7528) 20\u304c\u6700\u9069\u5024 Uni-Dir \u63a5\u7d9a\u5148/\u63a5\u7d9a\u5143\u3044\u305a\u308c\u304b\u304c\u975eP2P (UniDirectional \u5358\u4e00\u65b9\u5411\u63a5\u7d9a ) Bi-Dir \u63a5\u7d9a\u5148/\u63a5\u7d9a\u5143\u304c\u4e21\u7aef\u3067P2P (Bidirectional \u53cc\u65b9\u5411\u63a5\u7d9a) Duplex \u63a5\u7d9a\u5148/\u63a5\u7d9a\u5143\u304cP2P\u3067\u4e21\u7aef\u3067Hot\u3067\u63a5\u7d9a\u72b6\u614b \u76f8\u4e92\u30a2\u30af\u30c6\u30a3\u30d6\u63a5\u7d9a

Peer\u30a2\u30ca\u30ea\u30c6\u30a3\u30af\u30b9\u306b\u3064\u3044\u3066

Peer\u30a2\u30ca\u30ea\u30c6\u30a3\u30af\u30b9\u306e\u5909\u66f4\u70b9

P2P\u30e2\u30fc\u30c9\u306eOutgoing\u306f\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u3092\u4f7f\u7528\u3059\u308b\u305f\u3081\u3001\u30b3\u30de\u30f3\u30c9\u306e\u7279\u6027\u4e0a\u5168\u3066In\u3067\u30ab\u30a6\u30f3\u30c8\u3055\u308c\u307e\u3059\u3002

\u30ce\u30fc\u30c9\u9593\u306e\u8ddd\u96e2\u306b\u3064\u3044\u3066

P2P\u30e2\u30fc\u30c9\u3067\u6700\u9069\u306a\u63a5\u7d9a\u5148\u3068\u63a5\u7d9a\u3059\u308b\u3068\u306f\u8a00\u3048\u3001\u8ddd\u96e2\u306e\u591a\u69d8\u6027(\u8fd1\u30fb\u4e2d\u30fb\u9060\u8ddd\u96e2)\u306f\u7dad\u6301\u3055\u308c\u307e\u3059\u3002 \u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u306e\u5909\u66f4\u3001\u63a5\u7d9a\u6027\u306e\u90e8\u5206\u7684\u306a\u55aa\u5931\u3001\u7269\u7406\u7684\u306a\u30a4\u30f3\u30d5\u30e9\u969c\u5bb3\u306b\u3088\u308a\u63a5\u7d9a\u304c\u5931\u308f\u308c\u305f\u5834\u5408\u3001\u30ce\u30fc\u30c9\u306e\u4e00\u90e8\u307e\u305f\u306f\u5168\u90e8\u304c\u4ed6\u306e\u3088\u308a\u9577\u3044\u8ddd\u96e2\u306e\u30a6\u30a9\u30fc\u30e0\u63a5\u7d9a\u3092\u7dad\u6301\u3057\u3066\u3044\u308c\u3070\u3001\u305d\u308c\u3089\u3092\u30db\u30c3\u30c8\u63a5\u7d9a\u306b\u8fc5\u901f\u306b\u6607\u683c\u3055\u305b\u3066\u56de\u5fa9\u3067\u304d\u307e\u3059\u3002

"},{"location":"operation/pool-retire/","title":"\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u5ec3\u6b62\u3059\u308b","text":"

\u30d7\u30fc\u30eb\u5ec3\u6b62\u306e\u6d41\u308c

graph LR\n    A[1-\u30ea\u30bf\u30a4\u30a2\u51e6\u7406] -->|500ADA\u8fd4\u9084| B(2-\u767b\u9332\u6599\u8fd4\u9084\u78ba\u8a8d);\n    C[3-stake.addr\u304b\u3089\u5168\u984d\u5f15\u51fa\u51e6\u7406] -->|\u5168\u984d| D(3-payment.addr\u7740\u91d1\u78ba\u8a8d);\n    E[4-stake.addr\u89e3\u9664\u51e6\u7406] -->|2ADA\u8fd4\u9084| F(4-payment.addr\u78ba\u8a8d);\n    G[5-payment.addr\u5168\u984d\u5f15\u51fa\u51e6\u7406] -->|\u5168\u984d| H(5-\u4efb\u610f\u306e\u30a2\u30c9\u30ec\u30b9\u78ba\u8a8d);\n    click A \"./#1\"\n    click B \"./#_3\"\n    click C \"../withdrawal/#2-1-paymentaddr\"\n    click E \"./#2\"\n    click G \"./#3paymentaddr\"
"},{"location":"operation/pool-retire/#1","title":"1.\u30ea\u30bf\u30a4\u30a2\u51e6\u7406","text":"

\u73fe\u5728\u306e\u30a8\u30dd\u30c3\u30af\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
startTimeGenesis=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .systemStart)\nstartTimeSec=$(date --date=${startTimeGenesis} +%s)\ncurrentTimeSec=$(date -u +%s)\nepochLength=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .epochLength)\nepoch=$(( (${currentTimeSec}-${startTimeSec}) / ${epochLength} ))\necho current epoch: ${epoch}\n

\u30d7\u30fc\u30eb\u304c\u6700\u3082\u65e9\u304f\u5f15\u9000\u3067\u304d\u308b\u30a8\u30dd\u30c3\u30af\u3068\u6700\u3082\u9045\u3044\u5f15\u9000\u30a8\u30dd\u30c3\u30af\u3092\u898b\u3064\u3051\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
poolRetireMaxEpoch=$(cat $NODE_HOME/params.json | jq -r '.poolRetireMaxEpoch')\necho poolRetireMaxEpoch: ${poolRetireMaxEpoch}\n\nminRetirementEpoch=$(( ${epoch} + 1 ))\nmaxRetirementEpoch=$(( ${epoch} + ${poolRetireMaxEpoch} ))\n\necho \u30ea\u30bf\u30a4\u30a2\u53ef\u80fd\u6700\u77ed\u30a8\u30dd\u30c3\u30af: ${minRetirementEpoch}\necho \u30ea\u30bf\u30a4\u30a2\u53ef\u80fd\u6700\u9577\u30a8\u30dd\u30c3\u30af: ${maxRetirementEpoch}\n

\u30ea\u30bf\u30a4\u30a2\u306e\u30bf\u30a4\u30df\u30f3\u30b0\u306b\u3064\u3044\u3066

\u4f8b: \u30a8\u30dd\u30c3\u30af320\u3067eMax18\u306e\u5834\u5408,

  • \u6700\u3082\u65e9\u3044\u30dd\u30c3\u30af\u306f 321 ( \u73fe\u5728\u306e\u30a8\u30dd\u30c3\u30af + 1)
  • \u6700\u3082\u9045\u3044\u30a8\u30dd\u30c3\u30af\u306f 338 ( eMax + \u73fe\u5728\u306e\u30a8\u30dd\u30c3\u30af)

  • \u30d7\u30fc\u30eb\u306f\u30ea\u30bf\u30a4\u30a2\u6307\u5b9a\u30a8\u30dd\u30c3\u30af\u958b\u59cb\u6642\u306b\u30ea\u30bf\u30a4\u30a2\u51e6\u7406\u3055\u308c\u307e\u3059\u3002

  • \u3082\u3057\u5fc3\u5909\u308f\u308a\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u30a8\u30dd\u30c3\u30af\u6307\u5b9a\u30a8\u30dd\u30c3\u30af\u958b\u59cb\u524d\u306b\u65b0\u3057\u3044\u767b\u9332\u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u30ea\u30bf\u30a4\u30a2\u624b\u7d9a\u304d\u3092\u7121\u52b9\u306b\u3067\u304d\u307e\u3059\u3002
  • \u30d7\u30fc\u30eb\u767b\u9332\u6599500ADA\u306f\u30ea\u30bf\u30a4\u30a2\u51e6\u7406\u30a8\u30dd\u30c3\u30af\u958b\u59cb\u6642\u306bstake.addr\u306b\u5165\u91d1\u3055\u308c\u307e\u3059\u3002

\u767b\u9332\u89e3\u9664\u8a3c\u660e\u66f8 pool.dereg\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002 \u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u5185\u306e --epoch *** \u306b\u30ea\u30bf\u30a4\u30a2\u3057\u305f\u3044\u30a8\u30dd\u30c3\u30af\u3092\u8a18\u5165\u3057\u307e\u3059

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nchmod u+rwx $HOME/cold-keys\ncardano-cli stake-pool deregistration-certificate \\\n--cold-verification-key-file $HOME/cold-keys/node.vkey \\\n--epoch *** \\\n--out-file pool.dereg\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306epool.dereg\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|pool.dereg| B[BP];

payment.addr\u306e\u6b8b\u9ad8\u3092\u53c2\u7167\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

\u73fe\u5728\u306e\u30b9\u30ed\u30c3\u30c8\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

build-raw transaction\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${total_balance} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --certificate-file pool.dereg \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u6599\u91d1\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 2 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u5909\u66f4\u51fa\u529b\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}))\necho txOut: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --certificate-file pool.dereg \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3059\u308b

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file $HOME/cold-keys/node.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u3092\u30ed\u30c3\u30af\u3059\u308b

chmod a-rwx $HOME/cold-keys\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092 \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n
"},{"location":"operation/pool-retire/#_2","title":"\u30ea\u30bf\u30a4\u30a2\u78ba\u8a8d","text":"
  • KOIOS API\u3092\u4f7f\u7528\u3057\u3066\u30ea\u30bf\u30a4\u30a2\u51e6\u7406\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002

pool.id-bech32\u306e\u4f5c\u6210

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format bech32 > pool.id-bech32\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306epool.id-bech32\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|pool.id-bech32| B[BP];

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurl -s \"https://api.koios.rest/api/v0/pool_updates?_pool_bech32=$(cat pool.id-bech32)\" | jq '.[0].pool_status,.[0].retiring_epoch'\n
#\u623b\u308a\u5024\u30b5\u30f3\u30d7\u30eb\n\"retired\" # \"retiring\"\u3067\u30ea\u30bf\u30a4\u30a2\u51e6\u7406\u5f85\u3061 \"retired\"\u3067\u30ea\u30bf\u30a4\u30a2\u6e08\u307f \n309 #\u30ea\u30bf\u30a4\u30a2\u30a8\u30dd\u30c3\u30af\n
"},{"location":"operation/pool-retire/#2","title":"2.\u767b\u9332\u6599\u8fd4\u9084\u78ba\u8a8d","text":"

\u6ce8\u610f

\u4ee5\u964d\u306e\u51e6\u7406\u306f\u3001\u30d7\u30fc\u30eb\u306e\u30ea\u30bf\u30a4\u30a2\u51e6\u7406\u304c\u5b8c\u4e86\u3057\u3066\u304b\u3089\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306estake.addr \u3092 BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|stake.addr| B[BP];
\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli query stake-address-info \\\n--address $(cat stake.addr) \\\n$NODE_NETWORK\n

\u623b\u308a\u5024\u78ba\u8a8d

rewardAccountBalance: \u306e\u5024\u3092\u78ba\u8a8d\u3059\u308b

"},{"location":"operation/pool-retire/#3stakeaddr","title":"3.stake.addr\u304b\u3089\u5f15\u304d\u51fa\u3057","text":"

stake.addr\u304b\u3089payment.addr\u3078\u9001\u91d1\u3059\u308b\u65b9\u6cd5

"},{"location":"operation/pool-retire/#4","title":"4.\u30b9\u30c6\u30fc\u30af\u30ad\u30fc\u89e3\u9664\u624b\u9806","text":"

\u6ce8\u610f

  • \u3053\u306e\u624b\u9806\u3067\u306fstake.addr\u306e\u767b\u9332\u3092\u89e3\u9664\u3057\u30012ADA\u306e\u8fd4\u9084\u624b\u7d9a\u304d\u3092\u884c\u3044\u307e\u3059\u3002
  • \u30d7\u30fc\u30eb\u767b\u9332\u6599(500ADA)\u304c\u8fd4\u9084\u3055\u308c\u308b\u524d\u306b\u4ee5\u4e0b\u306e\u51e6\u7406\u3092\u884c\u3063\u3066\u3057\u307e\u3046\u3068\u3001500ADA\u3092\u53d7\u3051\u53d6\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u305b\u3093\u3002
  • \u4ee5\u4e0b\u306e\u624b\u7d9a\u304d\u306f\u3001\u30d7\u30fc\u30eb\u767b\u9332\u6599\u306e500ADA\u3092\u53d7\u3051\u53d6\u3063\u3066\u304b\u3089\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044

\u30b9\u30c6\u30fc\u30af\u30ad\u30fc\u767b\u9332\u89e3\u9664\u8a3c\u660e\u66f8\u4f5c\u6210

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli stake-address deregistration-certificate \\\n    --stake-verification-key-file stake.vkey \\\n    --out-file stake-dereg.cert\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306estake-dereg.cert \u3092 \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|stake-dereg.cert| B[BP];

\u30b9\u30c6\u30fc\u30af\u30ad\u30fc\u767b\u9332\u6599\u7b97\u51fa

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakeAddressDeposit')\necho keyDeposit: $keyDeposit\n

\u6700\u65b0\u30b9\u30ed\u30c3\u30c8\u7b97\u51fa

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

payment.addr\u6b8b\u9ad8\u3092\u53c2\u7167

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

\u4eee\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --certificate stake-dereg.cert \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u6599\u91d1\u3092\u8a08\u7b97\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 2 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u5909\u66f4\u51fa\u529b\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
txOut=$((total_balance+keyDeposit-fee))\necho Change Output: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --certificate-file stake-dereg.cert \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3059\u308b

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n
"},{"location":"operation/pool-retire/#5paymentaddr","title":"5.payment.addr\u304b\u3089\u5168\u984d\u5f15\u304d\u51fa\u3059\u624b\u9806","text":"

\u307e\u305a\u306f\u3001\u6700\u65b0\u306e\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u3092\u53d6\u5f97\u3057 invalid-hereafter \u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u6b63\u3057\u304f\u8a2d\u5b9a\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

\u9001\u91d1\u5148\u306e\u30a2\u30c9\u30ec\u30b9\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
destinationAddress=\u9001\u91d1\u5148\u30a2\u30c9\u30ec\u30b9\necho destinationAddress: $destinationAddress\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u53c2\u7167\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

build-raw\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out ${destinationAddress}+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u624b\u6570\u6599\u3092\u51fa\u529b\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 1 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u8a08\u7b97\u7d50\u679c\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}))\necho Change Output: ${txOut}\n

\u9001\u91d1\u91d1\u984d\u3092\u78ba\u8a8d\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
amountToSend=$((${txOut}))\necho amountToSend: $amountToSend\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u69cb\u7bc9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out ${destinationAddress}+${amountToSend} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

tx.signed \u3092\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u7f72\u540d\u3055\u308c\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

\u5168\u984d\u51fa\u91d1\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u6d88\u3048\u3066\u3044\u308c\u3070OK\u3067\u3059

                           TxHash                                 TxIx        Lovelace\n----------------------------------------------------------------------------------------\n
"},{"location":"operation/relay-move/","title":"\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u306e\u5f15\u8d8a\u3057\u624b\u9806\uff08\u65e7VPS\u4f1a\u793e\u2192\u65b0VPS\u4f1a\u793e\uff09","text":"

\u524d\u63d0\u6ce8\u610f\u4e8b\u9805

  • \u672c\u307e\u3068\u3081\u306f\u73feVPS\u4f1a\u793e\u2192\u65b0VPS\u4f1a\u793e\u3078\u3068 \u30ea\u30ec\u30fc\u306e\u307f \u3092\u79fb\u884c\u3059\u308b\u307e\u3068\u3081\u3067\u3059\u3002
  • \u5b9f\u969b\u306b\u884c\u3046\u969b\u306b\u306f\u624b\u9806\u3092\u3088\u304f\u8aad\u307f\u306a\u304c\u3089\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u4e88\u5b9a\u307e\u3067\u4f59\u88d5\u304c\u3042\u308b\u6642\u306b\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30ea\u30ec\u30fc1\u53f0\u304b\u3064\u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u306bIP\u30a2\u30c9\u30ec\u30b9\u3067\u767b\u9332\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u65e7\u30ea\u30ec\u30fc\u3068\u65b0\u30ea\u30ec\u30fc\u3092\u4e00\u5b9a\u671f\u9593\u4f75\u7528\u904b\u7528\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
"},{"location":"operation/relay-move/#1","title":"1.\u65b0\u30ea\u30ec\u30fc\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u7559\u610f\u4e8b\u9805

  1. \u30b5\u30fc\u30d0\u72ec\u81ea\u6a5f\u80fd\u306b\u7559\u610f\u3059\u308b
    • \u3055\u304f\u3089\u306e\u30d1\u30b1\u30c3\u30c8\u30d5\u30a3\u30eb\u30bf\u3084\u3001AWS\u306eFW\u8a2d\u5b9a\u306a\u3069\u306e\u30b5\u30fc\u30d0\u30fc\u72ec\u81ea\u306e\u6a5f\u80fd\u306b\u6c17\u3092\u4ed8\u3051\u3066\u304f\u3060\u3055\u3044\u3002
  2. \u65b0\u30ea\u30ec\u30fc\u306e\u30d5\u30a1\u30a4\u30e4\u30fc\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u306f\u3001\u65e7\u30ea\u30ec\u30fc\u3068\u540c\u3058\u8a2d\u5b9a\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  3. \u65e7\u30ea\u30ec\u30fc\u306e\u30e6\u30fc\u30b6\u30fc\u540d\uff08\u4f8b\uff1aubuntu\uff09\u3068\u65b0\u30ea\u30ec\u30fc\u306e\u30e6\u30fc\u30b6\u30fc\u540d\u306f\u5909\u66f4\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
    • \u3082\u3057\u5909\u66f4\u3059\u308b\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u30d5\u30a1\u30a4\u30eb\u5185\u306e\u30d1\u30b9\u540d\u3092\u624b\u52d5\u3067\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002
    • startRelayNode1.sh DIRECTORY=/home/\u30e6\u30fc\u30b6\u30fc\u540d/cnode
    • topologyUpdater.sh CNODE_HOME=/home/\u30e6\u30fc\u30b6\u30fc\u540d/cnode
    • relay-topology_pull.sh curl -4 -s -o /home/\u30e6\u30fc\u30b6\u30fc\u540d/cnode/****
"},{"location":"operation/relay-move/#1-1ubuntu","title":"1-1.Ubuntu\u521d\u671f\u8a2d\u5b9a","text":"

\u65b0\u30b5\u30fc\u30d0\u30fc\u3067Ubuntu\u521d\u671f\u8a2d\u5b9a\u3092\u5b9f\u65bd\u3057\u307e\u3059\u3002

"},{"location":"operation/relay-move/#1-2","title":"1-2.\u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u4f9d\u5b58\u95a2\u4fc2\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb \u301c gLiveView\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u307e\u3067\u5b9f\u65bd\u3057\u307e\u3059\u3002

"},{"location":"operation/relay-move/#2","title":"2.\u65e7\u30ea\u30ec\u30fc\u79fb\u884c\u51e6\u7406","text":"

\u65e7\u30ea\u30ec\u30fc\u30d5\u30a1\u30a4\u30eb\u79fb\u52d5

\u4ee5\u4e0b\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u65e7\u30ea\u30ec\u30fc\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304b\u3089\u65b0\u30ea\u30ec\u30fc\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u65e7\u30ea\u30ec\u30fc] -->|\u30d5\u30a1\u30a4\u30eb/\u30d5\u30a9\u30eb\u30c0| B[\u65b0\u30ea\u30ec\u30fc];
\u30d5\u30a1\u30a4\u30eb\u540d \u7528\u9014 mainnet-topology.json \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb startRelayNode1.sh \u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8 topologyUpdater.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u30b9\u30af\u30ea\u30d7\u30c8 relay-topology_pull.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u751f\u6210\u30b9\u30af\u30ea\u30d7\u30c8 rsyncd.conf RSYNC\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb(\u8a2d\u5b9a\u4e2d\u306e\u5834\u5408) rsync_ed25519.pub RSYNC\u9375\u30d5\u30a1\u30a4\u30eb(\u8a2d\u5b9a\u4e2d\u306e\u5834\u5408)"},{"location":"operation/relay-move/#3","title":"3.\u65b0\u30ea\u30ec\u30fc\u518d\u8a2d\u5b9a","text":"

\u65e7\u30ea\u30ec\u30fc\u3092\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u3067\u904b\u7528\u3057\u3066\u3044\u305f\u5834\u5408

\u65b0\u30ea\u30ec\u30fc\u306emainnet-config.json\u306eP2P\u8a2d\u5b9a\u3092true\u306b\u3059\u308b

\u65b0\u30ea\u30ec\u30fc
sed -i -e 's!\"EnableP2P\": false!\"EnableP2P\": true!' $NODE_HOME/mainnet-config.json\n
"},{"location":"operation/relay-move/#3-1","title":"3-1.\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u5909\u66f4","text":"\u65b0\u30ea\u30ec\u30fc
cd $NODE_HOME\nchmod +x startRelayNode1.sh\nchmod +x topologyUpdater.sh\nchmod +x relay-topology_pull.sh\n

\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl reload-or-restart cardano-node\n
\u30ce\u30fc\u30c9\u30ed\u30b0\u78ba\u8a8d
journalctl --unit=cardano-node --follow\n

DNS\u904b\u7528\u306e\u5834\u5408

  • \u30ea\u30ec\u30fcDNS\u306eA\u30ec\u30b3\u30fc\u30c9\u3092\u65b0\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u306eIP\u30a2\u30c9\u30ec\u30b9\u3078\u5909\u66f4\u3059\u308b
"},{"location":"operation/relay-move/#3-2","title":"3-2. \u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u8a2d\u5b9a","text":"\u65b0\u30ea\u30ec\u30fc
nano $NODE_HOME/topologyUpdater.sh\n

\u65e7\u30ea\u30ec\u30fc\u306eIP\u3068\u30dd\u30fc\u30c8\u3092\u65b0\u30ea\u30ec\u30fc\u306eIP\u3068\u30dd\u30fc\u30c8\u306b\u5909\u66f4\u3059\u308b

  • CNODE_PORT=xxxx\u3000\u3000
  • CNODE_HOSTNAME=\"xxx.xxx.xxx.xxx\"\u3000\u3000

DNS\u904b\u7528\u306e\u5834\u5408

  • (DNS\u904b\u7528\u306e\u5834\u5408\u306f\u5909\u66f4\u4e0d\u8981)

\u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u5b9f\u884c

cd $NODE_HOME\n./topologyUpdater.sh\n
topologyUpdater.sh\u304c\u6b63\u5e38\u306b\u5b9f\u884c\u3055\u308c\u305f\u5834\u5408\u3001\u4ee5\u4e0b\u306e\u5f62\u5f0f\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002

{ \"resultcode\": \"201\", \"datetime\":\"2020-07-28 01:23:45\", \"clientIp\": \"xxx.xxx.xxx.xx\", \"iptype\": 4, \"msg\": \"nice to meet you\" }

"},{"location":"operation/relay-move/#3-3cron","title":"3-3.Cron\u767b\u9332","text":"

1.Cron\u30b8\u30e7\u30d6\u8a2d\u5b9a\u3092\u5b9f\u884c\u3059\u308b

2.Cron\u30b8\u30e7\u30d6\u8a2d\u5b9a\u304b\u30894\u6642\u9593\u5f8c\u306b\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u767b\u9332\u78ba\u8a8d\u3092\u5b9f\u884c\u3059\u308b

3.\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u518d\u4f5c\u6210

\u624b\u52d5P2P\u306e\u5834\u5408\u30c0\u30a4\u30ca\u30df\u30c3\u30afP2P\u306e\u5834\u5408

relay-topology_pull.sh\u3092\u5b9f\u884c\u3057\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u518d\u4f5c\u6210\u3059\u308b\u3002

cd $NODE_HOME\n./relay-topology_pull.sh\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

\u4f55\u3082\u305b\u305a\u3001relay-topology_pull.sh\u3082\u5b9f\u884c\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002

\u65e7\u30ea\u30ec\u30fc\u4f75\u7528\u76ee\u5b89

\u30ea\u30ec\u30fc1\u53f0\u304b\u3064\u30c8\u30dd\u30ed\u30b8\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30bf\u306bIP\u30a2\u30c9\u30ec\u30b9\u3067\u767b\u9332\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u65b0\u30ea\u30ec\u30fc\u306eIncoming\u306e\u6570\u304c\u5b89\u5b9a\u3057\u306610\u4ee5\u4e0a\u306b\u5897\u3048\u308b\u307e\u3067\u65e7\u30ea\u30ec\u30fc\u3068\u65b0\u30ea\u30ec\u30fc\u3092\u4f75\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/relay-move/#4bp","title":"4.BP\u8a2d\u5b9a\u4fee\u6b63","text":""},{"location":"operation/relay-move/#4-1","title":"4-1.\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u5909\u66f4","text":"

AWS\u306a\u3069ufw\u3092\u4f7f\u7528\u3057\u306a\u3044\u5834\u5408

VPS\u306e\u7ba1\u7406\u753b\u9762\u304b\u3089\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u306e\u8a2d\u5b9a\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002

BP
PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n

<\u65b0\u30ea\u30ec\u30fcIP> \u306e <>\u3092\u9664\u3044\u3066\u65b0\u30ea\u30ec\u30fcIP\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo ufw allow from <\u65b0\u30ea\u30ec\u30fcIP> to any port ${b_PORT}\nsudo ufw reload\n

"},{"location":"operation/relay-move/#4-2","title":"4-2.\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u4fee\u6b63","text":"BP
nano $NODE_HOME/mainnet-topology.json\n
  • \u65e7\u30ea\u30ec\u30fcIP\u3068\u30dd\u30fc\u30c8\u3092\u65b0\u30ea\u30ec\u30fc\u306eIP\u3068\u30dd\u30fc\u30c8\u306b\u5909\u66f4\u3059\u308b
  • DNS\u904b\u7528\u306e\u5834\u5408\u306f\u5909\u66f4\u4e0d\u8981

BP\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl reload-or-restart cardano-node\n

\u30c1\u30a7\u30fc\u30f3\u304c\u540c\u671f\u3057\u305f\u3089\u65b0\u30ea\u30ec\u30fc\u3068BP\u306e\u53cc\u65b9\u5411\u306e\u758e\u901a(I/O)\u304c\u3067\u304d\u3066\u3044\u308b\u304b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

BP

gLiveView\u78ba\u8a8d

cd $NODE_HOME/scripts\n./gLiveView.sh\n

In\u3068Out\u306b\u65b0\u30ea\u30ec\u30fc\u306eIP\u304c\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/relay-move/#5grafanaprometheus","title":"5.Grafana/Prometheus\u8a2d\u5b9a","text":"\u65b0\u30ea\u30ec\u30fc\u3067Grafana\u3082\u904b\u7528\u3059\u308b\u5834\u5408\u65b0\u30ea\u30ec\u30fc\u3067Grafana\u3092\u904b\u7528\u3057\u306a\u3044\u5834\u5408

\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u30bf\u30d6\u30689-3.Grafana\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u8a2d\u5b9a\u3092\u5b9f\u884c\u3059\u308b\u3002

Grafana\u8ffd\u52a0\u8a2d\u5b9a

Grafana\u306f\u8ffd\u52a0\u8a2d\u5b9a\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • \u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a
  • \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u8a2d\u5b9a
  • \u65b0\u30ea\u30ec\u30fc\u306b\u3066prometheus node exporter\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002
\u65b0\u30ea\u30ec\u30fc
sudo apt install -y prometheus-node-exporter\n

\u30b5\u30fc\u30d3\u30b9\u3092\u6709\u52b9\u306b\u3057\u3066\u3001\u81ea\u52d5\u7684\u306b\u958b\u59cb\u3055\u308c\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3059\u3002

sudo systemctl enable prometheus-node-exporter.service\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

prometheus.yml\u306e\u4fee\u6b63

  • DNS\u30d9\u30fc\u30b9\u3067\u63a5\u7d9a\u3057\u3066\u3044\u308b\u4eba\u306f\u3001DNS\u306e\u5909\u66f4\u304c\u53cd\u6620\u3055\u308c\u305f\u3089\u81ea\u52d5\u7684\u306b\u5207\u308a\u66ff\u308f\u308b\u306e\u3067\u4ee5\u4e0b\u4f5c\u696d\u306f\u4e0d\u8981\u3067\u3059\u3002
Grafana\u30b5\u30fc\u30d0\u30fc(\u30ea\u30ec\u30fc1\u306a\u3069)
sudo nano /etc/prometheus/prometheus.yml\n
  • \u65e7\u30ea\u30ec\u30fc\u306eIP\u3092\u65b0\u30ea\u30ec\u30fc\u306eIP\u3078\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044

\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5

sudo systemctl restart grafana-server.service\nsudo systemctl restart prometheus.service\nsudo systemctl restart prometheus-node-exporter.service\n

\u30b5\u30fc\u30d3\u30b9\u304c\u6b63\u3057\u304f\u5b9f\u884c\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service\n

Grafana\u306b\u65b0\u30ea\u30ec\u30fc\u306e\u30e1\u30c8\u30ea\u30af\u30b9(Slot\u306a\u3069)\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b\u3002

"},{"location":"operation/relay-move/#6","title":"6.\u30d7\u30fc\u30eb\u60c5\u5831\u66f4\u65b0","text":"

\u30d7\u30fc\u30eb\u60c5\u5831\u306e\u66f4\u65b0\u3092\u7528\u3044\u3066\u3001\u30c1\u30a7\u30fc\u30f3\u767b\u9332\u4e2d\u306e\u30ea\u30ec\u30fcIP\u3092\u5909\u66f4\u3059\u308b\u3002 (DNS\u904b\u7528\u306e\u5834\u5408\u306f\u4e0d\u8981\u3067\u3059)

"},{"location":"operation/relay-move/#7","title":"7.\u88dc\u8db3","text":""},{"location":"operation/relay-move/#tracemempool","title":"Tracemempool\u7121\u52b9\u5316","text":"

\u65b0\u30ea\u30ec\u30fc\u306b\u5341\u5206\u306aIn\u304c\u78ba\u8a8d\u3067\u304d\u305f\u5834\u5408\u306e\u51e6\u7406

\u65b0\u30ea\u30ec\u30fc

Tx\u306e\u5897\u52a0\u304c\u78ba\u8a8d\u3067\u304d\u305f\u3089Tracemempool\u3092\u7121\u52b9\u306b\u3057\u307e\u3059\u3002

sed -i $NODE_HOME/${NODE_CONFIG}-config.json \\\n    -e \"s/TraceMempool\\\": true/TraceMempool\\\": false/g\"\n

\u30ce\u30fc\u30c9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cardano-node\n

\u65e7\u30ea\u30ec\u30fc\u30b9\u30c8\u30c3\u30d7

\u65e7\u30ea\u30ec\u30fc

sudo systemctl stop cardano-node\n
\u30b5\u30fc\u30d3\u30b9\u89e3\u9664
sudo systemctl disable cardano-node\n

BP\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u304b\u3089\u65e7\u30ea\u30ec\u30fcIP\u524a\u9664

BP

sudo ufw status numbered\n
sudo ufw delete <\u524a\u9664\u3057\u305f\u3044\u756a\u53f7>\n

ufw\u3092\u4f7f\u308f\u306a\u3044\u30b1\u30fc\u30b9

AWS\u3084VSP\u306b\u3088\u3063\u3066\u306f\u7ba1\u7406\u753b\u9762\u3067\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a(\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb)\u3092\u884c\u3063\u3066\u3044\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u3001\u305d\u306e\u5834\u5408\u306fVPS\u7ba1\u7406\u753b\u9762\u304b\u3089\u8a2d\u5b9a\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/relay-move/#mithril-signer","title":"Mithril-Signer\u518d\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u65e7\u30b5\u30fc\u30d0\u30fc\u3067Mithril-Signer-Relay\u3092\u5b9f\u884c\u3057\u3066\u3044\u305f\u5834\u5408\u306f\u3001\u65b0\u30b5\u30fc\u30d0\u30fc\u3067\u3082\u518d\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e0d\u660e\u70b9\u304c\u3042\u308b\u5834\u5408\u306fBTBF SPO LAB.\u3067\u3054\u8cea\u554f\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/rsync-ssh/","title":"\u30b5\u30fc\u30d0\u30fc\u9593\u540c\u671f\u8a2d\u5b9a(RSYNC+SSH)","text":"

\u6982\u8981

\u30b5\u30fc\u30d0\u30fc\u9593\u3067\u4efb\u610f\u306e\u30c7\u30fc\u30bf\u3092\u8ee2\u9001\u3059\u308b\u8a2d\u5b9a\u3067\u3059\u3002 \u65b0\u30ce\u30fc\u30c9\u66f4\u65b0\u6642\u306b\u767a\u751f\u3059\u308bDB\u518d\u69cb\u7bc9\u6642\u306e\u30c0\u30a6\u30f3\u30bf\u30a4\u30e0\u3092\u6291\u3048\u305f\u308a\u3001\u30d3\u30eb\u30c9\u3055\u308c\u305f\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb(NODE/CLI)\u3092\u305d\u306e\u307e\u307e\u4efb\u610f\u306e\u30b5\u30fc\u30d0\u30fc\u3078\u8ee2\u9001\u3067\u304d\u307e\u3059\u3002

1.\u8ee2\u9001\u5143\u306e\u30b5\u30fc\u30d0\u30fc\u30921\u53f0\u6c7a\u3081\u307e\u3059\u3002(\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3082\u3057\u304f\u306f\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30ce\u30fc\u30c9\u3092\u63a8\u5968) 2.\u8ee2\u9001\u5148\u306f\u8907\u6570\u53f0\u306e\u30b5\u30fc\u30d0\u30fc\u3092\u4e8b\u524d\u306b\u8a2d\u5b9a\u51fa\u6765\u307e\u3059\u3002 3.RSYNC+SSH\u5c02\u7528\u306e\u8a8d\u8a3c\u30ad\u30fc\u3092\u4f5c\u6210\u3057\u63a5\u7d9a\u3057\u307e\u3059\u3002 4.\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u306f\u3001\u6307\u5b9a\u3057\u305f\u8ee2\u9001\u5143IP\u304b\u3089\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u307f\u53d7\u3051\u4ed8\u3051\u307e\u3059\u3002

\u69cb\u6210\u30a4\u30e1\u30fc\u30b8

flowchart LR\n    a[\u8ee2\u9001\u5143\u30ea\u30ec\u30fc1] -->|RSYNC+SSH| b[\u30ea\u30ec\u30fc2] & c[\u30ea\u30ec\u30fc3] & d[BP]

"},{"location":"operation/rsync-ssh/#1","title":"1.\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a","text":"

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3082\u3057\u304f\u306f\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30ce\u30fc\u30c9

"},{"location":"operation/rsync-ssh/#1-1rsyncssh","title":"1-1.RSYNC\u5c02\u7528SSH\u8a8d\u8a3c\u30ad\u30fc\u306e\u4f5c\u6210","text":"\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a

ed25519\u6697\u53f7\u3067\u8a8d\u8a3c\u30ad\u30fc\u3092\u4f5c\u6210\u3059\u308b

ssh-keygen -t ed25519 -N '' -C Data_Transfer -f ~/.ssh/rsync_ed25519\n

\u751f\u6210\u3055\u308c\u305f\u8a8d\u8a3c\u30ad\u30fc\u3092\u78ba\u8a8d\u3059\u308b

ls ~/.ssh/\n
  • rsync_ed25519\u30fb\u30fb\u30fb\u79d8\u5bc6\u9375
  • rsync_ed25519.pub\u30fb\u30fb\u30fb\u516c\u958b\u9375

\u3053\u306e2\u3064\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u751f\u6210\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002USB\u306a\u3069\u3078\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u63a8\u5968

"},{"location":"operation/rsync-ssh/#1-2ssh","title":"1-2.SSH\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210","text":"

\u30b3\u30de\u30f3\u30c9\u5185\u8a33

\u5fc5\u305a\u81ea\u5206\u306e\u74b0\u5883\u306b\u5408\u308f\u305b\u3066\u30b3\u30de\u30f3\u30c9\u3092\u5b8c\u6210\u3055\u305b\u3066\u304f\u3060\u3055\u3044\u3002

Host [\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u306e\u4efb\u610f\u540d]\u3000\u203b\u63a5\u7d9a\u6642\u306e\u30a8\u30a4\u30ea\u30a2\u30b9\u540d\u306b\u306a\u308a\u307e\u3059 HostName [\u8ee2\u9001\u5148IP\u307e\u305f\u306f\u30c9\u30e1\u30a4\u30f3] User [\u8ee2\u9001\u5148\u306eUser\u540d] port [\u8ee2\u9001\u5148\u306eSSH\u30dd\u30fc\u30c8] IdentityFile [SSH\u79d8\u5bc6\u9375\u306e\u30d1\u30b9]

\u8ee2\u9001\u5148\u304c\u8907\u6570\u53f0\u3042\u308b\u5834\u5408\u306f\u4e0a\u8a18\u30921\u30bb\u30c3\u30c8\u3068\u3057\u3066\u8ffd\u52a0\u3059\u308b

\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9

cat > ~/.ssh/config << EOF\nHost BP\n    HostName xxx.xxx.xxx.xx\n    User xxxxx\n    Port xx\n    IdentityFile ~/.ssh/rsync_ed25519\n\nHost Relay2\n    HostName xxx.xx.xxx.xx\n    User xxxxx\n    Port xx\n    IdentityFile ~/.ssh/rsync_ed25519\nEOF\n

\u30a2\u30af\u30bb\u30b9\u6a29\u3092\u5909\u66f4\u3059\u308b

chmod 600 ~/.ssh/config\n

"},{"location":"operation/rsync-ssh/#1-3ssh","title":"1-3.SSH\u516c\u958b\u9375\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001","text":"

\u516c\u958b\u9375\u3092cnode\u3078\u79fb\u52d5\u3059\u308b

mv ~/.ssh/rsync_ed25519.pub $NODE_HOME/\n

"},{"location":"operation/rsync-ssh/#1-4zstandard","title":"1-4.ZStandard\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
sudo apt install zstd\n
"},{"location":"operation/rsync-ssh/#2","title":"2.\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a","text":"

\u8ee2\u9001\u5143\u306b\u3042\u308brsync_ed25519.pub\u3092\u8ee2\u9001\u5148\u3078\u30b3\u30d4\u30fc\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u3010\u91cd\u8981\u3011\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u306ecnode\u76f4\u4e0b\u306b\u3042\u308b\u516c\u958b\u9375\u30d5\u30a1\u30a4\u30ebrsync_ed25519.pub\u3092\u3001\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u306ecnode\u30d5\u30a9\u30eb\u30c0\u3078\u30b3\u30d4\u30fc\u3059\u308b

graph LR\n    A[\u8ee2\u9001\u5143] -->|rsync_ed25519.pub| B[\u8ee2\u9001\u5148];
"},{"location":"operation/rsync-ssh/#2-1ssh","title":"2-1.SSH\u516c\u958b\u9375\u306e\u8ffd\u8a18","text":"

\u30b3\u30de\u30f3\u30c9\u3068\u516c\u958b\u9375\u306e\u7d44\u307f\u5408\u308f\u305b\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\u3059\u308b

echo 'command=\"rsync --server --daemon --config='$NODE_HOME'/rsyncd.conf .\",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding '$(cat $NODE_HOME/rsync_ed25519.pub)'' > $NODE_HOME/rsync.txt\n

\u516c\u958b\u9375\u30b3\u30de\u30f3\u30c9\u3092authorized_keys\u306b\u8ffd\u8a18\u3059\u308b

cat $NODE_HOME/rsync.txt >> ~/.ssh/authorized_keys\n

"},{"location":"operation/rsync-ssh/#2-2rsync","title":"2-2.RSYNC\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210","text":"

allowIP\u5909\u6570\u306b\u8ee2\u9001\u5143IP\u3092\u4ee3\u5165\u3059\u308b\u3002x.x.x.x\u3092\u8ee2\u9001\u5143\u306eIP\u306b\u5909\u66f4\u3057\u3066\u5b9f\u884c\u3059\u308b\u3002

allowIP=x.x.x.x\n

\u4ee5\u4e0b\u30b3\u30de\u30f3\u30c9\u3092\u4e00\u62ec\u30b3\u30d4\u30fc\u3057\u3066\u3001\u5b9f\u884c\u3059\u308b\u3002

cat > $NODE_HOME/rsyncd.conf << EOF\n# SSH\u3067\u4e00\u822c\u30e6\u30fc\u30b6\u306e\u5834\u5408\u306f\u4f7f\u3048\u306a\u3044\u306e\u3067no\nuse chroot = no\n# \u66f8\u304d\u8fbc\u3080\u5fc5\u8981\u304c\u3042\u308b\u306e\u3067read only\u306fno\nread only = no\n# \u9006\u306b\u8aad\u307f\u53d6\u308b\u5fc5\u8981\u306f\u306a\u3044\u306e\u3067write only\u3092yes\u306b\nwrite only = yes\n# \u4e00\u65e6\u3059\u3079\u3066\u62d2\u5426\nhosts deny = *\n# \u5727\u7e2e\u6e08\u307f\u306e\u7269\u306f\u518d\u5727\u7e2e\u3057\u306a\u3044\ndont compress = *.pdf *.jpg *.jpeg *.gif *.png *.mp3 *.mp4 *.ogg *.avi *.7z *.z *.gz *.tgz *.zip *.lzh *.bz2 *.rar *.xz\n\n[Server]\n  #\u30a2\u30af\u30bb\u30b9\u8a31\u53ef\u30d1\u30b9\n  path = $NODE_HOME\n  # \u63a5\u7d9a\u5143\u306eIP\u30a2\u30c9\u30ec\u30b9\u3092\u8a2d\u5b9a\n  hosts allow = $allowIP\nEOF\n

"},{"location":"operation/rsync-ssh/#3","title":"3.\u8ee2\u9001\u30c6\u30b9\u30c8","text":"

\u8ee2\u9001\u5143\u304b\u3089\u8ee2\u9001\u5148\u3078\u30d5\u30a1\u30a4\u30eb\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002

\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc

\u8ee2\u9001\u7528\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

cd $NODE_HOME\ncardano-cli query protocol-parameters \\\n    --mainnet \\\n    --out-file params-test.json\n

\u8ee2\u9001\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b

\u30b3\u30de\u30f3\u30c9\u5185\u8a33

rsync -P --rsh=ssh [\u8ee2\u9001\u5143\u8ee2\u9001\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9] [\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u540d]::Server/[\u8ee2\u9001\u30d5\u30a1\u30a4\u30eb\u540d]

  • [\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u540d]\u306b\u306f\u30011-2\u3067\u8a2d\u5b9a\u3057\u305f\u8ee2\u9001\u5148Host\u540d(\u30a8\u30a4\u30ea\u30a2\u30b9)\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002

\u30b5\u30f3\u30d7\u30eb\u30b3\u30de\u30f3\u30c9

rsync -P --rsh=ssh $NODE_HOME/params-test.json Relay2::Server/params-test.json\n

  • \u521d\u56de\u63a5\u7d9a\u6642\u306e\u307f\u30d5\u30a3\u30f3\u30ac\u30fc\u30d7\u30ea\u30f3\u30c8\u306e\u78ba\u8a8d\u304c\u5165\u308b\u306e\u3067yes\u3092\u5165\u529b\u3059\u308b
  • Verification code: \u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408\u306f\u3001\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u306e2\u6bb5\u968e\u8a8d\u8a3c\u30b3\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u8ee2\u9001\u5148\u3067\u53d7\u4fe1\u3057\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u78ba\u8a8d\u3059\u308b\u3002

\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc
ls $NODE_HOME/params-test.json\n

\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306e\u623b\u308a\u5024\u304c\u3042\u308c\u3070\u8ee2\u9001\u6210\u529f\u3002

"},{"location":"operation/rsync-ssh/#4","title":"4.\u8ee2\u9001\u5148\u3092\u8ffd\u52a0\u3059\u308b\u5834\u5408","text":"

\u8ee2\u9001\u5148\u3092\u8ffd\u52a0\u3059\u308b\u5834\u5408

  • 1-2\u306eSSH\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u8ee2\u9001\u5148\u3092\u8ffd\u8a18\u3059\u308b
  • \u65b0\u3057\u3044\u8ee2\u9001\u5148\u30672\u30683\u3092\u5b9f\u65bd\u3059\u308b
"},{"location":"operation/sftp/","title":"FileZilla\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"
  • \u672c\u624b\u9806\u306f\u3001MacOS\u3067\u5b9f\u65bd\u3057\u3066\u3044\u307e\u3059\u304c\u3001Windows\u306e\u65b9\u3067\u3082\u3042\u307e\u308a\u9055\u3044\u306f\u306a\u3044\u304b\u3068\u601d\u3044\u307e\u3059\u306e\u3067Windows\u306e\u65b9\u306f\u8aad\u307f\u66ff\u3048\u3066\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u8ca2\u732e\u8005

[AKYO] AKYO\ud83e\udd41 Akyo\u3055\u3093\u306b\u5c0e\u5165\u624b\u9806\u3092\u4f5c\u6210\u9802\u304d\u307e\u3057\u305f\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\uff01

"},{"location":"operation/sftp/#1-filezilla","title":"1- FileZilla\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9","text":"

1-1. \u4ee5\u4e0b\u306e\u30ea\u30f3\u30af\u5148\u304b\u3089FileZilla Client\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002

FileZilla Client\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

OS \u30d5\u30a1\u30a4\u30eb\u540d MacOS FileZilla_X.XX.X_macosx-x86.app.tar.bz2 Windows FileZilla_X.XX.X_win64-setup.exe

Quick download links

Show additional download options

Download FileZilla Client

Mac\u3067\u3042\u308c\u3070\u300cFileZilla_X.XX.X_macosx-x86.app.tar.bz2\u300d

Win\u3067\u3042\u308c\u3070\u300cFileZilla_X.XX.X_win64-setup.exe\u300d - \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u3089\u89e3\u51cd\u3057\u3001Mac\u306e\u65b9\u306fDownloads\u30d5\u30a9\u30eb\u30c0\u304b\u3089Application\u30d5\u30a9\u30eb\u30c0\u3078\u79fb\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002

1-2. \u30dd\u30c3\u30d7\u30a2\u30c3\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u305f\u3089\u4ee5\u4e0b\u306e\u753b\u50cf\u306e\u3088\u3046\u306b\u9032\u3081\u3066FileZilla\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

"},{"location":"operation/sftp/#2-sftp","title":"2- SFTP\u8a2d\u5b9a","text":"

2-1. \u30e1\u30cb\u30e5\u30fc\u30d0\u30fc\u304b\u3089\u300cFileZilla\u300d\u2192\u300c\u8a2d\u5b9a\u300d\u3078\u3068\u9032\u307f\u307e\u3059\u3002

2-2. SFTP\u8a2d\u5b9a\u3057\u307e\u3059\u3002

2-3. \u63a5\u7d9a\u5148\u306e\u4f5c\u6210\u3068\u8a2d\u5b9a\u3092\u3057\u307e\u3059\u3002

\u30d7\u30ed\u30c8\u30b3\u30eb SFTP \u30db\u30b9\u30c8 \u30b5\u30fc\u30d0\u30fcIP \u30dd\u30fc\u30c8 \u8a2d\u5b9a\u3057\u305fssh\u30dd\u30fc\u30c8\u756a\u53f7 \u30ed\u30b0\u30aa\u30f3\u30bf\u30a4\u30d7 \u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6 \u30e6\u30fc\u30b6\u30fc \u30e6\u30fc\u30b6\u30fc\u540d

\u300c\u65b0\u3057\u3044\u30b5\u30a4\u30c8\u300d\u3067\u4f5c\u6210\u3057\u305f\u540d\u79f0\u306f\u4f8b\u3067\u3059\u306e\u3067\u304a\u597d\u307f\u3067\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u3046\u307e\u304f\u63a5\u7d9a\u3067\u304d\u306a\u304b\u3063\u305f\u5834\u5408\u306f\u3001\u30ed\u30b0\u30aa\u30f3\u30bf\u30a4\u30d7\u3092\u4e00\u5ea6\u300c\u9375\u30d5\u30a1\u30a4\u30eb\u300d\u3068\u3057\u3001\u79d8\u5bc6\u9375\u3092\u6307\u5b9a\u3057\u3066\u63a5\u7d9a\u3092\u8a66\u307f\u3066\u3001\u305d\u306e\u5f8c\u30ed\u30b0\u30aa\u30f3\u30bf\u30a4\u30d7\u3092\u300c\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u300d\u306b\u3057\u3066Google\u8a8d\u8a3c\u3067\u306e6\u6841\u306e\u6570\u5b57\u3092\u5165\u529b\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/sjg-fixed/","title":"SJG \u4fee\u6b63\u30d7\u30ed\u30b0\u30e9\u30e0","text":""},{"location":"operation/sjg-fixed/#env","title":"env\u30d5\u30a1\u30a4\u30eb\u5bfe\u5fdc","text":"

\u6700\u7d42\u66f4\u65b0\u65e5\uff1a2022/02/19 v1.0

\u6982\u8981

\u25a0\u767a\u751f\u4e8b\u8c61 gliveview.sh/cncli.sh\u5b9f\u884c\u6642\u306b\u3001\u5b9f\u884c\u3057\u305f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306benv/gliveview.sh/cncli.sh\u304c\u751f\u6210\u3055\u308c\u3066\u3057\u307e\u3046\u3002

\u25a0\u539f\u56e0 env\u5185\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u95a2\u6570\u51e6\u7406\u5909\u66f4\u306b\u4f34\u3046\u3082\u306e

\u25a0\u4fee\u6b63\u30d7\u30ed\u30b0\u30e9\u30e0\u5185\u5bb9 \u21d2.bashrc\u5185alias\u306b\u8a2d\u5b9a\u4e2d\u306e\u5909\u6570(glive/blocks)\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5909\u66f4 \u21d2cncli\u7cfb\u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u306eWorkingDirectory\u3092\u5909\u66f4

\u25a0\u5bfe\u8c61\u8005 * \u30d7\u30fc\u30eb\u69cb\u7bc9\u4e2d\u3067\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u306e\u8a2d\u5b9a\u307e\u3067\u5b8c\u4e86\u3057\u305f\u65b9 * \u30d7\u30fc\u30eb\u904b\u55b6\u4e2dSPO\u306e\u65b9

\u25a0\u5bfe\u8c61\u30b5\u30fc\u30d0\u30fc BP/\u30ea\u30ec\u30fc

"},{"location":"operation/sjg-fixed/#_1","title":"\u25a0\u4fee\u6b63\u30d7\u30ed\u30b0\u30e9\u30e0\u9069\u7528\u624b\u9806","text":""},{"location":"operation/sjg-fixed/#bp","title":"BP\uff0f\u30ea\u30ec\u30fc\u5171\u901a","text":"

1.\u4fee\u6b63\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b(BP\uff0f\u30ea\u30ec\u30fc\u5171\u901a)

cd $NODE_HOME/scripts\nwget -q https://raw.githubusercontent.com/btbf/coincashew/master/guild-tools/service_fixed.sh -O service_fixed.sh\n

2.\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u3092\u8a2d\u5b9a\u3057\u3001\u5b9f\u884c\u3059\u308b

chmod 755 service_fixed.sh\n./service_fixed.sh\n

3.\u30d7\u30ed\u30b0\u30e9\u30e0\u304c\u7d42\u4e86\u3059\u308b\u306e\u3092\u5f85\u3064

4. bashrc\u3092\u8aad\u307f\u8fbc\u3080

source $HOME/.bashrc\n

5.\u4fee\u6b63\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u524a\u9664\u3059\u308b

cd $NODE_HOME/scripts\nrm service_fixed.sh\n

6.\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u78ba\u8a8d\u5bfe\u5fdc

cd $HOME\nglive\n

Script update(s) detected, do you want to download the latest version? (yes/no):yes

\u518d\u5ea6\u3001gliveview\u3092\u5b9f\u884c\u3059\u308b

cd $HOME\nglive\n
\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u78ba\u8a8d\u304c\u51fa\u306a\u304f\u306a\u308b\u307e\u3067yes \u3067\u5bfe\u5fdc\u3059\u308b\u3002

"},{"location":"operation/sjg-fixed/#bp_1","title":"BP\u306e\u307f","text":"

9.\uff08BP\u306e\u307f\uff09\u5404\u30b5\u30fc\u30d3\u30b9\u304c\u52d5\u3044\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

\u8907\u6570\u306e\u30b5\u30fc\u30d3\u30b9\u3067\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u78ba\u8a8d\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u304c\u3001\u3069\u308c\u304b\uff11\u3064\u3067yes\u306b\u3057\u305f\u3089\u4ed6\u306e\u30b5\u30fc\u30d3\u30b9\u3067\u306fno\u306b\u3057\u3066\u304f\u3060\u3055\u3044 \u4f8b\uff09 tmux a -t cncli\u3067\u306fyes Script update(s) detected, do you want to download the latest version? (yes/no):yes tmux a -t validate\u3067\u306fno Script update(s) detected, do you want to download the latest version? (yes/no):no

tmux a -t cncli\n
tmux a -t validate\n
tmux a -t leaderlog\n
tmux a -t logmonitor\n

tmux a -t leaderlog\u306f\u3001\u4eca\u56de\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u306f\u4e2d\u65ad\u51e6\u7406\u3092\u5165\u308c\u3066\u308b\u306e\u3067\u4ee5\u4e0b\u306e\u8868\u8a18\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u304c\u554f\u984c\u3042\u308a\u307e\u305b\u3093\u3002

> Checking for script updates...  \n> ^C\n\n\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u5f97\u3057\u305f\u3044\u5834\u5408\u306f\u3001\u5225\u9014\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n

\u304a\u75b2\u308c\u3055\u307e\u3067\u3057\u305f\u3002

"},{"location":"operation/sjg-fixed/#_2","title":"\u4f5c\u696d\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\u4fee\u6b63","text":"

\u6700\u7d42\u66f4\u65b0\u65e5\uff1a2021\u5e7412\u670827\u65e5\u306e\u6642\u70b9\u3000version 2.2

\u6982\u8981

  • \u30ce\u30fc\u30c9\u3092\u6b62\u3081\u308b\u305f\u3081\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u4e88\u5b9a\u304c\u7121\u3044\u6642\u9593\u5e2f\u306b\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • BP/\u30ea\u30ec\u30fc\u306f\u81ea\u52d5\u5224\u5b9a\u3057\u3001\u305d\u308c\u305e\u308c\u306e\u4f9d\u5b58\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u307e\u3059\u3002
  • \u74b0\u5883\u5909\u6570$NODE_HOME\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u30d1\u30b9\u3092\u8aad\u307f\u53d6\u308a\u81ea\u52d5\u7f6e\u63db\u3057\u307e\u3059\u3002 ex) /home/user/cardano-my-node \u21d2 /home/user/cnode ex) /home/user/cardano-node \u21d2 /home/user/cnode
  • \u73fe\u5728\u8a2d\u5b9a\u4e2d\u306e\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3084\u30d7\u30fc\u30ebID\u3092\u8aad\u307f\u53d6\u308a\u3001\u5404\u30d5\u30a1\u30a4\u30eb\u306b\u81ea\u52d5\u53cd\u6620\u3057\u307e\u3059\u3002

\u6ce8\u610f

\ud83d\uded1 \u65e5\u672c\u8a9e\u30de\u30cb\u30e5\u30a2\u30eb\u3067\u4f7f\u308f\u308c\u3066\u308b\u5404\u7a2e\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u4efb\u610f\u306e\u540d\u524d\u306b\u5909\u66f4\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001\u6b63\u3057\u304f\u52d5\u4f5c\u3057\u306a\u3044\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 \ud83d\udea7 \u3082\u3057\u3001\u30b9\u30af\u30ea\u30d7\u30c8\u30d5\u30a1\u30a4\u30eb\u3084\u30ad\u30fc\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u5909\u66f4\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u5b9f\u884c\u524d\u306bBTBF\u307e\u3067\u3054\u76f8\u8ac7\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/sjg-fixed/#1","title":"1. \u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b","text":"
cd $HOME\nwget -q https://raw.githubusercontent.com/btbf/coincashew/master/guild-tools/dirname_cng.sh -O dirname_cng.sh\n
"},{"location":"operation/sjg-fixed/#2","title":"2.\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u5b9f\u884c\u3059\u308b","text":"
chmod 755 dirname_cng.sh\n./dirname_cng.sh\n

\u753b\u9762\u306e\u6307\u793a\u306b\u5f93\u3063\u3066\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/sjg-fixed/#3","title":"3.\u8d77\u52d5\u78ba\u8a8d","text":"

\u30ce\u30fc\u30c9\u30ed\u30b0\u8868\u793a

journalctl --unit=cardano-node --follow\n

\u30a8\u30e9\u30fc\u304c\u51fa\u3066\u308b\u5834\u5408\u306f\u3001$HOME\u76f4\u4e0b\u306b\u3042\u308b\u300cdirname-\uff0a\uff0a\uff0a.log\u300d\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u3092\u30ae\u30eb\u30c9\u306b\u63d0\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u74b0\u5883\u5909\u6570\u78ba\u8a8d

source $HOME/.bashrc\necho $NODE_HOME\n

\u4f8b) /home/user/cnode\u3000\u3068\u8868\u793a\u3055\u308c\u308c\u3070OK

gliveview\u78ba\u8a8d

\u8868\u793a\u3067\u304d\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Script update(s) detected, do you want to download the latest version? (yes/no):\u300d\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408\u306f\u3001\u51fa\u306a\u304f\u306a\u308b\u307e\u3067 Y

\u30ce\u30fc\u30c9\u5225\u78ba\u8a8d\u4e8b\u9805

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

clontab\u78ba\u8a8d

crontab -l\n

\u4f8b\uff09 \"22 * * * * /home/user/cnode/topologyUpdater.sh\" \u306e\u3088\u3046\u306b\u8868\u793a\u3055\u308c\u308c\u3070OK

\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u8d77\u52d5\u78ba\u8a8d

tmux a -t cncli\n

\uff5e\uff5e\uff5e100.00% synced\u304c\u8868\u793a\u3055\u308c\u305f\u3089OK \u8d64\u6587\u5b57\u306f\u30ce\u30fc\u30c9\u304c\u540c\u671f\u3059\u308b\u307e\u3067\u8868\u793a\u3055\u308c\u308b\u6587\u7ae0\u3067\u3042\u308a\u3001\u30a8\u30e9\u30fc\u3067\u306f\u306a\u3044\u306e\u3067\u30ce\u30fc\u30c9\u304c\u540c\u671f\u3059\u308b\u307e\u3067\u304a\u5f85\u3061\u304f\u3060\u3055\u3044

\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u8b66\u544a\u6587\u304c\u3042\u308b\u5834\u5408

Script update(s) detected, do you want to download the latest version? (yes/no):\u300d\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f Y \u30c7\u30bf\u30c3\u30c1\u3057\u3066\u304b\u3089\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5

sudo systemctl reload-or-restart cnode-cncli-sync.service\n

\u518d\u5ea6\u78ba\u8a8d

tmux a -t cncli\n

\uff5e\uff5e\uff5e100.00% synced\u304c\u8868\u793a\u3055\u308c\u305f\u3089OK

\u5b9f\u884c\u30d5\u30a1\u30a4\u30eb\u524a\u9664

rm $HOME/dirname_cng.sh\n
"},{"location":"operation/sjg-fixed/#4","title":"4.\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u540d\u5909\u66f4","text":"

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u306f\u3001\u4e0a\u8a18\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002

cd $HOME\nmv ./cardano-my-node ./cnode\n
sed -e \"s@cardano-my-node@cnode@g\" -i $HOME/.bashrc\nsource $HOME/.bashrc\necho $NODE_HOME\n

\u4f8b) /home/user/cnode\u3000\u3068\u8868\u793a\u3055\u308c\u308c\u3070OK

"},{"location":"operation/spo-poll/","title":"\u30ab\u30eb\u30c0\u30ce\u8ca1\u56e3SPO\u6295\u7968\u30de\u30cb\u30e5\u30a2\u30eb","text":"

\u6982\u8981

  • \u6295\u7968\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3 fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8
  • \u6295\u7968\u671f\u9650\uff1a413\u30a8\u30dd\u30c3\u30af\u7d42\u4e86\u307e\u3067
  • CIP-0094\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9 Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]
  • \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u624b\u6570\u6599\u306e\u307f\u3067\u6295\u7968\u3067\u304d\u307e\u3059
  • CIP-0094\u306b\u5bfe\u5fdc\u3057\u305fcardano-cli(v8.0.0-untested \u307e\u305f\u306f v8.0.0)\u304c\u5fc5\u8981\u3067\u3059
  • \u6295\u7968\u306f\u521d\u56de\uff11\u56de\u306e\u307f\u304c\u6709\u52b9\u3067\u3059\u3002
"},{"location":"operation/spo-poll/#1sjg-tool","title":"1.SJG TOOL\u3067\u6295\u7968\u3059\u308b","text":"

SJG TOOL\u6295\u7968\u4ed5\u69d8

  • \u6295\u7968\u30c7\u30fc\u30bf\u306b\u7c21\u6613\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u6dfb\u4ed8\u53ef\u80fd\uff01 ADASTAT\u306b\u5b9f\u88c5\u3055\u308c\u305f\u6295\u7968\u30c7\u30fc\u30bf\u7c21\u6613\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u8868\u793a\u3067\u304d\u307e\u3059\u3002
  • \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u306eCLI\u304cCIP-0094\u975e\u5bfe\u5fdc\u306e\u5834\u5408\u306f\u3001cardano-cli v8.0.0-untested\u3092\u5225\u9014\u81ea\u52d5\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002\u3053\u308c\u306f\u6295\u7968\u306e\u307f\u306b\u4f7f\u7528\u3057\u3001\u901a\u5e38\u306e\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306b\u306f\u4f7f\u7528\u3057\u307e\u305b\u3093\u3002
  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306bcardano-cli v8.0.0-untested\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002
  • \u6295\u7968\u5185\u5bb9\u306e\u81ea\u52d5\u7ffb\u8a33\u306fAPI\u81ea\u52d5\u7ffb\u8a33\u306e\u305f\u3081\u3001\u6b63\u3057\u3044\u65e5\u672c\u8a9e\u306b\u306a\u3063\u3066\u3044\u306a\u3044\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002

1-1. SJG TOOL\u3092\u8d77\u52d5\u3057\u3001v5.3\u3078\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044\u3002

1-2. [5] SPO\u6295\u7968\u30c4\u30fc\u30eb \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044

1-3. \u6295\u7968\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30cf\u30c3\u30b7\u30e5\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044

fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8\n

1-4. \u753b\u9762\u306e\u6307\u793a\u306b\u5f93\u3063\u3066\u9032\u3081\u3066\u304f\u3060\u3055\u3044\u3002(\u4e2d\u65ad\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059)

1-5. \u6295\u7968\u78ba\u8a8d CIP-0094\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u3067\u81ea\u8eab\u306e\u6295\u7968\u3092\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff01 Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]

\u4ee5\u4e0a\u3067\u3059\u3002

"},{"location":"operation/spo-poll/#2cli","title":"2.CLI\u30b3\u30de\u30f3\u30c9\u3067\u6295\u7968\u3059\u308b","text":"

CLI\u30b3\u30de\u30f3\u30c9\u6295\u7968\u4ed5\u69d8

  • \u6295\u7968\u30c7\u30fc\u30bf\u7c21\u6613\u30e1\u30c3\u30bb\u30fc\u30b8\u6dfb\u4ed8\u306b\u306f\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u305b\u3093\u3002\u6dfb\u4ed8\u3057\u305f\u3044\u5834\u5408\u306f\u5404\u81ea\u3067\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u7de8\u96c6\u3059\u308b\u304bSJGTOOL\u3092\u5229\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002

2-1.CLI\u30d0\u30fc\u30b8\u30e7\u30f3\u30c1\u30a7\u30c3\u30af

cardano-cli version\n

v8.0.0\u306fCIP-0094\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002

CLI\u30d1\u30b9\u3092\u8a2d\u5b9a\u3059\u308b

cli_path=$(which cardano-cli)\n

\u4f5c\u696d\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3059\u308b

mkdir $HOME/git/spo-poll && cd $HOME/git/spo-poll\n

CLI v1.35.7\u4ee5\u4e0b\u306e\u5834\u5408

CIP-0094\u306b\u5bfe\u5fdc\u3057\u305fCLI\u304c\u5fc5\u8981\u306e\u305f\u3081\u3001\u4ee5\u4e0b\u3092\u5b9f\u884c\u3057v8.0.0-untested\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u3053\u308c\u306f\u6295\u7968\u306e\u307f\u306b\u4f7f\u7528\u3057\u3001\u901a\u5e38\u306e\u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u306b\u306f\u4f7f\u7528\u3057\u307e\u305b\u3093\u3002

v8.0.0-untested\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

wget -q https://github.com/btbf/spojapanguild/raw/d7cd9792ab4cb532b74a8cd1bf30de3c1c03b8a6/scripts/spo-poll/cardano-cli.gz\ngzip -d cardano-cli.gz\nchmod 755 $HOME/git/spo-poll/cardano-cli\n
\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d
$HOME/git/spo-poll/cardano-cli version\n

cardano-cli 8.0.0 - linux-x86_64 - ghc-8.10 git rev 0000000000000000000000000000000000000000

CLI\u30d1\u30b9\u3092\u4e0a\u66f8\u304d\u3059\u308b

cli_path=$HOME/git/spo-poll/cardano-cli\n

  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306bcardano-cli v8.0.0-untested\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002

\u6295\u7968\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30cf\u30c3\u30b7\u30e5\u3092\u8a2d\u5b9a\u3059\u308b

txHash=\"fae7bda85acb99c513aeab5f86986047b6f6cbd33a8e11f11c5005513a054dc8\"\n

\u6295\u7968Cbor\u30c7\u30fc\u30bf(json)\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

wget https://raw.githubusercontent.com/cardano-foundation/CIP-0094-polls/main/networks/${NODE_CONFIG}/${txHash}/poll.json -O $HOME/git/spo-poll/poll_${txHash}-CBOR.json\n

\u6295\u7968\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b

${cli_path} governance answer-poll --poll-file $HOME/git/spo-poll/poll_${txHash}-CBOR.json > $HOME/git/spo-poll/poll_${txHash}-poll-answer.json\n

\u6295\u7968\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u9001\u4fe1\u6e96\u5099

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

\u30a6\u30a9\u30ec\u30c3\u30c8\u6b8b\u9ad8\u78ba\u8a8d

cd $NODE_HOME\ncardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u8a08\u7b97

tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

\u6295\u7968\u7528\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

cd $NODE_HOME\ncardano-cli transaction build \\\n    $NODE_NETWORK \\\n    ${tx_in} \\\n    --change-address $(cat payment.addr) \\\n    --metadata-json-file $HOME/git/spo-poll/poll_${txHash}-poll-answer.json \\\n    --json-metadata-detailed-schema \\\n    --required-signer-hash $(cat pool.id) \\\n    --out-file $NODE_HOME/poll-answer.tx\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306epoll-answer.tx \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|poll-answer.tx| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u7f72\u540d\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nchmod u+rwx $HOME/cold-keys\ncardano-cli transaction sign \\\n    --tx-body-file poll-answer.tx \\\n    --signing-key-file $HOME/cold-keys/node.skey \\\n    --signing-key-file payment.skey \\\n    $NODE_NETWORK \\\n    --out-file poll-answer-tx.signed\nchmod a-rwx $HOME/cold-keys\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306epoll-answer-tx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|poll-answer-tx.signed| B[BP];

BP\u3067\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
submit_txHash=$(cardano-cli transaction txid --tx-file $NODE_HOME/poll-answer.tx)\ncardano-cli transaction submit --tx-file $NODE_HOME/poll-answer-tx.signed $NODE_NETWORK\n

\u6570\u5206\u5f8c\u306b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u78ba\u8a8d\u3059\u308b

curl -sX POST \"https://api.koios.rest/api/v0/tx_metadata\" -H \"accept: application/json\" -H \"content-type: application/json\"  -d \"{\\\"_tx_hashes\\\":[\\\"${submit_txHash}\\\"]}\" | jq .\n

"},{"location":"operation/spo-poll/#_1","title":"\u6295\u7968\u78ba\u8a8d","text":"

CIP-0094\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u3067\u81ea\u8eab\u306e\u6295\u7968\u3092\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\uff01 Adastat.net [Mainnet] / Cardanoscan.io [Mainnet]

\u4ee5\u4e0a\u3067\u3059\u3002

"},{"location":"operation/start-guide/","title":"\u30ab\u30eb\u30c0\u30ce\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u904b\u7528\u30ac\u30a4\u30c9","text":"

\u30b5\u30dd\u30fc\u30c8

\u30b5\u30dd\u30fc\u30c8\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001SPO JAPAN GUILD\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u3067\u73fe\u5f79\u306eSPO\u306b\u8cea\u554f\u3067\u304d\u307e\u3059

"},{"location":"operation/start-guide/#_2","title":"\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u7406\u89e3\u3059\u308b","text":"\u9805\u76ee \u5024 \u7528\u9014 optimal_pool_count(K) 500 \u98fd\u548c\u95be\u5024\u8a2d\u5b9a\u7528 a0 0.3 \u8a93\u7d04\u5831\u916c\u4fc2\u6570\u3000 max_tx_size 16384 \u6700\u5927\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b5\u30a4\u30ba\u3000 max_block_size 90112 \u6700\u5927\u30d6\u30ed\u30c3\u30af\u30b5\u30a4\u30ba\u3000 epochLength 432000 1\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30ed\u30c3\u30c8\u6570\u3000 slotsPerKESPeriod 129600 1KES\u5f53\u305f\u308a\u306e\u30b9\u30ed\u30c3\u30c8\u6570\u3000 maxKESEvolutions 62 KES\u6709\u52b9\u671f\u9593\u3000 activeSlotsCoeff 0.05 1\u30a8\u30dd\u30c3\u30af\u5185\u306e\u6709\u52b9\u30b9\u30ed\u30c3\u30c8\u7387"},{"location":"operation/start-guide/#_3","title":"\u30b9\u30ed\u30c3\u30c8\u3092\u7406\u89e3\u3059\u308b","text":"
  • Slot = \u30b8\u30a7\u30cd\u30b7\u30b9\u30b9\u30ed\u30c3\u30c8\u304b\u3089\u306e\u30b9\u30ed\u30c3\u30c8
  • Slot epoch = \u30a8\u30dd\u30c3\u30af\u5185\u306e\u30b9\u30ed\u30c3\u30c8

  • 1\u30b9\u30ed\u30c3\u30c8\uff1d1\u79d2

  • 1\u30a8\u30dd\u30c3\u30af\uff1d432000\u30b9\u30ed\u30c3\u30c8(epochLength) (432000 / 60 = 7200\u5206 / 60 = 120\u6642\u9593 / 24 = 5\u65e5)
"},{"location":"operation/start-guide/#_4","title":"\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc","text":"

1\u30a8\u30dd\u30c3\u30af\u5185\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u6709\u52b9\u30b9\u30ed\u30c3\u30c8\u306f5%(432000\u30b9\u30ed\u30c3\u30c8 \u00d7 5% \uff1d \u7d0421600\u30b9\u30ed\u30c3\u30c8) \u59d4\u4efb\u91cf\u306b\u5fdc\u3058\u3066\u3001\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u304c\u30e9\u30f3\u30c0\u30e0\u306b\u6c7a\u5b9a\u3055\u308c\u307e\u3059\u3002

1\u30a8\u30dd\u30c3\u30af\u30671\u30d6\u30ed\u30c3\u30af\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u59d4\u4efb\u91cf\u306e\u76ee\u5b89\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002

  • 1M 60%
  • 2M 85%
  • 3M 95%

\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u306e\u5272\u308a\u5f53\u3066\u306f\u3001\u30d7\u30fc\u30eb\u9593\u540c\u58eb\u3067\u8abf\u6574\u3055\u308c\u306a\u3044\u305f\u3081\u4ee5\u4e0b\u306e\u30bf\u30a4\u30d7\u306e\u30d0\u30c8\u30eb\u304c\u767a\u751f\u3057\u307e\u3059\u3002

\u30b9\u30ed\u30c3\u30c8\u30d0\u30c8\u30eb(stolen)

\u4ed6\u30d7\u30fc\u30eb\u3068\u540c\u3058\u30b9\u30ed\u30c3\u30c8\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u969b\u306b\u767a\u751f vrf\u5024\u306b\u3088\u308b\u30b5\u30a4\u30b3\u30ed\u30b2\u30fc\u30e0\u304c\u884c\u308f\u308c\u51fa\u305f\u76ee\u306e\u5c0f\u3055\u3044\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u304c\u63a1\u7528\u3055\u308c\u307e\u3059\u3002(\u30b9\u30c6\u30fc\u30af\u91cf\u306b\u3088\u308b\u512a\u4f4d\u6027\u306f\u306a\u304f\u30e9\u30f3\u30c0\u30e0)

\u30cf\u30a4\u30c8\u30d0\u30c8\u30eb(Ghosted / missed)

\u4ed6\u30d7\u30fc\u30eb\u30685\u79d2\u4ee5\u5185\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u5834\u5408\u3084\u3001\u524d\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30d7\u30fc\u30eb\u306e\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a\u30fb\u74b0\u5883\u306b\u3088\u308a\u30d6\u30ed\u30c3\u30af\u4f1d\u64ad\u9045\u5ef6\u304c\u767a\u751f\u3059\u308b\u3053\u3068\u3067\u5f15\u304d\u8d77\u3053\u308b\u73fe\u8c61\u3002\u5730\u7406\u7684\u512a\u4f4d\u6027\u3092\u7121\u304f\u3059\u305f\u3081\u3001vrf\u5024\u306b\u3088\u308b\u30b5\u30a4\u30b3\u30ed\u30b2\u30fc\u30e0\u304c\u884c\u308f\u308c\u51fa\u305f\u76ee\u306e\u5c0f\u3055\u3044\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u304c\u63a1\u7528\u3055\u308c\u307e\u3059\u3002(\u30b9\u30c6\u30fc\u30af\u91cf\u306b\u3088\u308b\u512a\u4f4d\u6027\u306f\u306a\u304f\u30e9\u30f3\u30c0\u30e0)

"},{"location":"operation/start-guide/#kes","title":"KES\u3068\u306f\uff1f","text":"

KES\uff1dKey-Evolving Signatures

\u30d6\u30ed\u30c3\u30af\u751f\u6210\u7f72\u540d\u7528\u9375\u30d5\u30a1\u30a4\u30eb\u3002\u904e\u53bb\u306e\u30d6\u30ed\u30c3\u30af\u7f72\u540d\u3092\u66f8\u304d\u63db\u3048\u308b\u3053\u3068\u304c\u51fa\u6765\u306a\u3044\u3088\u304690\u65e5\u3054\u3068\u306b\u66f4\u65b0\u304c\u5fc5\u8981\u3002

"},{"location":"operation/start-guide/#vrf","title":"VRF\u3068\u306f\uff1f","text":"

VRF=Verifiable Random Function

Ouroboros Praos\u306f\u3001VRF\uff08Verifiable Random Function\uff09\u30ad\u30fc\u306b\u3088\u3063\u3066\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u3055\u3089\u306a\u308b\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5c64\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002 Ouroboros Praos\u306e\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u975e\u516c\u958b\u3068\u306a\u3063\u3066\u304a\u308a\u3001VRF\u30ad\u30fc\u3092\u4f7f\u3063\u3066\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u306e\u691c\u8a3c\u3092\u884c\u3063\u3066\u304a\u308a\u307e\u3059\u3002

"},{"location":"operation/start-guide/#_5","title":"\u5404\u30d5\u30a1\u30a4\u30eb\u306e\u5f79\u5272\u3068\u4fdd\u7ba1\u5834\u6240","text":""},{"location":"operation/start-guide/#_6","title":"\u8a3c\u660e\u66f8\u3068\u30da\u30a2\u30ad\u30fc","text":"

\u30fb\u30fb\u30fb\u30ed\u30c3\u30af\u5fc5\u9808\u30fb\u518d\u4f5c\u6210\u4e0d\u53ef\u30fb\u7d1b\u5931\u4e0d\u53ef \u30fb\u30fb\u30fb\u66f4\u65b0\u6642\u66f8\u304d\u63db\u3048\u30fb\u518d\u4f5c\u6210\u53ef\u80fd \ud83d\udd34\u30fb\u30fb\u30fbBP\u8d77\u52d5\u3067\u4f7f\u7528 \ud83d\udd37\u30fb\u30fb\u30fb\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u3067\u4f7f\u7528

\u9375\u30d5\u30a1\u30a4\u30eb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u306b\u3064\u3044\u3066

\u30de\u30fc\u30af\u304c\u4ed8\u3044\u305f\u30d5\u30a1\u30a4\u30eb\u306f\u30d7\u30fc\u30eb\u904b\u55b6\u306b\u3068\u3066\u3082\u91cd\u8981\u306a\u30d5\u30a1\u30a4\u30eb\u3067\u3059\u3002\u7d1b\u5931\u30fb\u524a\u9664\u3059\u308b\u3068\u30d7\u30fc\u30eb\u904b\u55b6\u304c\u7d99\u7d9a\u3067\u304d\u306a\u304f\u306a\u3063\u305f\u308a\u3001\u8cc7\u91d1\u3092\u5f15\u304d\u51fa\u305b\u306a\u304f\u306a\u308a\u307e\u3059\u3002\u305d\u306e\u305f\u3081\u540c\u4e00\u30d5\u30a1\u30a4\u30eb\u3092\u8907\u6570\u306eUSB\u306a\u3069\u3078\u5206\u6563\u4fdd\u7ba1\u3059\u308b\u3088\u3046\u306b\u3057\u307e\u3057\u3087\u3046\u3002

\u30d5\u30a1\u30a4\u30eb \u7528\u9014 \u63a8\u5968\u4fdd\u7ba1\u5834\u6240 \u91cd\u8981\u5ea6 payment.vkey payment\u30a2\u30c9\u30ec\u30b9\u516c\u958b\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB payment.skey payment\u30a2\u30c9\u30ec\u30b9\u79d8\u5bc6\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB stake.vkey \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u516c\u958b\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB stake.skey \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u79d8\u5bc6\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB vrf.vkey\ud83d\udd37 VRF\u516c\u958b\u9375 BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB vrf.skey\ud83d\udd34 VRF\u79d8\u5bc6\u9375 BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB node.vkey \u30b3\u30fc\u30eb\u30c9\u516c\u958b\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB node.skey \u30b3\u30fc\u30eb\u30c9\u79d8\u5bc6\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB payment.addr payment\u30a2\u30c9\u30ec\u30b9\u30d5\u30a1\u30a4\u30eb BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB stake.addr \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u79d8\u5bc6\u9375 BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB kes.vkey KES\u516c\u958b\u9375 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB kes.skey\ud83d\udd34 KES\u79d8\u5bc6\u9375 BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB node.cert\ud83d\udd34 \u30d7\u30fc\u30eb\u904b\u7528\u8a3c\u660e\u66f8 BP \uff0f \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB pool.cert \u30d7\u30fc\u30eb\u767b\u9332\u8a3c\u660e\u66f8 \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB node.counter \u30ab\u30a6\u30f3\u30bf\u30fc\u30d5\u30a1\u30a4\u30eb \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7 \uff0f USB"},{"location":"operation/start-guide/#_7","title":"\u30ce\u30fc\u30c9\u8d77\u52d5\u7528\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb","text":"\u30d5\u30a1\u30a4\u30eb \u7528\u9014 mainnet-byron-genesis.json Byron\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb mainnet-shelley-genesis.json Shelley\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb mainnet-alonzo-genesis.json Alonzo\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb mainnet-config.json \u30ce\u30fc\u30c9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb mainnet-topology.json \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb"},{"location":"operation/start-guide/#_8","title":"\u30b9\u30af\u30ea\u30d7\u30c8\u30d5\u30a1\u30a4\u30eb\u3084\u305d\u306e\u4ed6","text":"\u30d5\u30a1\u30a4\u30eb \u7528\u9014 \u63a8\u5968\u4fdd\u7ba1\u5834\u6240 \u91cd\u8981\u5ea6 startRelayNode1.sh \u30ea\u30ec\u30fc\u7528\u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8 \u30ea\u30ec\u30fc startBlockProducingNode.sh BP\u7528\u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8 BP gLiveView.sh \u30ce\u30fc\u30c9GUI\u7528\u30b9\u30af\u30ea\u30d7\u30c8 \u30ea\u30ec\u30fc/BP topologyUpdater.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u767b\u9332\u30b9\u30af\u30ea\u30d7\u30c8 \u30ea\u30ec\u30fc relay-topology_pull.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u751f\u6210\u30b9\u30af\u30ea\u30d7\u30c8 \u30ea\u30ec\u30fc params.json \u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u30d5\u30a1\u30a4\u30eb BP poolMetaData.json \u30d7\u30fc\u30eb\u60c5\u5831JSON BP poolMetaDataHash.txt poolMetaData.json\u30cf\u30c3\u30b7\u30e5\u5024\u30d5\u30a1\u30a4\u30eb BP fullUtxo.out UTXO\u51fa\u529b\u30d5\u30a1\u30a4\u30eb \u4f7f\u7528\u5f8c\u524a\u9664\u53ef - balance.out \u30a6\u30a9\u30ec\u30c3\u30c8\u6b8b\u9ad8\u51fa\u529b\u30d5\u30a1\u30a4\u30eb \u4f7f\u7528\u5f8c\u524a\u9664\u53ef - tx.tmp \u4eee\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb \u4f7f\u7528\u5f8c\u524a\u9664\u53ef - tx.raw \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb \u4f7f\u7528\u5f8c\u524a\u9664\u53ef - tx.signed \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u7f72\u540d\u4ed8\u304d\u30d5\u30a1\u30a4\u30eb \u4f7f\u7528\u5f8c\u524a\u9664\u53ef -"},{"location":"operation/start-guide/#_9","title":"\u4f5c\u696d\u5185\u5bb9\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8","text":"

\u65e5\u6b21\u4f5c\u696d

  • \u30ce\u30fc\u30c9\u7a3c\u50cd\u72b6\u6cc1\u30c1\u30a7\u30c3\u30af(Grafana\u7b49)

\u30a8\u30dd\u30c3\u30af\u6bce\u4f5c\u696d

  • \u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u7b97\u51fa\u3059\u308b (320000\u30b9\u30ed\u30c3\u30c8\u3092\u8d85\u3048\u3066\u304b\u3089\u30a8\u30dd\u30c3\u30af\u7d42\u4e86\u307e\u3067\u306b)

  • \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u66f4\u65b0

3\u304b\u6708\u6bce\u4f5c\u696d

  • KES\u66f4\u65b0(1-KES\u306e\u66f4\u65b0)

\u4e0d\u5b9a\u671f\u4f5c\u696d

  • \u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8
  • \u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u88fd\u30a2\u30d7\u30ea\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8
  • \u30b5\u30fc\u30d0\u30fc\u969c\u5bb3\u5bfe\u5fdc
  • \u30d7\u30fc\u30eb\u8a2d\u5b9a\u5909\u66f4\u306a\u3069
"},{"location":"operation/start-guide/#_10","title":"\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u66f4\u65b0","text":"

\u6982\u8981

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306b\u8a18\u8f09\u3055\u308c\u3066\u308b\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306f\u5e38\u306b\u6700\u65b0\u72b6\u614b\u3092\u4fdd\u3064\u3053\u3068\u304c\u671b\u307e\u3057\u3044\u305f\u3081\u30011\u30a8\u30dd\u30c3\u30af\u306b1\u56de\u306f\u66f8\u304d\u63db\u3048\u308b\u3053\u3068\u3092\u63a8\u5968\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\n./relay-topology_pull.sh\n

\u30d2\u30f3\u30c8

relay-topology_pull.sh\u3092\u5b9f\u884c\u3059\u308b\u3068\u65b0\u3057\u3044\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb(mainnet-topology.json)\u3092\u751f\u6210\u3057\u307e\u3059\u3002 \u65b0\u3057\u3044\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306f\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u5f8c\u306b\u6709\u52b9\u306b\u306a\u308a\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
sudo systemctl reload-or-restart cardano-node\n

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067gLiveView \u3092\u78ba\u8a8d

\u30ce\u30fc\u30c9\u304c\u540c\u671f\u3059\u308b\u304b\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME/scripts\n./gLiveView.sh\n
"},{"location":"operation/start-guide/#_11","title":"\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u7b97\u51fa","text":"

\u6982\u8981

\u6b21\u306e\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u30a8\u30dd\u30c3\u30af\u7d42\u4e86\u307e\u3067\u306b\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b\u3053\u3068\u306b\u3088\u3063\u3066\u7b97\u51fa\u3055\u308c\u3001\u628a\u63e1\u3067\u304d\u307e\u3059\u3002(1.5\u65e5\u524d\u304b\u3089\u7b97\u51fa\u53ef\u80fd) \u30a8\u30dd\u30c3\u30af\u304c\u5207\u308a\u66ff\u308f\u3063\u305f\u5f8c\u3067\u3082\u7b97\u51fa\u3067\u304d\u307e\u3059\u304c\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u5206\u304b\u3089\u306a\u3044\u72b6\u614b\u3067\u306e\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u3068\u306a\u308a\u3001\u30ea\u30b9\u30af\u3092\u4f34\u3046\u305f\u3081\u4e8b\u524d\u306b\u628a\u63e1\u3059\u308b\u3053\u3068\u3092\u63a8\u5968\u3057\u307e\u3059\u3002

  • 10-9. \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u7b97\u51fa\u3059\u308b\u3078\u79fb\u52d5\u3059\u308b
"},{"location":"operation/tool/","title":"SPO JAPAN GUILD TOOL","text":"

\u6700\u7d42\u66f4\u65b0\u65e5\uff1a2024/1/30 v3.7.1

\u4e3b\u306a\u6a5f\u80fd

  • payment.addr\u6b8b\u9ad8\u7167\u4f1a
  • \u5831\u916c\u5f15\u304d\u51fa\u3057
  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u53ef\u80fd\u53ef\u5426\u78ba\u8a8d
  • env\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u5207\u308a\u66ff\u3048
  • Catalyst\u6709\u6a29\u8005\u767b\u9332

"},{"location":"operation/tool/#_1","title":"\u8a2d\u5b9a","text":"

\u30b9\u30af\u30ea\u30d7\u30c8\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

cd $NODE_HOME/scripts\nwget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/sjgtool.sh -O sjgtool.sh\nchmod 755 sjgtool.sh\n

env\u30d5\u30a1\u30a4\u30eb\u4fee\u6b63

\u305d\u306e\u307e\u307e\u5168\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sed -i $NODE_HOME/scripts/env \\\n    -e '1,73s!#WALLET_PAY_ADDR_FILENAME=\"payment.addr\"!WALLET_PAY_ADDR_FILENAME=\"payment.addr\"!' \\\n    -e '1,73s!#WALLET_STAKE_ADDR_FILENAME=\"reward.addr\"!WALLET_STAKE_ADDR_FILENAME=\"stake.addr\"!' \\\n    -e '1,73s!#POOL_HOTKEY_VK_FILENAME=\"hot.vkey\"!POOL_HOTKEY_VK_FILENAME=\"kes.vkey\"!' \\\n    -e '1,73s!#POOL_HOTKEY_SK_FILENAME=\"hot.skey\"!POOL_HOTKEY_SK_FILENAME=\"kes.skey\"!' \\\n    -e '1,73s!#POOL_COLDKEY_VK_FILENAME=\"cold.vkey\"!POOL_COLDKEY_VK_FILENAME=\"node.vkey\"!' \\\n    -e '1,73s!#POOL_COLDKEY_SK_FILENAME=\"cold.skey\"!POOL_COLDKEY_SK_FILENAME=\"node.skey\"!' \\\n    -e '1,73s!#POOL_OPCERT_COUNTER_FILENAME=\"cold.counter\"!POOL_OPCERT_COUNTER_FILENAME=\"node.counter\"!' \\\n    -e '1,73s!#POOL_OPCERT_FILENAME=\"op.cert\"!POOL_OPCERT_FILENAME=\"node.cert\"!' \\\n    -e '1,73s!#POOL_VRF_SK_FILENAME=\"vrf.skey\"!POOL_VRF_SK_FILENAME=\"vrf.skey\"!'\n

\u5404\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u72ec\u81ea\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u5909\u66f4\u3057\u3066\u3044\u308b\u5834\u5408

~/cnode/scripts/env\u30d5\u30a1\u30a4\u30eb\u5185\u306e\u4ee5\u4e0b\u306e\u5909\u6570\u306b\u5bfe\u3057\u3001\u5148\u982d\u306e#\u3092\u524a\u9664\u3057\u3054\u81ea\u8eab\u306e\u74b0\u5883\u306b\u5408\u308f\u305b\u3066\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

WALLET_PAY_ADDR_FILENAME=\"payment.addr\" WALLET_STAKE_ADDR_FILENAME=\"stake.addr\" POOL_HOTKEY_VK_FILENAME=\"kes.vkey\" POOL_OPCERT_FILENAME=\"node.cert\" POOL_VRF_SK_FILENAME=\"vrf.skey\" POOL_OPCERT_COUNTER_FILENAME=\"node.counter\" POOL_OPCERT_FILENAME=\"node.cert POOL_VRF_SK_FILENAME=\"vrf.skey

\u30b9\u30af\u30ea\u30d7\u30c8\u3078\u306e\u30d1\u30b9\u3092\u901a\u3057\u3001\u4efb\u610f\u306e\u5358\u8a9e\u3067\u8d77\u52d5\u51fa\u6765\u308b\u3088\u3046\u306b\u3059\u308b

echo alias gtool=\"'cd $NODE_HOME/scripts; ./sjgtool.sh'\" >> $HOME/.bashrc\nsource $HOME/.bashrc\n

TOOL\u3092\u5b9f\u884c\u3059\u308b

gtool\n

\u65e2\u77e5\u306e\u4e0d\u5177\u5408

  • [2] \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af

1.\u5bfe\u8c61\u30d7\u30fc\u30eb\u3001\u30d7\u30fc\u30ebID\u304cnull\u306b\u306a\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002 2.\u30a8\u30dd\u30c3\u30af\u5207\u308a\u66ff\u308f\u308a\u5f8c\u3001\u534a\u65e5\uff5e1\u65e5\u307e\u3067\u306f\u6709\u52b9\u30b9\u30c6\u30fc\u30af\u304c0ADA\u306b\u306a\u308a\u307e\u3059\u3002

\u4e0a\u8a18\u306e\u4e0d\u5177\u5408\u306f\u3001\u30c1\u30a7\u30fc\u30f3\u30c7\u30fc\u30bf\u53d6\u5f97\u7528API\u306e\u65e2\u77e5\u306e\u4e0d\u5177\u5408\u306b\u3088\u308b\u3082\u306e\u3067\u3001\u73fe\u5728\u4fee\u6b63\u4f9d\u983c\u4e2d\u3067\u3059\u3002 \u3082\u3057\u3053\u306e\u9805\u76ee\u3067NG\u304c\u51fa\u305f\u5834\u5408\u306f\u3001\u30c7\u30a3\u30b9\u30b3\u30fc\u30c9\u3067\u3054\u8cea\u554f\u304f\u3060\u3055\u3044\u3002

\u307e\u305f\u3001\u305d\u306e\u4ed6\u30d0\u30b0\u3092\u767a\u898b\u3057\u305f\u5834\u5408\u306fGithub\u3067issue\u3092\u63d0\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/tool/#_2","title":"\u66f4\u65b0\u5c65\u6b74","text":""},{"location":"operation/tool/#371","title":"3.7.1","text":"
* \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af\u3000\u8a93\u7d04\u30c1\u30a7\u30c3\u30af\u5224\u5b9a\u4fee\u6b63\n   (payment.addr + stake.addr\u5831\u916c\u5408\u8a08)\n* Pledge\u5909\u66f4\u6642\u306e\u6709\u52b9\u30a8\u30dd\u30c3\u30af\u30c1\u30a7\u30c3\u30af\u5c0e\u5165\n
"},{"location":"operation/tool/#370","title":"3.7.0","text":"
* CLI 8.17.0.0\u5bfe\u5fdc\n* \u30c7\u30a3\u30b9\u30af\u7a7a\u304d\u5bb9\u91cf\u3068DB\u5bb9\u91cf\u8868\u793a\u8ffd\u52a0\n
"},{"location":"operation/tool/#364","title":"3.6.4","text":"
* gLiveView1.28.x\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u6a5f\u80fd\n* \u30d7\u30fc\u30ebID\u30d5\u30a1\u30a4\u30eb\u540d\u5909\u66f4  \n\u3000stakepoolid_hex \u2192 pool.id  \n\u3000stakepoolid_bech32 \u2192 pool.id-bech32\n
"},{"location":"operation/tool/#363","title":"3.6.3","text":"
* Catalyst\u6709\u6a29\u8005\u767b\u9332\u6a5f\u80fd\u3000payment.addr\u30a8\u30e9\u30fc\u4fee\u6b63\n
"},{"location":"operation/tool/#362","title":"3.6.2","text":"
* Catalyst\u6709\u6a29\u8005\u767b\u9332\u6a5f\u80fd\u3000\u8868\u793a\u6587\u8a00\u4fee\u6b63\n
"},{"location":"operation/tool/#360","title":"3.6.0","text":"
* Catalyst\u6709\u6a29\u8005\u767b\u9332\u6a5f\u80fd\u3000\u5b9f\u88c5\n\u3000payment.addr\u306eADA\u3092Catalyst Voting\u30d1\u30ef\u30fc\u306b\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002\n
"},{"location":"operation/tool/#351","title":"3.5.1","text":"
* SPO\u6295\u7968\u6a5f\u80fd\n\u3000cardano-cli 8.0.0-untested\u4f7f\u7528\u6642\u3001Tx\u304c\u4f5c\u6210\u3055\u308c\u306a\u3044\u4e0d\u5177\u5408\u3092\u89e3\u6d88\n
"},{"location":"operation/tool/#350","title":"3.5.0","text":"
* SPO\u6295\u7968\u6a5f\u80fd\u5b9f\u88c5\n\u3000\u7c21\u6613\u30e1\u30c3\u30bb\u30fc\u30b8\u6dfb\u4ed8\u53ef\u80fd\n
"},{"location":"operation/tool/#346","title":"3.4.6","text":"
* \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af\n    * \u30e1\u30bf\u30c7\u30fc\u30bf\u30cf\u30c3\u30b7\u30e5\u30c1\u30a7\u30c3\u30af\u8ffd\u52a0\n    * PeerIn\u30ab\u30a6\u30f3\u30c8\u304b\u3089127.0.0.1\u3092\u9664\u5916\n* Preview\u30cd\u30c3\u30c8\u30ef\u30fc\u30afTx\u78ba\u8a8d\u30ea\u30f3\u30af\u3092CardanoScan\u3078\u5909\u66f4\n
"},{"location":"operation/tool/#344","title":"3.4.4","text":"
* Preview / PreProd \u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u5bfe\u5fdc\uff08env\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u5fc5\u9808\uff09\n* \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30c1\u30a7\u30c3\u30af\u7dcf\u5408\u5224\u5b9a\u5c0e\u5165\n
"},{"location":"operation/tool/#343","title":"3.4.3","text":"
* \u8efd\u5fae\u306a\u4fee\u6b63\n
"},{"location":"operation/tool/#342","title":"3.4.2","text":"
* 364\u7279\u5225\u5bfe\u5fdc\u524a\u9664\n* env\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30c1\u30a7\u30c3\u30af\u30d5\u30e9\u30b0\u5207\u66ff\u6a5f\u80fd\u8ffd\u52a0\n* \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u9001\u4fe1\u5f8c\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u78ba\u8a8dURL\u3092\u8868\u793a\n
"},{"location":"operation/tool/#331","title":"3.3.1","text":"
* 364\u30a8\u30dd\u30c3\u30af\u7279\u5225\u5bfe\u5fdc cncli.sh\u30d1\u30c3\u30c1\u9069\u7528\u8ffd\u52a0\n
"},{"location":"operation/tool/#330","title":"3.3.0","text":"
* \u5831\u916c/\u8cc7\u91d1\u51fa\u91d1\u3000\u4efb\u610f\u30a2\u30c9\u30ec\u30b9\u51fa\u91d1ADA Handle\u306b\u5bfe\u5fdc\n
"},{"location":"operation/tool/#321","title":"3.2.1","text":"
* \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30b3\u30de\u30f3\u30c9\u3092\u4fee\u6b63\n
"},{"location":"operation/tool/#320","title":"3.2.0","text":"
* KES\u66f4\u65b0\u6642\u306e\u30ab\u30a6\u30f3\u30bf\u30fc\u30d5\u30a1\u30a4\u30eb\u30c1\u30a7\u30c3\u30af\u30fb\u4f5c\u6210\u624b\u9806\u8ffd\u52a0\n* \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af KES\u30d5\u30a1\u30a4\u30eb\u30c1\u30a7\u30c3\u30af\u30eb\u30fc\u30eb\u5909\u66f4\n
"},{"location":"operation/tool/#310","title":"3.1.0","text":"
* KES\u66f4\u65b0\u6642\u306enode.cert\u30d0\u30c3\u30af\u30a2\u30c3\u30d7/\u524a\u9664\u8ffd\u52a0\n
"},{"location":"operation/tool/#300","title":"3.0.0","text":"
  • KES\u66f4\u65b0\u6a5f\u80fd\u8ffd\u52a0

\u3053\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u306b\u4f34\u3044\u3001env\u30d5\u30a1\u30a4\u30eb\u306e\u4fee\u6b63\u304c\u5fc5\u8981\u3068\u306a\u308a\u307e\u3059\u3002 v2.x.x\u4ee5\u4e0a\u3092\u3059\u3067\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u3066\u3001\u30d7\u30fc\u30eb\u306eKES\u79d8\u5bc6\u9375\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u304ckes.skey\u306e\u5834\u5408\u306f\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u30921\u56de\u3060\u3051\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u9055\u3046\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u3054\u5229\u7528\u306e\u5834\u5408\u306f\u4efb\u610f\u306b\u66f8\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044\u3002

sed -i $NODE_HOME/scripts/env \\\n-e '1,73s!#POOL_HOTKEY_SK_FILENAME=\"hot.skey\"!POOL_HOTKEY_SK_FILENAME=\"kes.skey\"!'\n

"},{"location":"operation/tool/#210","title":"2.1.0","text":"
  • DdzF\u30a2\u30c9\u30ec\u30b9\u3078\u306e\u5831\u916c/\u8cc7\u91d1\u51fa\u91d1\u3092\u8a31\u53ef
  • payment.addr\u51fa\u91d1\u6642\u3001\u51fa\u91d1\u984d\u8868\u793a\u5358\u4f4d\u30d0\u30b0\u3092\u4fee\u6b63
"},{"location":"operation/transfer/","title":"\u30b5\u30fc\u30d0\u30fc\u9593\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001","text":"

\u30e1\u30ea\u30c3\u30c8

\u8907\u6570\u53f0\u306e\u30b5\u30fc\u30d0\u30fc\u304c\u3042\u308b\u5834\u5408\u306b\u3001\u4ee5\u4e0b\u306e\u51e6\u7406\u3092\u884c\u3046\u3053\u3068\u3067\u30d3\u30eb\u30c9\u6642\u9593\u306e\u77ed\u7e2e\u3084\u30ce\u30fc\u30c9\u306e\u30c0\u30a6\u30f3\u30bf\u30a4\u30e0\u3092\u6291\u3048\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002

\u30c7\u30e1\u30ea\u30c3\u30c8

  • RSYNC+SSH\u3092\u5229\u7528\u3057\u305f\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u65b9\u6cd5\u306f\u3001\u8ee2\u9001\u5143\u30fb\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u306e\u30c7\u30a3\u30b9\u30af\u7a7a\u304d\u5bb9\u91cf\u304c150GB\u4ee5\u4e0a\u5fc5\u8981\u3068\u306a\u308a\u307e\u3059\u3002

\u306f\u3058\u3081\u306b

  • RSYNC\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u3001\u6700\u521d\u306b\u4e8b\u524d\u8a2d\u5b9a\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044
"},{"location":"operation/transfer/#1-nodecli","title":"1. \u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb(node/cli)\u8ee2\u9001\u306e\u5834\u5408","text":""},{"location":"operation/transfer/#1-2","title":"1-2.\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u4f5c\u696d","text":"\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u8ee2\u9001\u30d5\u30a9\u30eb\u30c0\u7528\u306b\u30b3\u30d4\u30fc\u3059\u308b

mkdir $NODE_HOME/Transfer\ncp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name \"cardano-cli\") $NODE_HOME/Transfer/cardano-cli\ncp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name \"cardano-node\") $NODE_HOME/Transfer/cardano-node\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

$NODE_HOME/Transfer/cardano-cli version\n$NODE_HOME/Transfer/cardano-node version\n

\u5e0c\u671b\u3059\u308b\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u306a\u3063\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

"},{"location":"operation/transfer/#1-2_1","title":"1-2.\u8ee2\u9001\u5143\u304b\u3089\u8ee2\u9001\u5148\u3078\u8ee2\u9001\u3059\u308b","text":"

\u5909\u6570for\u306b\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u3092\u4ee3\u5165\u3059\u308b

\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc

\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u3092\u6307\u5b9a\u3059\u308b

for=xxxx\n

\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u306f\u3001\u4e8b\u524d\u8a2d\u5b9a\u306e 1-2.SSH\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210 \u3067\u8a2d\u5b9a\u3057\u305f\u8ee2\u9001\u5148Host\u540d(\u30a8\u30a4\u30ea\u30a2\u30b9)\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u3092\u8ee2\u9001\u3059\u308b

rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-cli $for::Server/cardano-cli\n

\u8ee2\u9001\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u5f85\u3064

rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-node $for::Server/cardano-node\n

\u8ee2\u9001\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u5f85\u3064

"},{"location":"operation/transfer/#1-3","title":"1-3.\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u4f5c\u696d","text":"\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc

\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop cardano-node\n

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u30fc\u3078\u30b3\u30d4\u30fc\u3059\u308b

sudo cp $NODE_HOME/cardano-cli /usr/local/bin/cardano-cli\n
sudo cp $NODE_HOME/cardano-node /usr/local/bin/cardano-node\n
\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d
cardano-cli version\ncardano-node version\n

\u5e0c\u671b\u3059\u308b\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u306a\u3063\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

\u30ce\u30fc\u30c9\u3092\u8d77\u52d5\u3059\u308b

sudo systemctl start cardano-node\n

\u30d2\u30f3\u30c8

  • GliveView\u3067\u30ce\u30fc\u30c9\u72b6\u6cc1\u3092\u78ba\u8a8d\u3059\u308b
  • Syncing 100%\u304cTip(diff): ** :)\u3068\u306a\u308b\u307e\u3067\u5f85\u3064
"},{"location":"operation/transfer/#2db","title":"2.DB\u30d5\u30a9\u30eb\u30c0\u8ee2\u9001\u306e\u5834\u5408","text":""},{"location":"operation/transfer/#2-1","title":"2-1.\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc\u4f5c\u696d","text":"

\u5bb9\u91cf\u78ba\u8a8d \u8ee2\u9001\u5143\u30fb\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u4e21\u65b9\u3067\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

df -h /usr\n
Avail\u304c180GB\u4ee5\u4e0a\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc

\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop cardano-node\n

DB\u30d5\u30a9\u30eb\u30c0\u3092\u5727\u7e2e\u3059\u308b

\u65b0\u3057\u3044TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u958b\u304f

tmux new -s tar\n
\u5727\u7e2e\u3059\u308b
tar cvzf $NODE_HOME/Transfer/cardano-db.tar.gz -C $NODE_HOME db\n

\u5727\u7e2e\u304c\u7d42\u4e86\u3057\u305f\u3089TMUX\u3092\u9589\u3058\u308b

exit\n

\u30ce\u30fc\u30c9\u3092\u30b9\u30bf\u30fc\u30c8\u3059\u308b

sudo systemctl start cardano-node\n

"},{"location":"operation/transfer/#2-2","title":"2-2.\u8ee2\u9001\u5143\u304b\u3089\u8ee2\u9001\u5148\u3078\u8ee2\u9001\u3059\u308b","text":"\u8ee2\u9001\u5143\u30b5\u30fc\u30d0\u30fc

\u65b0\u3057\u3044TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u958b\u304f

tmux new -s rsync\n

\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u3092\u6307\u5b9a\u3059\u308b\u3002\u5909\u6570for\u306b\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u3092\u4ee3\u5165\u3059\u308b

for=xxxx\n

\u8ee2\u9001\u5148\u30a8\u30a4\u30ea\u30a2\u30b9\u306f\u3001\u4e8b\u524d\u8a2d\u5b9a\u306e 1-2.SSH\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210 \u3067\u8a2d\u5b9a\u3057\u305f\u8ee2\u9001\u5148Host\u540d(\u30a8\u30a4\u30ea\u30a2\u30b9)\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002

\u5727\u7e2e\u3055\u308c\u305fDB\u3092\u8ee2\u9001\u3059\u308b

rsync -P --rsh=ssh $NODE_HOME/Transfer/cardano-db.tar.gz $for::Server/cardano-db.tar.gz\n

\u8ee2\u9001\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u5f85\u3064

\u8ee2\u9001\u304c\u7d42\u4e86\u3057\u305f\u3089TMUX\u3092\u9589\u3058\u308b

exit\n

"},{"location":"operation/transfer/#2-3","title":"2-3.\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc\u4f5c\u696d","text":"

\u65b0\u3057\u3044TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u958b\u304f

tmux new -s tar\n

\u8ee2\u9001\u5148\u30b5\u30fc\u30d0\u30fc

SSD\u306e\u7a7a\u304d\u5bb9\u91cf\u3092\u518d\u78ba\u8a8d\u3059\u308b

df -h /usr\n
Avail\u304c100GB\u4ee5\u4e0a\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

DB\u3092\u89e3\u51cd\u3059\u308b

mkdir $NODE_HOME/temp\ntar -xzvf $NODE_HOME/cardano-db.tar.gz -C $NODE_HOME/temp/\n

DB\u306e\u89e3\u51cd\u304c\u7d42\u308f\u308b\u307e\u3067\u5f85\u3061\u307e\u3059

\u89e3\u51cd\u304c\u7d42\u308f\u3063\u305f\u3089TMUX\u3092\u9589\u3058\u308b

exit\n

\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop cardano-node\n

DB\u30d5\u30a9\u30eb\u30c0\u3092\u5165\u308c\u66ff\u3048\u308b

mv $NODE_HOME/db $NODE_HOME/db_134\nmv $NODE_HOME/temp/db $NODE_HOME/db\n

\u30ce\u30fc\u30c9\u3092\u8d77\u52d5\u3059\u308b

sudo systemctl start cardano-node\n

\u30d2\u30f3\u30c8

  • GliveView\u3067\u30ce\u30fc\u30c9\u72b6\u6cc1\u3092\u78ba\u8a8d\u3059\u308b
  • Syncing 100%\u304cTip(diff): ** :)\u3068\u306a\u308b\u307e\u3067\u5f85\u3064

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u79fb\u52d5\u3059\u308b

cd $HOME/git\nrm -rf cardano-node-old/\nmv $HOME/git/cardano-node/ $HOME/git/cardano-node-old/\nmkdir cardano-node\nmv $NODE_HOME/cardano-cli $HOME/git/cardano-node/\nmv $NODE_HOME/cardano-node $HOME/git/cardano-node/\n

\u78ba\u8a8d

\u30ce\u30fc\u30c9\u306e\u540c\u671f\u304c\u6210\u529f\u3057\u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u6210\u529f\u3057\u6570\u30a8\u30dd\u30c3\u30af\u69d8\u5b50\u3092\u898b\u305f\u3042\u3068\u3001\u8ee2\u9001\u7528\u30d5\u30a1\u30a4\u30eb\u30fb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7DB\u3092\u524a\u9664\u3057\u3066\u304f\u3060\u3055\u3044

\u8ee2\u9001\u5143\u8ee2\u9001\u5148
rm -rf $NODE_HOME/Transfer\n
rm -rf $NODE_HOME/db_134\nrm $NODE_HOME/1.35.3-db.tar.gz\n
"},{"location":"operation/ubuntu22/","title":"Ubuntu20.04\u219222.04\u4efb\u610f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u30de\u30cb\u30e5\u30a2\u30eb","text":"

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u524d\u306e\u78ba\u8a8d\u4e8b\u9805

  • 2023\u5e746\u6708\u6642\u70b9\u306b\u304a\u3044\u3066\u3001\u3053\u306e\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306f\u4efb\u610f\u3067\u3059\u3002
  • 20.04LTS\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30b5\u30dd\u30fc\u30c8\u306f2025\u5e744\u6708\u307e\u3067\u6709\u52b9\u3067\u3059\u3002
  • IOG\u304b\u3089\u306f\u6b63\u5f0f\u306a22.04\u5bfe\u5fdc\u30a2\u30ca\u30a6\u30f3\u30b9\u306f\u307e\u3060\u3054\u3056\u3044\u307e\u305b\u3093\u304c\u3001\u5185\u90e8\u958b\u767a\u30fb\u691c\u8a3c\u3067\u306f22.04\u304c\u4f7f\u308f\u308c\u3066\u304a\u308a\u307e\u3059\u3002
  • 22.04\u3067\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30fb\u5b89\u5b9a\u7a3c\u50cd\u78ba\u8a8d\u6e08\u307f\u3067\u3059\u3002
  • \u4f5c\u696d\u524d\u306b\u4e00\u901a\u308a\u719f\u8aad\u3057\u3001\u4f5c\u696d\u30d5\u30ed\u30fc\u3092\u7406\u89e3\u3057\u3066\u4e0b\u3055\u3044\u3002
  • OS\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306e\u305f\u3081\u3001\u4f5c\u696d\u306f\u614e\u91cd\u306b\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
"},{"location":"operation/ubuntu22/#1","title":"1.\u4e8b\u524d\u6e96\u5099","text":""},{"location":"operation/ubuntu22/#1-1","title":"1-1.\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210","text":"

\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8\u306e\u4f5c\u6210

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u524d\u306b\u5fc5\u305a\u3001VPS\u306e\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u753b\u9762\u304b\u3089\u73fe\u6642\u70b9\u306e\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8(\u30d0\u30c3\u30af\u30a2\u30c3\u30d7)\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u4e07\u4e00\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306b\u5931\u6557\u3057\u305f\u5834\u5408\u3001\u7d20\u65e9\u304f\u5fa9\u65e7\u3067\u304d\u307e\u3059\u3002

"},{"location":"operation/ubuntu22/#1-2ssh","title":"1-2.SSH\u9375\u306e\u7a2e\u985e\u3092\u78ba\u8a8d\u3059\u308b","text":"

SSH\u63a5\u7d9a\u7528\u306e\u30ed\u30fc\u30ab\u30eb\u30d1\u30bd\u30b3\u30f3\u306b\u4fdd\u5b58\u3055\u308c\u3066\u3044\u308b\u3001SSH\u79d8\u5bc6\u9375\u30d5\u30a1\u30a4\u30eb\u306e\u7a2e\u985e\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • id_rsa
  • ssh_ed25519

\u306e\u3069\u3061\u3089\u304b

"},{"location":"operation/ubuntu22/#1-3ssh","title":"1-3.SSH\u30bf\u30fc\u30df\u30ca\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3\u6700\u65b0\u5316","text":"

Windows\u3067R-login\u3092\u3054\u5229\u7528\u306e\u5834\u5408\u306f\u3001RLogin-2.28.2\u3092\u4f7f\u7528\u3057\u3066\u4e0b\u3055\u3044\u3002

"},{"location":"operation/ubuntu22/#1-4","title":"1-4.\u4f5c\u696d\u5bfe\u8c61\u30b5\u30fc\u30d0\u30ed\u30b0\u30a4\u30f3","text":"

\u63a5\u7d9a\u65b9\u6cd5

1-4\uff5e1-8\u306f\u901a\u5e38\u306eSSH\u63a5\u7d9a\u3067\u4f5c\u696d\u3059\u308b

id_rsa\u306e\u5834\u5408ssh_ed25519\u306e\u5834\u5408

22.04\u3067\u306fRSA\u65b9\u5f0f\u304c\u7121\u52b9\u3068\u306a\u3063\u3066\u304a\u308a\u3001\u65b0\u3057\u3044\u9375\u30da\u30a2(ed25519\u6697\u53f7\u65b9\u5f0f)\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

\u30da\u30a2\u9375\u306e\u4f5c\u6210

ssh-keygen -t ed25519 -N '' -C ssh_connect -f ~/.ssh/ssh_ed25519\n

ssh_ed25519\uff08\u79d8\u5bc6\u9375\uff09\u3068ssh_ed25519.pub\uff08\u516c\u958b\u9375\uff09\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u304c\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b\u3002

cd ~/.ssh\nls\n

\u516c\u958b\u9375\u3092\u8a8d\u8a3c\u30d5\u30a1\u30a4\u30eb\u306b\u66f8\u304d\u8fbc\u3080

cat ssh_ed25519.pub >> authorized_keys\n

SSH\u9375\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

  1. R-login\u306e\u5834\u5408\u306f\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u958b\u304f
  2. \u5de6\u5074\u30a6\u30a3\u30f3\u30c9\u30a6(\u30ed\u30fc\u30ab\u30eb\u5074)\u306f\u4efb\u610f\u306e\u968e\u5c64\u306b\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3059\u308b\u3002
  3. \u53f3\u5074\u30a6\u30a3\u30f3\u30c9\u30a6(\u30b5\u30fc\u30d0\u5074)\u306f\u300c.ssh\u300d\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e\u3059\u308b
  4. \u53f3\u5074\u30a6\u30a3\u30f3\u30c9\u30a6\u304b\u3089\u3001ssh_ed25519\u3068ssh_ed25519.pub\u306e\u4e0a\u3067\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066 \u300c\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u300d\u3092\u9078\u629e\u3059\u308b
  5. \u4e00\u65e6\u30b5\u30fc\u30d0\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3059\u308b
  6. R-Login\u306e\u30b5\u30fc\u30d0\u63a5\u7d9a\u7de8\u96c6\u753b\u9762\u3092\u958b\u304d\u3001\u300cSSH\u8a8d\u8a3c\u9375\u300d\u3092\u30af\u30ea\u30c3\u30af\u30574\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fssh_ed25519\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u3076
  7. \u30b5\u30fc\u30d0\u3078\u63a5\u7d9a\u3059\u308b

\u203b4\u3067\u30ed\u30fc\u30ab\u30eb\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fSSH\u9375\u30da\u30a2\u306f\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u3092\u30aa\u30b9\u30b9\u30e1\u3057\u307e\u3059\u3002

\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u3001\u30b5\u30fc\u30d0\u30fc\u5185\u306e\u9375\u3092\u524a\u9664\u3059\u308b

rm ~/.ssh/ssh_ed25519\nrm ~/.ssh/ssh_ed25519.pub\n

Ubuntu22.04\u306b\u5bfe\u5fdc\u3057\u305f\u6697\u53f7\u65b9\u5f0f\u3067\u3059\u3002\u6b21\u306e\u9805\u76ee\u306b\u79fb\u52d5\u3057\u3066\u4e0b\u3055\u3044\u3002

"},{"location":"operation/ubuntu22/#1-5","title":"1-5.\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3059\u308b","text":"
sudo systemctl stop cardano-node\n

\u81ea\u52d5\u8d77\u52d5\u3092\u4e00\u65e6\u505c\u6b62\u3059\u308b

sudo systemctl disable cardano-node\n

"},{"location":"operation/ubuntu22/#1-6ubuntu","title":"1-6.Ubuntu\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d","text":"

\u73fe\u5728\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b

cat /etc/os-release | grep \"VERSION=\"\n

VERSION=\"20.04.x LTS (Focal Fossa)\"\u3000x\u306e\u6570\u5b57\u306f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u6642\u671f\u306b\u3088\u3063\u3066\u5909\u308f\u308a\u307e\u3059

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u53ef\u80fd\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b

sudo do-release-upgrade -c | grep \"New release\"\n

New release '22.04.x LTS' available.\u3000x\u306e\u6570\u5b57\u306f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u6642\u671f\u306b\u3088\u3063\u3066\u5909\u308f\u308a\u307e\u3059

"},{"location":"operation/ubuntu22/#1-7","title":"1-7.\u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"
sudo apt full-upgrade -y\n
"},{"location":"operation/ubuntu22/#1-8","title":"1-8.\u30d1\u30c3\u30b1\u30fc\u30b8\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
sudo apt install update-manager-core\n
"},{"location":"operation/ubuntu22/#1-9","title":"1-9.\u30b7\u30b9\u30c6\u30e0\u3092\u518d\u8d77\u52d5","text":"
sudo reboot\n
"},{"location":"operation/ubuntu22/#2ubuntu","title":"2.Ubuntu\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9","text":"

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306e\u6ce8\u610f\u70b9

Ubuntu22.04\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9(\u4ee5\u4e0b\u306e\u4f5c\u696d)\u306b\u304a\u3044\u3066\u3001SSH\u63a5\u7d9a\u3067\u306e\u4f5c\u696d\u306f\u4e0d\u610f\u306a\u5207\u65ad\u304c\u767a\u751f\u3057\u305f\u5834\u5408\u306b\u5fa9\u65e7\u304c\u56f0\u96e3\u306b\u306a\u308b\u305f\u3081\u975e\u63a8\u5968\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002

\u305d\u306e\u305f\u3081\u3001\u5951\u7d04\u4e8b\u696d\u8005(VPS)\u306e\u30de\u30a4\u30da\u30fc\u30b8\u307e\u305f\u306f\u30b5\u30fc\u30d0\u30d1\u30cd\u30eb\u306b\u4ed8\u968f\u3057\u3066\u3044\u308b\u30b3\u30f3\u30bd\u30fc\u30eb\u753b\u9762(VNC\u307e\u305f\u306fKVN\u306a\u3069)\u304b\u3089\u306e\u4f5c\u696d\u3092\u30aa\u30b9\u30b9\u30e1\u3057\u307e\u3059\u3002

\u305f\u3060\u3057\u4ee5\u4e0b\u306e\u70b9\u306b\u3054\u4e86\u627f\u9802\u3051\u308b\u5834\u5408\u306fSSH\u63a5\u7d9a\u3067\u4f5c\u696d\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002

  • \u4e8b\u524d\u306b\u30b9\u30ca\u30c3\u30d7\u30b7\u30e7\u30c3\u30c8(\u30d0\u30c3\u30af\u30a2\u30c3\u30d7)\u4f5c\u6210\u304c\u53ef\u80fd\u306a\u65b9
  • \u4e0d\u610f\u306aSSH\u5207\u65ad\u3067\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u4e2d\u65ad\u3057\u3066\u3082\u3054\u81ea\u8eab\u3067\u5fa9\u65e7\u51fa\u6765\u308b\u65b9

SSH\u3067\u4f5c\u696d\u3059\u308b\u5834\u5408

  • \u4e88\u5099\u306eSSH\u30dd\u30fc\u30c8\u3092\u958b\u653e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u203b\u305f\u3060\u3057AWS\u3084IONOS\u306a\u3069\u3001VPS\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u753b\u9762\u304b\u3089\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u8a2d\u5b9a\u3059\u308b\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u306f\u5b9f\u884c\u305b\u305aVPS\u7ba1\u7406\u753b\u9762\u304b\u3089\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    sudo ufw allow 1022/tcp\nsudo ufw reload\n

  • R-login\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306f\u3001\u4e0d\u610f\u306a\u5207\u65ad\u3092\u9632\u3050\u305f\u3081\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3092\u884c\u3063\u3066\u4e0b\u3055\u3044\u3002

\u300c\u30d5\u30a1\u30a4\u30eb\u300d\u2192\u300c\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u300d\u2192 \u63a5\u7d9a\u5148\u53f3\u30af\u30ea\u30c3\u30af\u3057\u300c\u63a5\u7d9a\u3092\u7de8\u96c6\u3059\u308b\u300d\u2192\u300c\u30d7\u30ed\u30c8\u30b3\u30eb\u300d\u2192 SSH\u67a0\u306e\u300cKeepAlve\u30d1\u30b1\u30c3\u30c8\u9001\u4fe1\u9593\u9694(sec)\u300d\u306b\u30c1\u30a7\u30c3\u30af\u3092\u5165\u308c\u3001\u7a7a\u6b04\u306b20\u3092\u5165\u529b\u3059\u308b\u3002

"},{"location":"operation/ubuntu22/#2-1","title":"2-1.\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u5b9f\u884c","text":"

\u63a5\u7d9a\u30d1\u30bf\u30fc\u30f3

  • \u30d1\u30bf\u30fc\u30f31\uff1aVPS\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u753b\u9762\u306e\u30b3\u30f3\u30bd\u30fc\u30eb\u304b\u3089\u63a5\u7d9a\u3059\u308b
  • \u30d1\u30bf\u30fc\u30f32\uff1a\u30ed\u30fc\u30ab\u30ebPC\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u305fVNC\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304b\u3089\u63a5\u7d9a\u3059\u308b(\u4e3b\u306bContabo)
  • \u30d1\u30bf\u30fc\u30f33\uff1a\u3044\u3064\u3082\u901a\u308aSSH\u3067\u63a5\u7d9a\u3059\u308b

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b

sudo do-release-upgrade\n

"},{"location":"operation/ubuntu22/#2-2","title":"2-2.\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u30e1\u30c3\u30bb\u30fc\u30b8","text":"

\u4ee5\u4e0b\u3001\u78ba\u8a8d\u30e1\u30c3\u30bb\u30fc\u30b8\u4f8b\u3067\u3059\u3002\u3054\u5229\u7528\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u3088\u3063\u3066\u8868\u793a\u5185\u5bb9\u304c\u7570\u306a\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002\u8868\u793a\u3055\u308c\u305f\u5185\u5bb9\u3092\u3088\u304f\u8aad\u3093\u3067\u4e0b\u3055\u3044\u3002

SSH\u3067\u4f5c\u696d\u3059\u308b\u5834\u5408

\u30d0\u30c3\u30af\u30a2\u30c3\u30d7SSH\u30dd\u30fc\u30c8\u958b\u653e y \u3092\u5165\u529b\u3057\u3066Enter

Continue running under SSH?\n\nThis session appears to be running under ssh. It is not recommended\nto perform a upgrade over ssh currently because in case of failure it\nis harder to recover.\n\nIf you continue, an additional ssh daemon will be started at port\n'1022'.\nDo you want to continue?\n\nContinue [yN] y      # y \u3092\u5165\u529b\u3057\u3066Enter\n

sshd\u306b1022\u30dd\u30fc\u30c8\u8ffd\u52a0\u306e\u304a\u77e5\u3089\u305b \u305d\u306e\u307e\u307eENTER

Starting additional sshd\n\nTo make recovery in case of failure easier, an additional sshd will\nbe started on port '1022'. If anything goes wrong with the running\nssh you can still connect to the additional one.\nIf you run a firewall, you may need to temporarily open this port. As\nthis is potentially dangerous it's not done automatically. You can\nopen the port with e.g.:\n'iptables -I INPUT -p tcp --dport 1022 -j ACCEPT'\n\nTo continue please press [ENTER]  # ENTER \n

\u30d1\u30c3\u30b1\u30fc\u30b8\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30ea\u30dd\u30b8\u30c8\u30ea\u66f4\u65b0\u3057\u307e\u3059\u304b\uff1f y \u3092\u5165\u529b\u3057\u3066Enter

Updating repository information\n\nNo valid mirror found\n\nWhile scanning your repository information no mirror entry for the\nupgrade was found. This can happen if you run an internal mirror or\nif the mirror information is out of date.\n\nDo you want to rewrite your 'sources.list' file anyway? If you choose\n'Yes' here it will update all 'focal' to 'jammy' entries.\nIf you select 'No' the upgrade will cancel.\n\nContinue [yN] y      # y \u3092\u5165\u529b\u3057\u3066Enter\n

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u958b\u59cb\u3057\u307e\u3059\u304b\uff1f y \u3092\u5165\u529b\u3057\u3066Enter

Do you want to start the upgrade?\n\n\n3 installed packages are no longer supported by Canonical. You can\nstill get support from the community.\n\n5 packages are going to be removed. 117 new packages are going to be\ninstalled. 629 packages are going to be upgraded.\n\nYou have to download a total of 694 M. This download will take about\n2 minutes with a 40Mbit connection and about 18 minutes with a 5Mbit\nconnection.\n\nFetching and installing the upgrade can take several hours. Once the\ndownload has finished, the process cannot be canceled.\n\n Continue [yN]  Details [d] y      # y \u3092\u5165\u529b\u3057\u3066Enter\n

libc6\u306a\u3069\u306e\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u304b\uff1f \u30ab\u30fc\u30bd\u30eb\u30ad\u30fc\u3067YES\u3092\u9078\u629e\u3057\u3066ENTER

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u66f4\u65b0\u306e\u6709\u7121 N \u3092\u5165\u529b\u3057\u3066Enter

Configuration file '/etc/ssh/ssh_config'\n ==> Modified (by you or by a script) since installation.\n ==> Package distributor has shipped an updated version.\n   What would you like to do about it ? Your options are:\n    Y or I : install the package maintainer's version\n    N or O : keep your currently-installed version\n      D : show the differences between the versions\n      Z : start a shell to examine the situation\n The default action is to keep your current version.\n*** ssh_config (Y/I/N/O/D/Z) [default=N] ?  N       # N \u3092\u5165\u529b\u3057\u3066Enter\n

\u6ce8\u610f

  • \u3053\u306e\u7a2e\u985e\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u5fc5\u305a N \u3092\u5165\u529b\u3057\u3066\u3001\u300ckeep your currently-installed version\uff08\u73fe\u5728\u306e\u8a2d\u5b9a\u3092\u7dad\u6301\u3059\u308b\uff09\u300d\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002
  • \u30b5\u30fc\u30d0\u30fc\u306b\u3088\u3063\u3066\u306fssh_config\u4ee5\u5916\u306b\u3082\u540c\u69d8\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002(chrony,opne-ssh,sudoers,sysctl.conf\u306a\u3069) \u3044\u305a\u308c\u3082 N \u300ckeep your currently-installed version\uff08\u73fe\u5728\u306e\u8a2d\u5b9a\u3092\u7dad\u6301\u3059\u308b\uff09\u300d\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002

\u65b0\u3057\u3044\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u51e6\u7406\u65b9\u6cd5\u306b\u3064\u3044\u3066 keep the local version currently installed\uff08\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u306e\u30ed\u30fc\u30ab\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u7dad\u6301\u3059\u308b\uff09\u304c\u9078\u629e\u3055\u308c\u305f\u72b6\u614b\u3067ENTER

\u6ce8\u610f

  • \u3053\u306e\u7a2e\u985e\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u5fc5\u305a \u300ckeep the local version currently installed\uff08\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u306e\u30ed\u30fc\u30ab\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u7dad\u6301\u3059\u308b\uff09\u300d\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002
  • \u30b5\u30fc\u30d0\u30fc\u306b\u3088\u3063\u3066\u306fchrony\u4ee5\u5916\u306b\u3082\u540c\u69d8\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002(sshd\u306a\u3069) \u3044\u305a\u308c\u3082 keep the local version currently installed\uff08\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u307f\u306e\u30ed\u30fc\u30ab\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u7dad\u6301\u3059\u308b\uff09\u300d\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002

\u53e4\u3044\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u524a\u9664\u3057\u307e\u3059\u304b\uff1f y \u3092\u5165\u529b\u3057\u3066Enter

Remove obsolete packages?\n\n\n73 packages are going to be removed.\n\n Continue [yN]  Details [d] y      # y \u3092\u5165\u529b\u3057\u3066Enter\n

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002\u518d\u8d77\u52d5\u3057\u307e\u3059\u304b\uff1f y \u3092\u5165\u529b\u3057\u3066Enter

System upgrade is complete.\n\nRestart required\n\nTo finish the upgrade, a restart is required.\nIf you select 'y' the system will be restarted.\n\nContinue [yN] y      # y \u3092\u5165\u529b\u3057\u3066Enter\n

"},{"location":"operation/ubuntu22/#3ssh","title":"3.\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u78ba\u8a8d(SSH\u63a5\u7d9a)","text":"

\u63a5\u7d9a\u65b9\u6cd5

3~5\u306fSSH\u63a5\u7d9a\u3067\u4f5c\u696d\u3059\u308b

"},{"location":"operation/ubuntu22/#3-1ubuntu","title":"3-1.\u73fe\u5728\u306eUbuntu\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b","text":"
cat /etc/os-release | grep \"VERSION=\" # (1)!\n
  1. 22.04\u306f\u30d6\u30e9\u30b1\u30c3\u30c8\u30da\u30fc\u30b9\u30c8\u30e2\u30fc\u30c9\u304c\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u308b\u305f\u3081\u30b3\u30de\u30f3\u30c9\u30da\u30fc\u30b9\u30c8\u5f8c\u3001ENTER\u3067\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

VERSION=\"22.04.x LTS (Jammy Jellyfish)\"\u3000x\u306e\u6570\u5b57\u306f\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u6642\u671f\u306b\u3088\u3063\u3066\u5909\u308f\u308a\u307e\u3059

"},{"location":"operation/ubuntu22/#3-2off","title":"3-2.\u30d6\u30e9\u30b1\u30c3\u30c8\u30da\u30fc\u30b9\u30c8\u30e2\u30fc\u30c9OFF","text":"
echo \"set enable-bracketed-paste off\" >> ~/.inputrc\n
"},{"location":"operation/ubuntu22/#3-3ssh","title":"3-3.SSH\u518d\u63a5\u7d9a","text":"
exit\n

SSH\u3067\u518d\u63a5\u7d9a\u3059\u308b

"},{"location":"operation/ubuntu22/#4","title":"4.\u4f9d\u5b58\u95a2\u4fc2\u518d\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8

sudo apt update -y && sudo apt upgrade -y\n

\u30ea\u30ec\u30fc\u306e\u5834\u5408BP\u306e\u5834\u5408
sudo apt install needrestart git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y\n

sudo apt install needrestart git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y\n
pip install discordwebhook python-dotenv slackweb\n

\u30c7\u30fc\u30e2\u30f3\u518d\u8d77\u52d5\u81ea\u52d5\u5316

echo \"\\$nrconf{restart} = 'a';\" | sudo tee /etc/needrestart/conf.d/50local.conf\n
echo \"\\$nrconf{blacklist_rc} = [qr(^cardano-node\\\\.service$) => 0,];\" | sudo tee -a /etc/needrestart/conf.d/50local.conf\n

\u81ea\u52d5\u8d77\u52d5\u6709\u52b9\u5316

sudo systemctl enable cardano-node\n

\u30b3\u30f3\u30d1\u30a4\u30eb\u6e08\u307fHaskell\u30d1\u30c3\u30b1\u30fc\u30b8\u524a\u9664

cd ~/.cabal/store\nrm -rf ghc-8.10.7\n

SSH\u3067\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3092\u5b9f\u65bd\u3057\u305f\u5834\u5408

1022\u30dd\u30fc\u30c8\u3092\u524a\u9664\u3059\u308b\uff08AWS\u3084IONOS\u306a\u3069\u306fVPS\u306e\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u753b\u9762\u304b\u3089\uff09

sudo ufw deny 1022/tcp\nsudo ufw reload\n

"},{"location":"operation/ubuntu22/#5","title":"5. \u30ce\u30fc\u30c9\u518d\u30d3\u30eb\u30c9","text":"

\u65e2\u5b58\u306e\u30ce\u30fc\u30c9\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u4f5c\u696d\u5185\u5bb9\u304c\u7570\u306a\u308a\u307e\u3059\u3002

\u65e2\u5b58\u30ce\u30fc\u30c91.35\u7cfb\u306e\u5834\u5408

\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30de\u30cb\u30e5\u30a2\u30eb\u30925\u30686\u4ee5\u5916\u306f\u5168\u3066\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044 (RSYNC\u3092\u4f7f\u7528\u3057\u306a\u3044\u5834\u54083\u306f\u5b9f\u65bd\u4e0d\u8981)

  • 1-4 BP\u306eCNCLI\u304c\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3042\u3063\u3066\u3082\u8d64\u67a0\u3092\u958b\u3044\u3066\u518d\u30d3\u30eb\u30c9\u3057\u3066\u304f\u3060\u3055\u3044

\u65e2\u5b58\u30ce\u30fc\u30c98.1.2\u306e\u5834\u5408

\u30ce\u30fc\u30c9\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30de\u30cb\u30e5\u30a2\u30eb 1-1\u30011-2\u30011-4(BP\u306e\u307f)\u30012-1\u30012-2\u30012-3\u30012-5\u30014(BP\u306e\u307f)

  • 1-2 Cabal\u304c\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3055\u308c\u3066\u307e\u3059\u306e\u3067\u5fc5\u305a\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • 1-4 BP\u306eCNCLI\u304c\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3042\u3063\u3066\u3082\u8d64\u67a0\u3092\u958b\u3044\u3066\u518d\u30d3\u30eb\u30c9\u3057\u3066\u304f\u3060\u3055\u3044
"},{"location":"operation/ubuntu22/#6","title":"6. \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9","text":""},{"location":"operation/ubuntu22/#6-1","title":"6-1. \u4e8b\u524d\u6e96\u5099","text":"
  • 6-1-1.Ubuntu\u3078\u30ed\u30b0\u30a4\u30f3\u3057\u3001\u4e3b\u8981\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30af\u30bb\u30b9\u5236\u9650\u3092\u89e3\u9664\u3059\u308b
cd $NODE_HOME\nchmod 700 payment.vkey\nchmod 700 payment.skey\nchmod 700 stake.vkey\nchmod 700 stake.skey\nchmod 700 stake.addr\nchmod 700 payment.addr\nchmod u+rwx $HOME/cold-keys\n
  • 6-1-2.\u4ee5\u4e0b\u30d5\u30a9\u30eb\u30c0\u5185\u3059\u3079\u3066\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u5916\u90e8\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u9000\u907f\u3055\u305b\u308b

  • /home/user/cnode (user\u306f\u5404\u81ea\u3067\u8a2d\u5b9a\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u540d)

  • /home/cold-keys

  • 6-1-3.\u9000\u907f\u3055\u305b\u305f\u3089\u3001\u4e0a\u8a18\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u5185\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u3059\u3079\u3066\u524a\u9664\u3059\u308b (\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30d5\u30a9\u30eb\u30c0\u306f\u6b8b\u3057\u3066\u4e0b\u3055\u3044)

  • 6-1-4.Ubuntu\u3092\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3(\u96fb\u6e90\u30aa\u30d5)\u3059\u308b

"},{"location":"operation/ubuntu22/#6-2-virtualbox","title":"6-2. VirtualBox\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9","text":"

VirtualBox\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30b5\u30a4\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001VirtualBox 7.0.8 platform packages\u306eWindows hosts\u307e\u305f\u306fmacOS\u306e\u30ea\u30f3\u30af\u304b\u3089\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3001\u65e2\u5b58\u306eVirtuialBox\u306b\u5bfe\u3057\u3066\u4e0a\u66f8\u304d\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u304f\u3060\u3055\u3044

  • VirtualBox\u306e\u5165\u624b
"},{"location":"operation/ubuntu22/#6-3","title":"6-3. \u30b7\u30b9\u30c6\u30e0\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8","text":"
  • 6-3-1.VirtualBox\u306e\u30de\u30b7\u30f3\u8a2d\u5b9a\u304b\u3089\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u6709\u52b9\u306b\u3059\u308b

  • 6-3-2.Ubuntu\u3092\u8d77\u52d5\u3059\u308b

  • 6-3-3.\u30c7\u30a3\u30b9\u30af\u5bb9\u91cf\u3092\u78ba\u8a8d\u3059\u308b

df -h /root\n

Avail\u306e\u5024\u304c10G\u4ee5\u4e0a\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

  • Ubuntu\u8a2d\u5b9a\u304b\u3089\u300c\u96fb\u6e90\u7ba1\u7406\u300d\u2192\u300c\u30d6\u30e9\u30f3\u30af\u30b9\u30af\u30ea\u30fc\u30f3\u300d\u2192\u300c\u3057\u306a\u3044\u300d\u306b\u8a2d\u5b9a

  • \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e00\u89a7\u304b\u3089soft\u3068\u691c\u7d22\u3057\u3001[\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3068\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8]\u3092\u8d77\u52d5

  • [\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8]\u30bf\u30d6\u306e\u9577\u671f\u30b5\u30dd\u30fc\u30c8(LTS)\u7248\u304c\u9078\u629e\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3001\u9589\u3058\u308b

  • \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e00\u89a7\u304b\u3089update\u3068\u691c\u7d22\u3057\u3001[\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u66f4\u65b0]\u3092\u8d77\u52d5

  • \u300c\u4eca\u3059\u3050\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u300d\u3092\u30af\u30ea\u30c3\u30af\u3002

  • \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5f8c\u518d\u8d77\u52d5\u3092\u6c42\u3081\u3089\u308c\u305f\u3089\u518d\u8d77\u52d5\u3059\u308b\u3002

"},{"location":"operation/ubuntu22/#6-4-ubuntu","title":"6-4. Ubuntu\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9","text":"
  • 6-4-1.\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e00\u89a7\u304b\u3089update\u3068\u691c\u7d22\u3057\u3001[\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u66f4\u65b0]\u3092\u8d77\u52d5

  • 6-4-2.\u300c\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9

\u8868\u793a\u3055\u308c\u305f\u5185\u5bb9\u306b\u6cbf\u3063\u3066\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u306b\u306f\u6570\u5341\u5206\u304b\u304b\u308a\u307e\u3059\u3002

  • 6-4-3.\u51e6\u7406\u304c\u9032\u3080\u3068\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u753b\u50cf\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002

  • 6-4-4.FireFox\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u306f\u4ee5\u4e0b\u306e\u753b\u50cf\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002\u300cNEXT\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • 6-4-5.\u66f4\u306b\u51e6\u7406\u304c\u9032\u307f\u3001\u30b5\u30dd\u30fc\u30c8\u5916\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u524a\u9664\u3057\u307e\u3059

"},{"location":"operation/ubuntu22/#6-5-guestaddtions","title":"6-5. GuestAddtions\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9","text":"
  • 6-5-1.GuestAddtions\u3092\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3059\u308b
  • 6-5-2.Ubuntu\u3092\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3(\u96fb\u6e90\u30aa\u30d5)\u3059\u308b
"},{"location":"operation/ubuntu22/#6-6","title":"6-6. \u6700\u7d42\u4ed5\u4e0a\u3052","text":"
  • 6-6-1.\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30aa\u30d5

  • 6-6-2.Ubuntu\u3092\u8d77\u52d5\u3059\u308b

  • 6-6-3.\u30d6\u30e9\u30b1\u30c3\u30c8\u30da\u30fc\u30b9\u30c8\u30e2\u30fc\u30c9OFF

echo \"set enable-bracketed-paste off\" >> ~/.inputrc\n
  • 6-6-4.\u9000\u907f\u3057\u305f\u30ad\u30fc\u30d5\u30a1\u30a4\u30eb\u3092cnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u623b\u3059

  • 6-6-5.\u623b\u3057\u305f\u4e3b\u8981\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30af\u30bb\u30b9\u5236\u9650

cd $NODE_HOME\nchmod 400 payment.vkey\nchmod 400 payment.skey\nchmod 400 stake.vkey\nchmod 400 stake.skey\nchmod 400 stake.addr\nchmod 400 payment.addr\nchmod a-rwx $HOME/cold-keys\n
  • 6-6-6.Ubuntu22.04\u3067\u518d\u30d3\u30eb\u30c9\u3057\u305fcardano-cli\u3092\u30b3\u30d4\u30fc\u3059\u308b(\u53c2\u8003\u624b\u9806)
"},{"location":"operation/withdrawal/","title":"\u8cc7\u91d1\u5f15\u304d\u51fa\u3057","text":""},{"location":"operation/withdrawal/#1-stakeaddr","title":"1 stake.addr\u304b\u3089\u306e\u5f15\u304d\u51fa\u3057","text":"

\u6982\u8981

  • \u5831\u916c\u306f stake.addr \u30a2\u30c9\u30ec\u30b9\u306b\u84c4\u7a4d\u3055\u308c\u3066\u3044\u304d\u307e\u3059\u3002
  • 1\u56de\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3067\u5f15\u304d\u51fa\u305b\u308b\u91d1\u984d\u306f\u6b8b\u9ad8\u5168\u984d\u306e\u307f\u3067\u3059\u3002 (\u5206\u5272\u3057\u3066\u5f15\u304d\u51fa\u3059\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093)
  • \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u624b\u6570\u6599\u306fpayment.addr\u304b\u3089\u5f15\u304d\u843d\u3068\u3055\u308c\u307e\u3059\u3002

1-1 payment.addr\u3078\u9001\u91d1\u3059\u308b\u65b9\u6cd5\u306f\u3053\u3061\u3089

1-2 \u4efb\u610f\u306e\u30a2\u30c9\u30ec\u30b9\u3078\u9001\u91d1\u3059\u308b\u65b9\u6cd5\u306f\u3053\u3061\u3089

\u6ce8\u610f

\u5165\u529b\u30df\u30b9\u306a\u3069\u3067\u9001\u91d1\u304c\u5931\u6557\u3057\u3066\u3082\u8cac\u4efb\u306f\u8ca0\u3048\u307e\u305b\u3093\u3002\u81ea\u5df1\u8cac\u4efb\u306e\u3082\u3068\u5b9f\u65bd\u4e0b\u3055\u3044\u3002 payment.skey\u3068stake.skey\u306f\u5fc5\u305a\u30aa\u30d5\u30e9\u30a4\u30f3\u74b0\u5883\u3067\u4fdd\u7ba1\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"operation/withdrawal/#1-1-paymentaddr","title":"1-1 payment.addr\u3078\u9001\u91d1\u3059\u308b\u65b9\u6cd5","text":"

\u73fe\u5728\u306e\u30b9\u30ed\u30c3\u30c8\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u306e\u6b8b\u9ad8\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\nrewardBalance=$(cardano-cli query stake-address-info \\\n    $NODE_NETWORK \\\n    --address $(cat stake.addr) | jq -r \".[0].rewardAccountBalance\")\necho rewardBalance: $rewardBalance\n

1 ADA = 1,000,000 lovelace.\u3068\u899a\u3048\u307e\u3057\u3087\u3046

\u5831\u916c\u306e\u79fb\u52d5\u5148\u3068\u306a\u308bpayment.addr\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002payment.addr\u306b\u306f\u53d6\u5f15\u624b\u6570\u6599\u3092\u652f\u6255\u3046\u305f\u3081\u306e\u6b8b\u9ad8\u304c\u5fc5\u8981\u3067\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
destinationAddress=$(cat payment.addr)\necho destinationAddress: $destinationAddress\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n\nwithdrawalString=\"$(cat stake.addr)+${rewardBalance}\"\n

build-raw transaction\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --withdrawal ${withdrawalString} \\\n    --out-file tx.tmp\n

\u73fe\u5728\u306e\u6700\u4f4e\u6599\u91d1\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 2 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u5909\u66f4\u51fa\u529b\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}+${rewardBalance}))\necho Change Output: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --withdrawal ${withdrawalString} \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u652f\u6255\u3044\u3068\u30b9\u30c6\u30fc\u30af\u306e\u79d8\u5bc6\u9375\u306e\u4e21\u65b9\u3092\u4f7f\u7528\u3057\u3066\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u7f72\u540d\u3055\u308c\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

\u8cc7\u91d1\u304c\u5230\u7740\u3057\u305f\u304b\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address ${destinationAddress} \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

\u66f4\u65b0\u3055\u308c\u305f\u30e9\u30d6\u30ec\u30fc\u30b9\u306e\u6b8b\u9ad8\u3068\u5831\u916c\u3092\u8868\u793a\u3057\u307e\u3059\u3002

                           TxHash                                 TxIx        Lovelace\n----------------------------------------------------------------------------------------\n100322a39d02c2ead....  \n
"},{"location":"operation/withdrawal/#1-2","title":"1-2 \u4efb\u610f\u306e\u30a2\u30c9\u30ec\u30b9\u3078\u9001\u91d1\u3059\u308b\u65b9\u6cd5","text":"

\u73fe\u5728\u306e\u30b9\u30ed\u30c3\u30c8No\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

\u5165\u91d1\u5148\u30a2\u30c9\u30ec\u30b9\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
destinationAddress=\u5165\u91d1\u5148\u30a2\u30c9\u30ec\u30b9\u3092\u6307\u5b9a\u3059\u308b\necho destinationAddress: $destinationAddress\n

\u5831\u916c\u30a2\u30c9\u30ec\u30b9\u6b8b\u9ad8\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cd $NODE_HOME\nrewardBalance=$(cardano-cli query stake-address-info \\\n    $NODE_NETWORK \\\n    --address $(cat stake.addr) | jq -r \".[0].rewardAccountBalance\")\necho rewardBalance: $rewardBalance\n

payment.addr \u306e\u6b8b\u9ad8\u3092\u7b97\u51fa

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n\nwithdrawalString=\"$(cat stake.addr)+${rewardBalance}\"\necho ${withdrawalString}\n

build-raw transaction\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+0 \\\n    --tx-out ${destinationAddress}+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --withdrawal ${withdrawalString} \\\n    --out-file tx.tmp\n

\u73fe\u5728\u306e\u6700\u4f4e\u6599\u91d1\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 2 \\\n    $NODE_NETWORK \\\n    --witness-count 2 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u5909\u66f4\u51fa\u529b\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}))\necho Change Output: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --tx-out ${destinationAddress}+${rewardBalance} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --withdrawal ${withdrawalString} \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u652f\u6255\u3044\u3068\u30b9\u30c6\u30fc\u30af\u306e\u79d8\u5bc6\u9375\u306e\u4e21\u65b9\u3092\u4f7f\u7528\u3057\u3066\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

tx.signed \u3092 \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u7f72\u540d\u3055\u308c\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

\u8cc7\u91d1\u304c\u5230\u7740\u3057\u305f\u304b\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address ${destinationAddress} \\\n    $NODE_NETWORK\n

\u66f4\u65b0\u3055\u308c\u305f\u30e9\u30d6\u30ec\u30fc\u30b9\u306e\u6b8b\u9ad8\u3068\u5831\u916c\u3092\u8868\u793a\u3057\u307e\u3059\u3002

                           TxHash                                 TxIx        Lovelace\n----------------------------------------------------------------------------------------\n100322a39d02c2ead....  \n
"},{"location":"operation/withdrawal/#2-paymentaddr","title":"2 Payment.addr\u304b\u3089\u306e\u5f15\u304d\u51fa\u3057","text":"

\u6982\u8981

payment.addr\u304b\u3089\u4efb\u610f\u306e\u30a2\u30c9\u30ec\u30b9\u3078\u9001\u4fe1\u3059\u308b\u4f8b\u3067\u3059

\u6ce8\u610f

  • \u5165\u529b\u30df\u30b9\u306a\u3069\u3067\u9001\u91d1\u304c\u5931\u6557\u3057\u3066\u3082\u8cac\u4efb\u306f\u8ca0\u3048\u307e\u305b\u3093\u3002\u81ea\u5df1\u8cac\u4efb\u306e\u3082\u3068\u5b9f\u65bd\u4e0b\u3055\u3044\u3002
  • \u5ba3\u8a00\u3057\u305f\u8a93\u7d04(Pledge)\u5206\u307e\u3067\u5f15\u304d\u51fa\u3057\u3066\u3057\u307e\u3046\u3068\u3001\u30d7\u30fc\u30eb\u5831\u916c\u304c\u30bc\u30ed\u306b\u306a\u308a\u307e\u3059\u306e\u3067\u3054\u6ce8\u610f\u304f\u3060\u3055\u3044
  • payment.skey\u3068stake.skey\u306f\u5fc5\u305a\u30aa\u30d5\u30e9\u30a4\u30f3\u74b0\u5883\u3067\u4fdd\u7ba1\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u6700\u65b0\u306e\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u3092\u53d6\u5f97\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

lovelace\u5f62\u5f0f\u3067\u9001\u4fe1\u3059\u308b\u91d1\u984d\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u30021 ADA = 1,000,000 lovelace \u3067\u899a\u3048\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
amountToSend=10000000\necho amountToSend: $amountToSend\n

\u9001\u91d1\u5148\u306e\u30a2\u30c9\u30ec\u30b9\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
destinationAddress=\u9001\u91d1\u5148\u30a2\u30c9\u30ec\u30b9\necho destinationAddress: $destinationAddress\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

build-raw\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+0 \\\n    --tx-out ${destinationAddress}+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u624b\u6570\u6599\u3092\u51fa\u529b\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 2 \\\n    $NODE_NETWORK \\\n    --witness-count 1 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u8a08\u7b97\u7d50\u679c\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${fee}-${amountToSend}))\necho Change Output: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u69cb\u7bc9\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --tx-out ${destinationAddress}+${amountToSend} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

tx.signed \u3092\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306etx.signed \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u7f72\u540d\u3055\u308c\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

\u5165\u91d1\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address ${destinationAddress} \\\n    $NODE_NETWORK \\\n

\u5148\u7a0b\u6307\u5b9a\u3057\u305f\u91d1\u984d\u3068\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070\u554f\u984c\u306a\u3044\u3067\u3059\u3002

                           TxHash                                 TxIx        Lovelace\n----------------------------------------------------------------------------------------\n100322a39d02c2ead....                                              0        10000000\n
"},{"location":"setup/1-ubuntu-setup/","title":"1.Ubuntu\u521d\u671f\u8a2d\u5b9a","text":"

AWS\u3092\u3054\u5229\u7528\u306e\u65b9

AWS EC2\u53ca\u3073lightsail\u306f\u7279\u6b8a\u74b0\u5883\u306a\u305f\u3081\u3001\u3053\u306e\u30de\u30cb\u30e5\u30a2\u30eb\u901a\u308a\u306b\u52d5\u304b\u306a\u3044\u5834\u5408\u304c\u3054\u3056\u3044\u307e\u3059\u3002 \u4e0d\u660e\u306a\u70b9\u306fGuild\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u3067\u8cea\u554f\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002

\u30d2\u30f3\u30c8

\u3053\u306e\u624b\u9806\u306f\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3(VirtualBox\u4e0a\u306eUbuntu)\u3067\u306f\u5b9f\u65bd\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093

"},{"location":"setup/1-ubuntu-setup/#1-1","title":"1-1.\u30aa\u30b9\u30b9\u30e1\u306e\u30bf\u30fc\u30df\u30ca\u30eb\u30bd\u30d5\u30c8","text":"

1.R-Login(Windows) https://kmiya-culti.github.io/RLogin/

\u63a5\u7d9a\u72b6\u614b\u7dad\u6301\u306e\u305f\u3081\u306e\u8a2d\u5b9a

R-Login\u4f7f\u7528\u306e\u969b\u306f\u3001\u672a\u64cd\u4f5c\u6642\u306e\u63a5\u7d9a\u72b6\u614b\u3092\u4fdd\u6301\u3059\u308b\u305f\u3081\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3092\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002

2.Terminal(Mac) https://www.webdesignleaves.com/pr/plugins/mac_terminal_basics_01.html

"},{"location":"setup/1-ubuntu-setup/#1-2","title":"1-2.\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u4f5c\u6210","text":"

\u30d2\u30f3\u30c8

root\u30a2\u30ab\u30a6\u30f3\u30c8\u306f\u30b5\u30fc\u30d0\u30fc\u306e\u6700\u4e0a\u4f4d\u6a29\u9650\u3067\u3059\u3002 \u30b5\u30fc\u30d0\u3092\u64cd\u4f5c\u3059\u308b\u5834\u5408\u306froot\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f7f\u7528\u305b\u305a\u3001root\u6a29\u9650\u3092\u4ed8\u4e0e\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u64cd\u4f5c\u3059\u308b\u3088\u3046\u306b\u3057\u307e\u3057\u3087\u3046\u3002

\u65b0\u3057\u3044\u30e6\u30fc\u30b6\u30fc\u306e\u8ffd\u52a0\u3000(\u4f8b\uff1acardano)

1.\u4e0a\u8a18\u30bf\u30fc\u30df\u30ca\u30eb\u30bd\u30d5\u30c8\u3092\u4f7f\u7528\u3057\u3001\u30b5\u30fc\u30d0\u30fc\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u521d\u671f\u30a2\u30ab\u30a6\u30f3\u30c8(root\u306a\u3069)\u3067\u30ed\u30b0\u30a4\u30f3\u3059\u308b\u3002

2.\u65b0\u3057\u3044\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c\u308b(\u4efb\u610f\u306e\u30a2\u30eb\u30d5\u30a1\u30d9\u30c3\u30c8\u6587\u5b57)

adduser cardano\n
New password:           # \u30e6\u30fc\u30b6\u30fc\u306e\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u8a2d\u5b9a\nRetype new password:    # \u78ba\u8a8d\u518d\u5165\u529b\n\nEnter the new value, or press ENTER for the default\n        Full Name []:   # \u30d5\u30eb\u30cd\u30fc\u30e0\u7b49\u306e\u60c5\u5831\u3092\u8a2d\u5b9a (\u4e0d\u8981\u3067\u3042\u308c\u3070\u30d6\u30e9\u30f3\u30af\u3067\u3082 OK)\n        Room Number []:\n        Work Phone []:\n        Home Phone []:\n        Other []:\nIs the information correct? [Y/n]:y\n

cardano\u3092sudo\u30b0\u30eb\u30fc\u30d7\u306b\u8ffd\u52a0\u3059\u308b

usermod -G sudo cardano\n

root\u30e6\u30fc\u30b6\u30fc\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3059\u308b

exit\n

3.\u30bf\u30fc\u30df\u30ca\u30eb\u30bd\u30d5\u30c8\u306e\u30e6\u30fc\u30b6\u30fc\u3092\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u4e0a\u8a18\u3067\u4f5c\u6210\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u66f8\u304d\u63db\u3048\u3066\u518d\u63a5\u7d9a\u3057\u307e\u3059\u3002

Ubuntu22.04\u306e\u5834\u5408\u306e\u7279\u5225\u8a2d\u5b9a

\u3054\u5229\u7528\u306eOS\u304cUbuntu22.04\u306e\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30d6\u30e9\u30b1\u30c3\u30c8\u30da\u30fc\u30b9\u30c8\u30e2\u30fc\u30c9OFF

echo \"set enable-bracketed-paste off\" >> ~/.inputrc\n

\u30c7\u30fc\u30e2\u30f3\u518d\u8d77\u52d5\u81ea\u52d5\u5316

echo \"\\$nrconf{restart} = 'a';\" | sudo tee /etc/needrestart/conf.d/50local.conf\n
echo \"\\$nrconf{blacklist_rc} = [qr(^cardano-node\\\\.service$) => 0,];\" | sudo tee -a /etc/needrestart/conf.d/50local.conf\n

"},{"location":"setup/1-ubuntu-setup/#1-3ssh","title":"1-3.SSH\u9375\u8a8d\u8a3c\u65b9\u5f0f\u3078\u5207\u308a\u66ff\u3048","text":"

Summary

SSH\u3092\u5f37\u5316\u3059\u308b\u57fa\u672c\u7684\u306a\u30eb\u30fc\u30eb\u306f\u6b21\u306e\u901a\u308a\u3067\u3059\u3002

  • SSH\u30ed\u30b0\u30a4\u30f3\u6642\u30d1\u30b9\u30ef\u30fc\u30c9\u7121\u52b9\u5316 (\u79d8\u5bc6\u9375\u3092\u4f7f\u7528)
  • SSH\u30c7\u30d5\u30a9\u30eb\u30c8\u30dd\u30fc\u30c8(22)\u306e\u5909\u66f4
  • root\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u306eSSH\u30ed\u30b0\u30a4\u30f3\u7121\u52b9\u5316 (root\u6a29\u9650\u304c\u5fc5\u8981\u306a\u30b3\u30de\u30f3\u30c9\u306fsu or sudo\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3046)
  • \u8a31\u53ef\u3055\u308c\u3066\u3044\u306a\u3044\u30a2\u30ab\u30a6\u30f3\u30c8\u304b\u3089\u306e\u30ed\u30b0\u30a4\u30f3\u8a66\u884c\u3092\u30ed\u30b0\u306b\u8a18\u9332\u3059\u308b (fail2ban\u306a\u3069\u306e\u3001\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3092\u30d6\u30ed\u30c3\u30af\u307e\u305f\u306f\u7981\u6b62\u3059\u308b\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u5c0e\u5165\u3092\u691c\u8a0e\u3059\u308b)
  • SSH\u30ed\u30b0\u30a4\u30f3\u5143\u306eIP\u30a2\u30c9\u30ec\u30b9\u7bc4\u56f2\u306e\u307f\u306b\u9650\u5b9a\u3059\u308b (\u5e0c\u671b\u3059\u308b\u5834\u5408\u306e\u307f)\u203b\u5229\u7528\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306b\u3088\u3063\u3066\u306f\u3001\u5b9a\u671f\u7684\u306b\u30b0\u30ed\u30fc\u30d0\u30ebIP\u304c\u5909\u66f4\u3055\u308c\u308b\u306e\u3067\u6ce8\u610f\u304c\u5fc5\u8981

\u30da\u30a2\u9375\u306e\u4f5c\u6210

ssh-keygen -t ed25519 -N '' -C ssh_connect -f ~/.ssh/ssh_ed25519\n

cd ~/.ssh\nls\n
ssh_ed25519\uff08\u79d8\u5bc6\u9375\uff09\u3068ssh_ed25519.pub\uff08\u516c\u958b\u9375\uff09\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u304c\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b\u3002

cd ~/.ssh/\ncat ssh_ed25519.pub >> authorized_keys\nchmod 600 authorized_keys\nchmod 700 ~/.ssh\n

SSH\u9375\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

1.R-login\u306e\u5834\u5408\u306f\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u958b\u304f 2.\u5de6\u5074\u30a6\u30a3\u30f3\u30c9\u30a6(\u30ed\u30fc\u30ab\u30eb\u5074)\u306f\u4efb\u610f\u306e\u968e\u5c64\u306b\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3059\u308b\u3002 3.\u53f3\u5074\u30a6\u30a3\u30f3\u30c9\u30a6(\u30b5\u30fc\u30d0\u5074)\u306f\u300c.ssh\u300d\u30d5\u30a9\u30eb\u30c0\u3092\u9078\u629e\u3059\u308b 4.\u53f3\u5074\u30a6\u30a3\u30f3\u30c9\u30a6\u304b\u3089\u3001ssh_ed25519\u3068ssh_ed25519.pub\u306e\u4e0a\u3067\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u300c\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u300d\u3092\u9078\u629e\u3059\u308b 5.\u4e00\u65e6\u30b5\u30fc\u30d0\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3059\u308b 6.R-Login\u306e\u30b5\u30fc\u30d0\u63a5\u7d9a\u7de8\u96c6\u753b\u9762\u3092\u958b\u304d\u3001\u300cSSH\u8a8d\u8a3c\u9375\u300d\u3092\u30af\u30ea\u30c3\u30af\u30574\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fssh_ed25519\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u3076 7.\u30b5\u30fc\u30d0\u3078\u63a5\u7d9a\u3059\u308b

SSH\u306e\u8a2d\u5b9a\u5909\u66f4

/etc/ssh/sshd_config\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f

sudo nano /etc/ssh/sshd_config\n

ResponseAuthentication\u306e\u9805\u76ee\u3092\u300cno\u300d\u306b\u3057\u307e\u3059\u3002

Ubuntu20.04\u306e\u5834\u5408Ubuntu22.04\u306e\u5834\u5408
ChallengeResponseAuthentication no\n
KbdInteractiveAuthentication no\n

PasswordAuthentication\u306e\u9805\u76ee\u3092\u300cno\u300d\u306b\u3059\u308b

PasswordAuthentication no \n

PermitRootLogin\u306e\u9805\u76ee\u3092\u300cno\u300d\u306b\u3059\u308b

PermitRootLogin no\n

PermitEmptyPasswords\u306e\u9805\u76ee\u3092\u300cno\u300d\u306b\u3059\u308b

PermitEmptyPasswords no\n

SSH\u30dd\u30fc\u30c8\u306e\u30d2\u30f3\u30c8

SSH\u30dd\u30fc\u30c8\u306f\u4e16\u754c\u6a19\u6e96\u306722\u756a\u304c\u5272\u308a\u5f53\u3066\u3089\u308c\u3066\u3044\u307e\u3059\u3002 \u3057\u304b\u3057\u3001\u30dd\u30fc\u30c8\u30a2\u30bf\u30c3\u30af\u306e\u6a19\u7684\u3068\u306a\u308a\u5f97\u308b\u305f\u3081\u4efb\u610f\u306e\u756a\u53f7\u3078\u5909\u66f4\u3059\u308b\u3053\u3068\u3092\u304a\u3059\u3059\u3081\u3057\u3066\u3044\u307e\u3059\u3002\u4efb\u610f\u306e\u756a\u53f7\u306f49513\uff5e65535\u307e\u3067\u306e\u6570\u5b57\u3067\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

SSH\u30dd\u30fc\u30c8\u3092\u4efb\u610f\u306e\u756a\u53f7\u3078\u5909\u66f4\u3059\u308b\u3002\u5148\u982d\u306e#\u3092\u524a\u9664\u3057\u3066\u756a\u53f7\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

Port xxxxx\n

Ctrl+O \u3067\u4fdd\u5b58\u3057\u3001Ctrl+X\u3067\u9589\u3058\u308b

SSH\u69cb\u6587\u306b\u30a8\u30e9\u30fc\u304c\u306a\u3044\u304b\u30c1\u30a7\u30c3\u30af\u3057\u307e\u3059\u3002

sudo sshd -t\n

SSH\u69cb\u6587\u30a8\u30e9\u30fc\u304c\u306a\u3044\u5834\u5408\u3001SSH\u30d7\u30ed\u30bb\u30b9\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo service sshd reload\n

\u63a5\u7d9a\u3057\u305f\u307e\u307e\u3001\u30bf\u30fc\u30df\u30ca\u30eb\u30bd\u30d5\u30c8\u3092\u3082\u3046\u4e00\u3064\u8d77\u52d5\u3059\u308b\u3002

\u30bf\u30fc\u30df\u30ca\u30eb\u30bd\u30d5\u30c8\u8a2d\u5b9a\u306b\u3064\u3044\u3066

\u63a5\u7d9a\u8a2d\u5b9a\u306eSSH\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5909\u66f4\u3057\u79d8\u5bc6\u9375\u3092\u8a2d\u5b9a\u3057\u30b5\u30fc\u30d0\u30fc\u3078\u30ed\u30b0\u30a4\u30f3\u3067\u304d\u308b\u304b\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002 \u63a5\u7d9a\u3067\u304d\u306a\u3044\u5834\u5408\u306f\u3001\u63a5\u7d9a\u3055\u308c\u3066\u308b\u30bf\u30fc\u30df\u30ca\u30eb\u753b\u9762\u3067\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a\u3092\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002

"},{"location":"setup/1-ubuntu-setup/#1-4","title":"1-4.\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u6709\u52b9\u5316","text":"

\u6a19\u6e96\u306eUFW\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3066\u3001\u30a4\u30f3\u30d0\u30a6\u30f3\u30c9\u30a2\u30af\u30bb\u30b9\u30dd\u30fc\u30c8\u3092\u9650\u5b9a\u3057\u307e\u3059\u3002

\u8a2d\u5b9a\u524d\u306e\u6ce8\u610f\u4e8b\u9805

\u3054\u5229\u7528\u306eVPS\u306b\u3088\u3063\u3066\u306f\u7ba1\u7406\u753b\u9762\u304b\u3089FW\u3092\u8a2d\u5b9a\u3059\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\uff08\u4f8bAWS\u7cfb\u306a\u3069\uff09 \u305d\u306e\u5834\u5408\u306f\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3092\u884c\u308f\u305a\u3001VPS\u30de\u30a4\u30da\u30fc\u30b8\u7ba1\u7406\u753b\u9762\u306a\u3069\u304b\u3089\u500b\u5225\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u3055\u304f\u3089VPS\u3092\u3054\u5229\u7528\u306e\u5834\u5408

\u7ba1\u7406\u753b\u9762\u304b\u3089\u30d1\u30b1\u30c3\u30c8\u30d5\u30a3\u30eb\u30bf\u30fc\u3092\u3001\u201d\u5229\u7528\u3057\u306a\u3044\u201d\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

SSH\u30dd\u30fc\u30c8\u3092\u8a31\u53ef\u3059\u308b

PORT=`grep \"Port\" /etc/ssh/sshd_config`\ns_PORT=${PORT#\"Port\"}\nssh_PORT=`echo ${s_PORT} | sed -e 's/[^0-9]//g'`\necho ${ssh_PORT}\n

sudo ufw allow ${ssh_PORT}/tcp\n
FW\u3092\u6709\u52b9\u5316
sudo ufw enable\n
\u4ee5\u4e0b\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u305f\u3089 y \u3092\u5165\u529b\u3057\u3066 Enter

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y

\u30b9\u30c6\u30fc\u30bf\u30b9\u78ba\u8a8d

sudo ufw status\n
\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u304c\u3042\u308c\u3070OK

Status: active

"},{"location":"setup/1-ubuntu-setup/#1-5","title":"1-5.\u30b7\u30b9\u30c6\u30e0\u3092\u66f4\u65b0\u3059\u308b","text":"

\u91cd\u8981

\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3092\u4e88\u9632\u3059\u308b\u306b\u306f\u3001\u30b7\u30b9\u30c6\u30e0\u306b\u6700\u65b0\u306e\u30d1\u30c3\u30c1\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002

sudo apt update -y && sudo apt upgrade -y\nsudo apt autoremove\nsudo apt autoclean\n

\u81ea\u52d5\u66f4\u65b0\u3092\u6709\u52b9\u306b\u3059\u308b\u3068\u3001\u624b\u52d5\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u624b\u9593\u3092\u7701\u3051\u307e\u3059\u3002

YES\u3092\u9078\u629e\u3057Enter

sudo apt install unattended-upgrades\nsudo dpkg-reconfigure --priority=low unattended-upgrades\n
"},{"location":"setup/1-ubuntu-setup/#1-6root","title":"1-6.root\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7121\u52b9\u306b\u3059\u308b","text":"

\u30b5\u30fc\u30d0\u30fc\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u7dad\u6301\u3059\u308b\u305f\u3081\u306b\u3001\u983b\u7e41\u306broot\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30ed\u30b0\u30a4\u30f3\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002

\u901a\u5e38\u306froot\u30a2\u30ab\u30a6\u30f3\u30c8\u7121\u52b9\u306b\u3057\u307e\u3059

sudo passwd -l root\n

# \u4f55\u3089\u304b\u306e\u7406\u7531\u3067root\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u6709\u52b9\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u5834\u5408\u306f\u3001-u\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002

sudo passwd -u root\n
"},{"location":"setup/1-ubuntu-setup/#1-7","title":"1-7.\u5b89\u5168\u306a\u5171\u6709\u30e1\u30e2\u30ea\u30fc","text":"

\u30b7\u30b9\u30c6\u30e0\u3067\u5171\u6709\u3055\u308c\u308b\u30e1\u30e2\u30ea\u3092\u4fdd\u8b77\u3057\u307e\u3059\u3002

/etc/fstab\u3092\u958b\u304d\u307e\u3059

sudo nano /etc/fstab\n

\u6b21\u306e\u884c\u3092\u30d5\u30a1\u30a4\u30eb\u306e\u6700\u5f8c\u306b\u8ffd\u8a18\u3057\u3066\u4fdd\u5b58\u3057\u307e\u3059\u3002

tmpfs   /run/shm    tmpfs   ro,noexec,nosuid    0 0\n
"},{"location":"setup/1-ubuntu-setup/#1-8fail2ban","title":"1-8.Fail2ban\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

Fail2ban\u306f\u3001\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u3092\u76e3\u8996\u3057\u3001\u30ed\u30b0\u30a4\u30f3\u8a66\u884c\u306b\u5931\u6557\u3057\u305f\u7279\u5b9a\u306e\u30d1\u30bf\u30fc\u30f3\u3092\u76e3\u8996\u3059\u308b\u4fb5\u5165\u9632\u6b62\u30b7\u30b9\u30c6\u30e0\u3067\u3059\u3002\u7279\u5b9a\u306eIP\u30a2\u30c9\u30ec\u30b9\u304b\u3089\uff08\u6307\u5b9a\u3055\u308c\u305f\u6642\u9593\u5185\u306b\uff09\u4e00\u5b9a\u6570\u306e\u30ed\u30b0\u30a4\u30f3\u5931\u6557\u304c\u691c\u77e5\u3055\u308c\u305f\u5834\u5408\u3001Fail2ban\u306f\u305d\u306eIP\u30a2\u30c9\u30ec\u30b9\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3092\u30d6\u30ed\u30c3\u30af\u3057\u307e\u3059\u3002

sudo apt install fail2ban -y\n

SSH\u30ed\u30b0\u30a4\u30f3\u3092\u76e3\u8996\u3059\u308b\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304d\u307e\u3059\u3002

sudo nano /etc/fail2ban/jail.local\n

\u30d5\u30a1\u30a4\u30eb\u306e\u6700\u5f8c\u306b\u6b21\u306e\u884c\u3092\u8ffd\u52a0\u3057\u4fdd\u5b58\u3057\u307e\u3059\u3002

\u30b3\u30de\u30f3\u30c9\u4e2d\u306e (SSH\u30dd\u30fc\u30c8\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044) \u306b\u3064\u3044\u3066\u306f1-3\u3067\u8a2d\u5b9a\u3057\u305fSSH\u30dd\u30fc\u30c8\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002()\u306f\u4e0d\u8981\u3067\u3059\u3002

[sshd]\nenabled = true\nport = (SSH\u30dd\u30fc\u30c8\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044)\nfilter = sshd\nlogpath = /var/log/auth.log\nmaxretry = 3\n

fail2ban\u3092\u518d\u8d77\u52d5\u3057\u3066\u8a2d\u5b9a\u3092\u6709\u52b9\u306b\u3057\u307e\u3059\u3002

sudo systemctl restart fail2ban\n
"},{"location":"setup/1-ubuntu-setup/#1-9chrony","title":"1-9.Chrony\u3092\u8a2d\u5b9a\u3059\u308b","text":"

chrony\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002

sudo apt install chrony\n

/etc/chrony/chrony.conf \u3092\u66f4\u65b0\u3057\u307e\u3059\u3002

cat > $HOME/chrony.conf << EOF\npool time.google.com       iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3\npool time.facebook.com     iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3\npool time.euro.apple.com   iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3\npool time.apple.com        iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3\npool ntp.ubuntu.com        iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3\n\n# This directive specify the location of the file containing ID/key pairs for\n# NTP authentication.\nkeyfile /etc/chrony/chrony.keys\n\n# This directive specify the file into which chronyd will store the rate\n# information.\ndriftfile /var/lib/chrony/chrony.drift\n\n# Uncomment the following line to turn logging on.\n#log tracking measurements statistics\n\n# Log files location.\nlogdir /var/log/chrony\n\n# Stop bad estimates upsetting machine clock.\nmaxupdateskew 5.0\n\n# This directive enables kernel synchronisation (every 11 minutes) of the\n# real-time clock. Note that it can\u2019t be used along with the 'rtcfile' directive.\nrtcsync\n\n# Step the system clock instead of slewing it if the adjustment is larger than\n# one second, but only in the first three clock updates.\nmakestep 0.1 -1\n\n# Get TAI-UTC offset and leap seconds from the system tz database\nleapsectz right/UTC\n\n# Serve time even if not synchronized to a time source.\nlocal stratum 10\nEOF\n

\u4f5c\u6210\u3057\u305fchrony.conf\u3092/etc/chrony/chrony.conf\u306b\u79fb\u52d5\u3057\u307e\u3059\u3002

sudo mv $HOME/chrony.conf /etc/chrony/chrony.conf\n

UFW\u3067\u4ee5\u4e0b\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002

sudo ufw allow 123/udp\n

\u8a2d\u5b9a\u3092\u6709\u52b9\u306b\u3059\u308b\u306b\u306f\u3001Chrony\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl reload-or-restart chronyd.service\n

\u30d8\u30eb\u30d7\u30b3\u30de\u30f3\u30c9

\u540c\u671f\u30c7\u30fc\u30bf\u306e\u30bd\u30fc\u30b9\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

chronyc sources\n

\u73fe\u5728\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002

chronyc tracking\n
"},{"location":"setup/1-ubuntu-setup/#1-10ssh2","title":"1-10.SSH\u306e2\u6bb5\u968e\u8a8d\u8a3c\u3092\u8a2d\u5b9a\u3059\u308b","text":"

\u6ce8\u610f

  • \u3053\u3061\u3089\u306e\u5c0e\u5165\u306f\u5fc5\u9808\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u5c0e\u5165\u3059\u308b\u5834\u5408\u3001\u4e8b\u524d\u306b\u304a\u624b\u5143\u306e\u30b9\u30de\u30fc\u30c8\u30d5\u30a9\u30f3\u306b\u300cGoogle\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u30a2\u30d7\u30ea\u300d\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304c\u5fc5\u8981\u3067\u3059

  • \u8a2d\u5b9a\u306b\u5931\u6557\u3059\u308b\u3068\u30ed\u30b0\u30a4\u30f3\u3067\u304d\u306a\u304f\u306a\u308b\u5834\u5408\u304c\u3042\u308b\u306e\u3067\u3001\u8a2d\u5b9a\u524d\u306b\u4e8c\u3064\u76ee\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u30b5\u30fc\u30d0\u30fc\u306b\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u304a\u3044\u3066\u304f\u3060\u3055\u3044\u3002\u4e07\u304c\u4e00\u30ed\u30b0\u30a4\u30f3\u3067\u304d\u306a\u304f\u306a\u3063\u305f\u5834\u5408\u3001\u5fa9\u65e7\u3067\u304d\u307e\u3059\u3002

sudo apt update\nsudo apt upgrade\nsudo apt install libpam-google-authenticator -y\n

SSH\u304cGoogle Authenticator PAM \u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u4f7f\u7528\u3059\u308b\u305f\u3081\u306b\u3001/etc/pam.d/sshd\u30d5\u30a1\u30a4\u30eb\u3092\u7de8\u96c6\u3057\u307e\u3059\u3002

sudo nano /etc/pam.d/sshd \n

4\u884c\u76ee\u306e @include common-auth\u306e\u5148\u982d\u3078#\u3092\u4ed8\u4e0e\u3057\u3066\u30b3\u30e1\u30f3\u30c8\u30a2\u30a6\u30c8\u3059\u308b\u3002

#@include common-auth\n

\u4ee5\u4e0b\u306e\u884c\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002

auth required pam_google_authenticator.so\n

\u4ee5\u4e0b\u3092\u4f7f\u7528\u3057\u3066sshd\u30c7\u30fc\u30e2\u30f3\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl restart sshd.service\n

/etc/ssh/sshd_config \u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304d\u307e\u3059\u3002

sudo nano /etc/ssh/sshd_config\n

ResponseAuthentication\u306e\u9805\u76ee\u3092\u300cyes\u300d\u306b\u3057\u307e\u3059\u3002

Ubuntu20.04\u306e\u5834\u5408Ubuntu22.04\u306e\u5834\u5408
ChallengeResponseAuthentication yes\n
KbdInteractiveAuthentication yes\n

UsePAM\u306e\u9805\u76ee\u3092\u300cyes\u300d\u306b\u3057\u307e\u3059\u3002

UsePAM yes\n

\u6700\u5f8c\u306e\u884c\u306b1\u884c\u8ffd\u52a0\u3057\u307e\u3059\u3002(SSH\u516c\u958b\u9375\u79d8\u5bc6\u9375\u30ed\u30b0\u30a4\u30f3\u3092\u5229\u7528\u306e\u5834\u5408)

AuthenticationMethods publickey,keyboard-interactive\n

\u30d5\u30a1\u30a4\u30eb\u3092\u4fdd\u5b58\u3057\u3066\u9589\u3058\u307e\u3059\u3002

\u4ee5\u4e0b\u3092\u4f7f\u7528\u3057\u3066sshd\u30c7\u30fc\u30e2\u30f3\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl restart sshd.service\n

google-authenticator \u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

google-authenticator\n

\u3044\u304f\u3064\u304b\u8cea\u554f\u4e8b\u9805\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002\u63a8\u5968\u9805\u76ee\u306f\u4ee5\u4e0b\u306e\u3068\u304a\u308a\u3067\u3059\u3002

Do you want authentication tokens to be time-based (y/n) : y\n
Do you want me to update your \n\"/home/cardano/.google_authenticator\" file? (y/n): y\n
Do you want to disallow multiple uses of the same authentication\ntoken? This restricts you to one login about every 30s, but it increases\nyour chances to notice or even prevent man-in-the-middle attacks (y/n): y\n

By default, a new token is generated every 30 seconds by the mobile app.\nIn order to compensate for possible time-skew between the client and the server,\nwe allow an extra token before and after the current time. This allows for a\ntime skew of up to 30 seconds between authentication server and client. If you\nexperience problems with poor time synchronization, you can increase the window\nfrom its default size of 3 permitted codes (one previous code, the current\ncode, the next code) to 17 permitted codes (the 8 previous codes, the current\ncode, and the 8 next codes). This will permit for a time skew of up to 4 minutes\nbetween client and server.\nDo you want to do so? (y/n): n\n
If the computer that you are logging into isn't hardened against brute-force\nlogin attempts, you can enable rate-limiting for the authentication module.\nBy default, this limits attackers to no more than 3 login attempts every 30s.\nDo you want to enable rate-limiting? (y/n) : y\n

\u30d7\u30ed\u30bb\u30b9\u4e2d\u306b\u5927\u304d\u306aQR\u30b3\u30fc\u30c9\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u304c\u3001\u305d\u306e\u4e0b\u306b\u306f\u7dca\u6025\u6642\u306e\u30b9\u30af\u30e9\u30c3\u30c1\u30b3\u30fc\u30c9\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u306e\u3067\u3001\u5fd8\u308c\u305a\u306b\u66f8\u304d\u7559\u3081\u3066\u304a\u3044\u3066\u4e0b\u3055\u3044\u3002

\u30b9\u30de\u30fc\u30c8\u30d5\u30a9\u30f3\u3067Google\u8a8d\u8a3c\u30b7\u30b9\u30c6\u30e0\u30a2\u30d7\u30ea\u3092\u958b\u304d\u3001QR\u30b3\u30fc\u30c9\u3092\u8aad\u307f\u53d6\u308a2\u6bb5\u968e\u8a8d\u8a3c\u3092\u6a5f\u80fd\u3055\u305b\u307e\u3059\u3002

"},{"location":"setup/10-blocklog-setup/","title":"10.\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u5c0e\u5165\u624b\u9806","text":"

\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u306b\u3064\u3044\u3066

\u3053\u306e\u30c4\u30fc\u30eb\u306fPoS\u306b\u304a\u3051\u308b\u81ea\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u4e8b\u524d\u306b\u53d6\u5f97\u3059\u308b\u30c4\u30fc\u30eb\u3067\u3059\u3002

\u5236\u4f5c\u30af\u30ec\u30b8\u30c3\u30c8

\u3053\u306e\u30c4\u30fc\u30eb\u306f\u6d77\u5916\u30ae\u30eb\u30c9\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5236\u4f5c\u306eCNCLI By AndrewWestberg\u3001logmonitor by Guild Operators\u3001Guild LiveView\u3001BLOCK LOG for CNTools\u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u30c4\u30fc\u30eb\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3059\u308b\u306b\u3042\u305f\u308a\u3001\u958b\u767a\u8005\u306eAHLNET(AHL)\u306b\u3054\u5354\u529b\u9802\u304d\u307e\u3057\u305f\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\u3002

"},{"location":"setup/10-blocklog-setup/#10-0","title":"10-0. \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u8981\u4ef6","text":"

\u8a2d\u5b9a\u30b5\u30fc\u30d0\u30fc

  • BP\u30ce\u30fc\u30c9\u9650\u5b9a

\u7a3c\u50cd\u8981\u4ef6

  • \uff14\u3064\u306e\u30b5\u30fc\u30d3\u30b9(\u30d7\u30ed\u30b0\u30e9\u30e0)\u3092systemd \u00d7 tmux\u306b\u3066\u5e38\u99d0\u3055\u305b\u307e\u3059\u3002
  • \u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u540c\u671f\u7528DB\u3092\u65b0\u3057\u304f\u8a2d\u7f6e\u3057\u307e\u3059(sqlite3)
  • \u65e5\u672c\u8a9e\u30de\u30cb\u30e5\u30a2\u30eb\u306e\u30d5\u30a9\u30eb\u30c0\u69cb\u6210\u306b\u5408\u308f\u305b\u3066\u4f5c\u6210\u3055\u308c\u3066\u3044\u307e\u3059\u3002
  • vrf.skey \u3068 vrf.vkey\u304c\u5fc5\u8981\u3067\u3059\u3002

\u69cb\u6210\u56f3

    flowchart TB\n        a1[cardano-node] --> a2[log\u30d5\u30a1\u30a4\u30eb]\n        a3 --> a5[leaderlog.service]\n        a3 --> a6[validate.service]\n        a1[cardano-node] --> a3[cncli.service]\n        a2 --> a4[logmonitor.service]\n        a3[cncli.service]\n        a4[logmonitor.service]\n        a5[leaderlog.service]\n        a6[validate.service]\n        subgraph Guild-DB\n            a7[cncli.db]\n            a8[blocklog.db]\n        end\n        subgraph \u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\n            a9[blockcheck] --> \u5404\u30a2\u30d7\u30ea\n        end\n        Guild-DB --> blocks.sh\n        a8[blocklog.db] --> a9[blockcheck]\n        a3[cncli.service] --> a7[cncli.db]\n        a5[leaderlog.service] --> a8[blocklog.db]\n        a6[validate.service] --> a8[blocklog.db]\n
"},{"location":"setup/10-blocklog-setup/#10-1-cncli","title":"10-1. CNCLI\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

CNCLI\u306b\u3064\u3044\u3066

AndrewWestberg\u3055\u3093\u306b\u3088\u3063\u3066\u958b\u767a\u3055\u308c\u305fCNCLI\u306f\u30d7\u30fc\u30eb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u7b97\u51fa\u3057\u3001Shelley\u671f\u306b\u304a\u3051\u308bSPO\u306b\u9769\u547d\u3092\u3082\u305f\u3089\u3057\u307e\u3057\u305f\u3002

RUST\u74b0\u5883\u3092\u6e96\u5099\u3057\u307e\u3059

mkdir $HOME/.cargo && mkdir $HOME/.cargo/bin\nchown -R $USER $HOME/.cargo\ntouch $HOME/.profile\nchown $USER $HOME/.profile\n

rustup\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059-\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u7d9a\u884c\u3057\u307e\u3059\uff08\u30aa\u30d7\u30b7\u30e7\u30f31\uff09

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n

1) Proceed with installation (default) 1\u3092\u5165\u529b\u3057\u3066Enter

source $HOME/.cargo/env\nrustup install stable\nrustup default stable\nrustup update\nrustup component add clippy rustfmt\nrustup target add x86_64-unknown-linux-musl\n

\u4f9d\u5b58\u95a2\u4fc2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3001cncli\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059

source $HOME/.cargo/env\nsudo apt update -y && sudo apt install -y automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw5 libtool autoconf musl-tools\n
cd $HOME/git\ngit clone --recurse-submodules https://github.com/cardano-community/cncli\ncd cncli\ngit checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)\ncargo install --path . --force\n

CNCLI\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

cncli --version\n

6.0.1 \u304c\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059

"},{"location":"setup/10-blocklog-setup/#10-2-sqlite3","title":"10-2. sqlite3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
sudo apt install sqlite3\nsqlite3 --version\n

3.31.1\u4ee5\u4e0a\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u305f\u3089OK\u3067\u3059\u3002

"},{"location":"setup/10-blocklog-setup/#10-3","title":"10-3. \u4f9d\u5b58\u30d5\u30a1\u30a4\u30eb\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9","text":"

\u4f9d\u5b58\u95a2\u4fc2\u306e\u3042\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002

cd $NODE_HOME\nmkdir scripts\ncd $NODE_HOME/scripts\nwget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/cncli.sh -O ./cncli.sh\nwget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env -O ./env\nwget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh -O ./gLiveView.sh\nwget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/cntools.library -O ./cntools.library\nwget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/blocks.sh -O ./blocks.sh \nwget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/logMonitor.sh -q -O ./logMonitor.sh\n

\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u3092\u8a2d\u5b9a\u3059\u308b

chmod 755 cncli.sh\nchmod 755 logMonitor.sh\nchmod 755 gLiveView.sh\nchmod 755 blocks.sh\n

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3059\u308b

env\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u307e\u3059

PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n
sed -i $NODE_HOME/scripts/env \\\n  -e '1,73s!#CNODEBIN=\"${HOME}/.local/bin/cardano-node\"!CNODEBIN=\"/usr/local/bin/cardano-node\"!' \\\n  -e '1,73s!#CCLI=\"${HOME}/.local/bin/cardano-cli\"!CCLI=\"/usr/local/bin/cardano-cli\"!' \\\n  -e '1,73s!#CNCLI=\"${HOME}/.local/bin/cncli\"!CNCLI=\"${HOME}/.cargo/bin/cncli\"!' \\\n  -e '1,73s!#CNODE_HOME=\"/opt/cardano/cnode\"!CNODE_HOME='${NODE_HOME}'!' \\\n  -e '1,73s!#CNODE_PORT=6000!CNODE_PORT='${b_PORT}'!' \\\n  -e '1,73s!#UPDATE_CHECK=\"Y\"!UPDATE_CHECK=\"N\"!' \\\n  -e '1,73s!#CONFIG=\"${CNODE_HOME}/files/config.json\"!CONFIG=\"${CNODE_HOME}/'${NODE_CONFIG}'-config.json\"!' \\\n  -e '1,73s!#SOCKET=\"${CNODE_HOME}/sockets/node0.socket\"!SOCKET=\"${CNODE_HOME}/db/socket\"!' \\\n  -e '1,73s!#BLOCKLOG_TZ=\"UTC\"!BLOCKLOG_TZ=\"Asia/Tokyo\"!' \\\n  -e '1,73s!#POOL_NAME=\"\"!POOL_DIR=${CNODE_HOME}!'\n

cncli.sh\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u307e\u3059

\u30d7\u30fc\u30ebID\u3092\u78ba\u8a8d\u3059\u308b\u3002\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u3059\u3079\u3066\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

pool_hex=`cat $NODE_HOME/pool.id`\npool_bech32=`cat $NODE_HOME/pool.id-bech32`\nprintf \"\\n\u30d7\u30fc\u30ebID(hex)\u306f \\e[32m${pool_hex}\\e[m \u3067\u3059\\n\\n\"\nprintf \"\\n\u30d7\u30fc\u30ebID(bech32)\u306f \\e[32m${pool_bech32}\\e[m \u3067\u3059\\n\\n\"\n

\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30ebID 2\u7a2e\u985e\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044 \u30d7\u30fc\u30ebID\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u3001\u3053\u3061\u3089\u306e\u624b\u9806\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cncli.sh\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3057\u307e\u3059\u3002\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u3059\u3079\u3066\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

sed -i $NODE_HOME/scripts/cncli.sh \\\n-e '1,73s!#POOL_ID=\"\"!POOL_ID=\"'${pool_hex}'\"!' \\\n-e '1,73s!#POOL_ID_BECH32=\"\"!POOL_ID_BECH32=\"'${pool_bech32}'\"!' \\\n-e '1,73s!#POOL_VRF_SKEY=\"\"!POOL_VRF_SKEY=\"${CNODE_HOME}/vrf.skey\"!' \\\n-e '1,73s!#POOL_VRF_VKEY=\"\"!POOL_VRF_VKEY=\"${CNODE_HOME}/vrf.vkey\"!'\n

"},{"location":"setup/10-blocklog-setup/#10-4","title":"10-4. \u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210\u30fb\u767b\u9332","text":"
cd $NODE_HOME\nmkdir service\ncd service\n
cnclivalidateleaderloglogmonitor
cat > $NODE_HOME/service/cnode-cncli-sync.service << EOF \n# file: /etc/systemd/system/cnode-cncli-sync.service\n\n[Unit]\nDescription=Cardano Node - CNCLI sync\nBindsTo=cardano-node.service\nAfter=cardano-node.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME/scripts\nExecStart=/bin/bash -c \"sleep 5;/usr/bin/tmux new -d -s cncli\"\nExecStartPost=/usr/bin/tmux send-keys -t cncli ./cncli.sh Space sync Enter\nExecStop=/usr/bin/tmux kill-session -t cncli\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-cncli-sync\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cardano-node.service\nEOF\n
cat > $NODE_HOME/service/cnode-cncli-validate.service << EOF \n# file: /etc/systemd/system/cnode-cncli-validate.service\n\n[Unit]\nDescription=Cardano Node - CNCLI validate\nBindsTo=cnode-cncli-sync.service\nAfter=cnode-cncli-sync.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME/scripts\nExecStart=/bin/bash -c \"sleep 10;/usr/bin/tmux new -d -s validate\"\nExecStartPost=/usr/bin/tmux send-keys -t validate ./cncli.sh Space validate Enter\nExecStop=/usr/bin/tmux kill-session -t validate\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-cncli-validate\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cnode-cncli-sync.service\nEOF\n
cat > $NODE_HOME/service/cnode-cncli-leaderlog.service << EOF \n# file: /etc/systemd/system/cnode-cncli-leaderlog.service\n\n[Unit]\nDescription=Cardano Node - CNCLI Leaderlog\nBindsTo=cnode-cncli-sync.service\nAfter=cnode-cncli-sync.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME/scripts\nExecStart=/bin/bash -c \"sleep 15;/usr/bin/tmux new -d -s leaderlog\"\nExecStartPost=/usr/bin/tmux send-keys -t leaderlog ./cncli.sh Space leaderlog Enter\nExecStop=/usr/bin/tmux kill-session -t leaderlog\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-cncli-leaderlog\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cnode-cncli-sync.service\nEOF\n
cat > $NODE_HOME/service/cnode-logmonitor.service << EOF \n# file: /etc/systemd/system/cnode-logmonitor.service\n\n[Unit]\nDescription=Cardano Node - CNCLI logmonitor\nBindsTo=cnode-cncli-sync.service\nAfter=cnode-cncli-sync.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME\nExecStart=/bin/bash -c \"sleep 20;/usr/bin/tmux new -d -s logmonitor\"\nExecStartPost=/usr/bin/tmux send-keys -t logmonitor $NODE_HOME/scripts/logMonitor.sh Enter\nExecStop=/usr/bin/tmux kill-session -t logmonitor\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-logmonitor\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cnode-cncli-sync.service\nEOF\n

\u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u306b\u30b3\u30d4\u30fc\u3057\u3066\u6a29\u9650\u3092\u4ed8\u4e0e\u3057\u307e\u3059

1\u884c\u305a\u3064\u30b3\u30de\u30f3\u30c9\u306b\u8cbc\u308a\u4ed8\u3051\u3066\u304f\u3060\u3055\u3044

sudo cp $NODE_HOME/service/cnode-cncli-sync.service /etc/systemd/system/cnode-cncli-sync.service\nsudo cp $NODE_HOME/service/cnode-cncli-validate.service /etc/systemd/system/cnode-cncli-validate.service\nsudo cp $NODE_HOME/service/cnode-cncli-leaderlog.service /etc/systemd/system/cnode-cncli-leaderlog.service\nsudo cp $NODE_HOME/service/cnode-logmonitor.service /etc/systemd/system/cnode-logmonitor.service\n

sudo chmod 644 /etc/systemd/system/cnode-cncli-sync.service\nsudo chmod 644 /etc/systemd/system/cnode-cncli-validate.service\nsudo chmod 644 /etc/systemd/system/cnode-cncli-leaderlog.service\nsudo chmod 644 /etc/systemd/system/cnode-logmonitor.service\n

\u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u6709\u52b9\u5316\u3057\u307e\u3059

sudo systemctl daemon-reload\nsudo systemctl enable cnode-cncli-sync.service\nsudo systemctl enable cnode-cncli-validate.service\nsudo systemctl enable cnode-cncli-leaderlog.service\nsudo systemctl enable cnode-logmonitor.service\n
"},{"location":"setup/10-blocklog-setup/#10-5-db","title":"10-5. \u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u3068DB\u3092\u540c\u671f","text":"

cncli-sync\u30b5\u30fc\u30d3\u30b9\u3092\u958b\u59cb\u3057\u3001\u30ed\u30b0\u753b\u9762\u3092\u8868\u793a\u3057\u307e\u3059

sudo systemctl start cnode-cncli-sync.service\ntmux a -t cncli\n

\u78ba\u8a8d

\u300c100.00% synced\u300d\u306b\u306a\u308b\u307e\u3067\u5f85\u3061\u307e\u3059\u3002 100%\u306b\u306a\u3063\u305f\u3089\u3001Ctrl+b\u3092\u62bc\u3057\u305f\u5f8c\u306b d \u3092\u62bc\u3057\u5143\u306e\u753b\u9762\u306b\u623b\u308a\u307e\u3059(\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5b9f\u884c\u306b\u5207\u308a\u66ff\u3048)

"},{"location":"setup/10-blocklog-setup/#10-6","title":"10-6. \u904e\u53bb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u5b9f\u7e3e\u53d6\u5f97","text":"
cd $NODE_HOME/scripts\n./cncli.sh init\n

tmux\u8d77\u52d5\u78ba\u8a8d

tmux ls\n

\u78ba\u8a8d

\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3057\u3066\u304b\u3089\u3001\u7d0420\u79d2\u5f8c\u306b4\u30d7\u30ed\u30b0\u30e9\u30e0\u304c\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u3067\u8d77\u52d5\u4e2d\u3067\u3042\u308c\u3070OK\u3067\u3059

  • cncli
  • leaderlog
  • validate
  • logmonitor

\u4fbf\u5229\u306a\u30b3\u30de\u30f3\u30c9

\u25cf\u5404\u7a2e\u30b5\u30fc\u30d3\u30b9\u3092\u30b9\u30c8\u30c3\u30d7\u3059\u308b\u65b9\u6cd5

sudo systemctl stop cnode-cncli-sync.service\n
\u4e0a\u8a18\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3068\u4ee5\u4e0b\u30b5\u30fc\u30d3\u30b9\u3082\u9023\u52d5\u3057\u3066\u6b62\u307e\u308a\u307e\u3059

  • cnode-cncli-validate.service
  • cnode-cncli-leaderlog.service
  • cnode-logmonitor.service

\u25cf\u5404\u7a2e\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b\u65b9\u6cd5

sudo systemctl reload-or-restart cnode-cncli-sync.service\n
\u4e0a\u8a18\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3068\u4ee5\u4e0b\u30b5\u30fc\u30d3\u30b9\u3082\u9023\u52d5\u3057\u3066\u6b62\u307e\u308a\u307e\u3059

  • cnode-cncli-validate.service
  • cnode-cncli-leaderlog.service
  • cnode-logmonitor.service

\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u30ed\u30b0\u753b\u9762\u3092\u78ba\u8a8d\u3057\u307e\u3059

validateleaderloglogmonitor

\u3053\u3061\u3089\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u306f\u751f\u6210\u3057\u305f\u30d6\u30ed\u30c3\u30af\u304c\u3001\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u4e0a\u306b\u8a18\u9332\u3055\u308c\u3066\u3044\u308b\u304b\u7167\u5408\u3059\u308b\u305f\u3081\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u3059

tmux a -t validate\n
\u4ee5\u4e0b\u306e\u8868\u793a\u306a\u3089\u6b63\u5e38\u3067\u3059\u3002
~ CNCLI Block Validation started ~\n
Ctrl+b\u3092\u62bc\u3057\u305f\u5f8c\u3059\u3050\u306bd \u3067\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5b9f\u884c\u306b\u5207\u308a\u66ff\u3048\u307e\u3059(\u30c7\u30bf\u30c3\u30c1)

\u3053\u3061\u3089\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u306f\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u3092\u81ea\u52d5\u7684\u306b\u7b97\u51fa\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3067\u3059\u3002 \u6b21\u30a8\u30dd\u30c3\u30af\u306e1.5\u65e5\u524d\u304b\u3089\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u7b97\u51fa\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

tmux a -t leaderlog\n

\u4ee5\u4e0b\u306e\u8868\u793a\u306a\u3089\u6b63\u5e38\u3067\u3059\u3002 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u4e88\u5b9a\u304c\u3042\u308b\u5834\u5408\u3001\u8868\u793a\u3055\u308c\u308b\u307e\u3067\u306b5\u5206\u307b\u3069\u304b\u304b\u308a\u307e\u3059\u3002

~ CNCLI Leaderlog started ~\n

Ctrl+b\u3092\u62bc\u3057\u305f\u5f8c\u3059\u3050\u306bd \u3067\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5b9f\u884c\u306b\u5207\u308a\u66ff\u3048\u307e\u3059(\u30c7\u30bf\u30c3\u30c1)

\u3053\u3061\u3089\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u306f\u30d7\u30fc\u30eb\u306e\u30ce\u30fc\u30c9\u30ed\u30b0\u304b\u3089\u30d6\u30ed\u30c3\u30af\u751f\u6210\u7d50\u679c\u3092\u62bd\u51fa\u3057\u307e\u3059\u3002

tmux a -t logmonitor\n

\u4ee5\u4e0b\u306e\u8868\u793a\u306a\u3089\u6b63\u5e38\u3067\u3059\u3002

~~ LOG MONITOR STARTED ~~\nmonitoring logs/node.json for traces\n
Ctrl+b\u3092\u62bc\u3057\u305f\u5f8c\u3059\u3050\u306bd \u3067\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u5b9f\u884c\u306b\u5207\u308a\u66ff\u3048\u307e\u3059(\u30c7\u30bf\u30c3\u30c1)

"},{"location":"setup/10-blocklog-setup/#10-8","title":"10-8. \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u3092\u8868\u793a\u3059\u308b","text":"

\u3053\u306e\u30c4\u30fc\u30eb\u3067\u306f\u4e0a\u8a18\u3067\u8a2d\u5b9a\u3057\u3066\u304d\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u7d44\u307f\u5408\u308f\u305b\u3001\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u306b\u5bfe\u3057\u3066\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u7d50\u679c\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u683c\u7d0d\u3057\u3001\u78ba\u8a8d\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

cd $NODE_HOME/scripts\n./blocks.sh\n

\u4fbf\u5229\u306a\u8a2d\u5b9a

\u30b9\u30af\u30ea\u30d7\u30c8\u3078\u306e\u30d1\u30b9\u3092\u901a\u3057\u3001\u4efb\u610f\u306e\u5358\u8a9e\u3067\u8d77\u52d5\u51fa\u6765\u308b\u3088\u3046\u306b\u3059\u308b\u3002

echo alias blocks=\"'cd $NODE_HOME/scripts; ./blocks.sh'\" >> $HOME/.bashrc\nsource $HOME/.bashrc\n

\u5358\u8a9e\u3092\u5165\u529b\u3059\u308b\u3060\u3051\u3067\u3001\u3069\u3053\u304b\u3089\u3067\u3082\u8d77\u52d5\u3067\u304d\u307e\u3059\u3002 blocks\u30fb\u30fb\u30fbblocks.sh

\uff08\uff53\uff09\u5b9f\u7e3e\u6982\u8981---\u30a8\u30dd\u30c3\u30af\u6bce\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u5b9f\u7e3e\u53c2\u7167 \uff08\uff45\uff09\u30a8\u30dd\u30c3\u30af\u8a73\u7d30---\u500b\u5225\u30a8\u30dd\u30c3\u30af\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304a\u3088\u3073\u751f\u6210\u5b9f\u7e3e\u53c2\u7167

\u30d6\u30ed\u30c3\u30af\u30b9\u30c6\u30fc\u30bf\u30b9

\u9805\u76ee \u610f\u5473 Leader \u30d6\u30ed\u30c3\u30af\u751f\u6210\u5272\u308a\u5f53\u3066\u6570 Ideal \u30a2\u30af\u30c6\u30a3\u30d6\u30b9\u30c6\u30fc\u30af\uff08\u30b7\u30b0\u30de\uff09\u306b\u57fa\u3065\u3044\u3066\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30d6\u30ed\u30c3\u30af\u6570\u306e\u671f\u5f85\u5024/\u7406\u60f3\u5024 Luck \u671f\u5f85\u5024\u306b\u304a\u3051\u308b\u5b9f\u969b\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u30b9\u30ed\u30c3\u30c8\u30ea\u30fc\u30c0\u30fc\u6570\u306e\u30d1\u30fc\u30bb\u30f3\u30c6\u30fc\u30b8 Adopted \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30d5\u30e9\u30b0 Confirmed \u751f\u6210\u3057\u305f\u30d6\u30ed\u30c3\u30af\u306e\u3046\u3061\u78ba\u5b9f\u306b\u30aa\u30f3\u30c1\u30a7\u30fc\u30f3\u3067\u3042\u308b\u3053\u3068\u304c\u691c\u8a3c\u3055\u308c\u305f\u30d6\u30ed\u30c3\u30af (\u30d6\u30ed\u30c3\u30af\u751f\u6210\u6210\u529f) Missed \u30b9\u30ed\u30c3\u30c8\u3067\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u304c\u3001 cncli DB \u306b\u306f\u8a18\u9332\u3055\u308c\u3066\u304a\u3089\u305a\u4ed6\u306e\u30d7\u30fc\u30eb\u304c\u3053\u306e\u30b9\u30ed\u30c3\u30c8\u306e\u305f\u3081\u306b\u30d6\u30ed\u30c3\u30af\u3092\u4f5c\u3063\u305f\u53ef\u80fd\u6027 Ghosted \u30d6\u30ed\u30c3\u30af\u306f\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u304c\u300cOrphans(\u5b64\u7acb\u30d6\u30ed\u30c3\u30af)\u300d\u3068\u306a\u3063\u3066\u304a\u308a\u307e\u3059\u3002 \u30b9\u30ed\u30c3\u30c8\u30d0\u30c8\u30eb\u30fb\u30cf\u30a4\u30c8\u30d0\u30c8\u30eb\u3067\u6557\u5317\u3057\u305f\u304b\u3001\u30d6\u30ed\u30c3\u30af\u4f1d\u64ad\u306e\u554f\u984c\u3067\u6709\u52b9\u306a\u30d6\u30ed\u30c3\u30af\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093 Stolen \u5225\u306e\u30d7\u30fc\u30eb\u306b\u6709\u52b9\u306a\u30d6\u30ed\u30c3\u30af\u304c\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u30b9\u30ed\u30c3\u30c8\u30d0\u30c8\u30eb\u3067\u6557\u5317\u3057\u305f\u53ef\u80fd\u6027 Invalid \u30d7\u30fc\u30eb\u306f\u30d6\u30ed\u30c3\u30af\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002base64\u3067\u30a8\u30f3\u30b3\u30fc\u30c9\u3055\u308c\u305f\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u304clogmonitor\u306b\u8868\u793a\u3055\u308c\u307e\u3059

Invalid\u306e\u30a8\u30e9\u30fc\u5185\u5bb9\u306f\u6b21\u306e\u30b3\u30fc\u30c9\u3067\u30c7\u30b3\u30fc\u30c9\u3067\u304d\u307e\u3059

echo (base64\u30b3\u30fc\u30c9\u3092\u5165\u308c\u308b) | base64 -d | jq -r\n

\u30e1\u30cb\u30e5\u30fc\u9805\u76ee\u304c\u6587\u5b57\u5316\u3051\u3059\u308b\u5834\u5408\u306f\u3001\u30b7\u30b9\u30c6\u30e0\u6587\u5b57\u30b3\u30fc\u30c9\u304c\u300cUTF-8\u300d\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

echo $LANG\n

"},{"location":"setup/10-blocklog-setup/#10-9","title":"10-9. \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u5f97\u3059\u308b","text":"

\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u306e\u30bf\u30a4\u30df\u30f3\u30b0\u306b\u3064\u3044\u3066

\u53d6\u5f97\u30bf\u30a4\u30df\u30f3\u30b0\u306f\u3001\u30a8\u30dd\u30c3\u30af\u30b9\u30ed\u30c3\u30c8\u304c\u7d04302400\u3092\u904e\u304e\u3066\u304b\u3089\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u5f97\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002(\u6b21\u30a8\u30dd\u30c3\u30af\u306e1.5\u65e5\u524d)

11.\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u3092\u5c0e\u5165\u3059\u308b\u3053\u3068\u3067\u300c\u81ea\u52d5\u53d6\u5f97\u300d\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002 \u30a8\u30dd\u30c3\u30af\u30b9\u30ed\u30c3\u30c8\u304c\u7d04302400\u3092\u904e\u304e\u308b\u3068\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u81ea\u52d5\u53d6\u5f97\u3057\u3001\u4efb\u610f\u306e\u901a\u77e5\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u306b\u901a\u77e5\u3057\u307e\u3059\u3002

\u5404\u81ea\u306e\u904b\u7528\u65b9\u91dd\u306b\u5408\u305b\u3066\u3001\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb \u300c\u81ea\u52d5\u53d6\u5f97\u300d\u307e\u305f\u306f \u300c\u624b\u52d5\u53d6\u5f97\u300d \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u300c\u624b\u52d5\u53d6\u5f97\u300d \u306e\u5834\u5408\u306f\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u624b\u52d5\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u5f97\u3059\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002

\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b(\u624b\u52d5\u53d6\u5f97\u306e\u5834\u5408)

tmux send-keys -t leaderlog './cncli.sh leaderlog' C-m\n
\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u72b6\u6cc1\u3092\u78ba\u8a8d\u3059\u308b
tmux a -t leaderlog\n

Tip

  • \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306e\u4e2d\u306bError: database is locked\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u3088\u304f\u3042\u308b\u8cea\u554f\u306eQ4.\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u6642\u300cError: database is locked\u300d\u304c\u8868\u793a\u3055\u308c\u308b\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044
  • Leaderslots: 0 - Ideal slots for epoch based on active stake: 0.01 - Luck factor 0%\u304c\u8868\u793a\u3055\u308c\u305f\u5834\u5408\u306f\u3001\u6b8b\u5ff5\u304c\u3089\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u3042\u308a\u307e\u305b\u3093\u3002
  • \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u304c\u78ba\u8a8d\u3067\u304d\u305f\u3089 Ctrl+b d \u3067\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u304f\u3060\u3055\u3044\u3002

1\u30a8\u30dd\u30c3\u30af\u30671\u30d6\u30ed\u30c3\u30af\u5272\u308a\u5f53\u3066\u3089\u308c\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u59d4\u4efb\u91cf\u306e\u76ee\u5b89\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002%\u306f\u78ba\u7387 1M 60% 2M 85% 3M 95%

\u30d7\u30fc\u30eb\u958b\u8a2d\u6642\u306f\u30012\u30a8\u30dd\u30c3\u30af\u5f8c\u304b\u3089\u5272\u308a\u5f53\u3066\u304c\u30b9\u30bf\u30fc\u30c8\u3057\u307e\u3059\u3002 303 \u30d7\u30fc\u30eb\u767b\u9332 304 \u5f85\u6a5f\u671f\u9593 \u6b21\u30a8\u30dd\u30c3\u30af\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u7b97\u51fa 305 \u59d4\u4efb\u6709\u52b9 \u30d6\u30ed\u30c3\u30af\u751f\u6210 306 \u5831\u916c\u8a08\u7b97 307 \u5831\u916c\u632f\u308a\u8fbc\u307f

\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u3092\u901a\u77e5\u3059\u308b

\u30d6\u30ed\u30c3\u30af\u30ed\u30b0DB\u306b\u4fdd\u5b58\u3055\u308c\u308b\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u3092LINE/Slack/discord/telegram\u306b\u901a\u77e5\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 \u8a2d\u5b9a\u624b\u9806\u306f\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u8a2d\u5b9a\u624b\u9806\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/10-blocklog-setup/#10-99cncli","title":"10-99.CNCLI\u66f4\u65b0\u624b\u9806","text":"

\u4ee5\u4e0b\u306f\u6700\u65b0\u7248\u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u305f\u5834\u5408\u306b\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cncli\u65e7\u30d0\u30fc\u30b8\u30e7\u30f3\u304b\u3089\u306e\u66f4\u65b0\u624b\u9806

\u6ce8\u610f

\uff11\u6642\u9593\u4ee5\u5185\u306b\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304b\u3089\u3001\u4ee5\u4e0b\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044

rustup update\nrustup target add x86_64-unknown-linux-musl\n
sudo apt update -y && sudo apt install -y automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw5 libtool autoconf musl-tools\n

cd $HOME/git/cncli\ngit fetch --all --prune\ngit checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)\ncargo install --path . --force\n
\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b
cncli --version\n

5.3.2 \u304c\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059

\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl reload-or-restart cardano-node\n

\u30ce\u30fc\u30c9\u304c\u540c\u671f\u3057\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

tmux a -t cncli\n

100% synced\u306b\u306a\u3063\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

\u5404\u30b5\u30fc\u30d3\u30b9\u3092\u8868\u793a\u3057\u3001env\u307e\u305f\u306fcncli.sh\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u3042\u308b\u5834\u5408\u306f\"n\"\u3067\u62d2\u5426

tmux a -t leaderlog\ntmux a -t validate\n

env\u307e\u305f\u306fcncli.sh\u306e\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u304c\u5fc5\u8981\u306b\u306a\u3063\u305f\u5834\u5408\u306f\u6539\u3081\u3066\u30a2\u30ca\u30a6\u30f3\u30b9\u3057\u307e\u3059\u3002

"},{"location":"setup/10-blocklog-setup/#_1","title":"\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306b\u306a\u3044\u30d6\u30ed\u30c3\u30af\u304c\u751f\u6210\u3055\u308c\u308b\u5834\u5408","text":"

CNCLI\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u6b63\u3057\u3044\u5024\u304c\u53d6\u5f97\u3067\u304d\u3066\u3044\u308c\u3070\u3001100%\u6b63\u78ba\u3067\u3059\u3002 cncli.db\u3092\u518d\u4f5c\u6210\u3059\u308b\u3053\u3068\u3067\u6b63\u3057\u3044\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u53d6\u5f97\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002

\u4fee\u6b63\u624b\u9806

\u30fb\u30b5\u30fc\u30d3\u30b9\u3092\u6b62\u3081\u308b

sudo systemctl stop cnode-cncli-sync.service\n

cncli.db\u3092\u524a\u9664\u3059\u308b

cd $NODE_HOME/guild-db/cncli\nrm cncli.db\n

\u30b5\u30fc\u30d3\u30b9\u3092\u8d77\u52d5\u3057\u3001\u540c\u671f\u304c100\uff05\u306b\u306a\u308b\u307e\u3067\u5f85\u3064

sudo systemctl start cnode-cncli-sync.service\ntmux a -t cncli\n

\u30ea\u30fc\u30c0\u30fc\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u518d\u53d6\u5f97\u3059\u308b

tmux a -t leaderlog\n(Ctrl+C)\u3067\u51e6\u7406\u3092\u4e2d\u65ad\u3059\u308b\n$NODE_HOME/scripts/cncli.sh leaderlog force\n
\u904e\u53bb\u306e\u30d6\u30ed\u30c3\u30af\u751f\u6210\u5b9f\u7e3e\u3092DB\u306b\u767b\u9332\u3059\u308b
cd $NODE_HOME/scripts\n./cncli.sh init\n

"},{"location":"setup/11-blocknotify-setup/","title":"** \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5 **","text":"

\u6982\u8981

\u6700\u7d42\u66f4\u65b0\u65e5\uff1a2023/09/28 v1.9.5

  • \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u3067\u8868\u793a\u3055\u308c\u308b\u30d6\u30ed\u30c3\u30af\u751f\u6210\u7d50\u679c\u3092\u4efb\u610f\u306e\u30bd\u30fc\u30b7\u30e3\u30eb\u30a2\u30d7\u30ea\u3078\u901a\u77e5\u3057\u307e\u3059\u3002

  • \u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u81ea\u52d5\u53d6\u5f97\u3057\u3001\u53d6\u5f97\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u4e00\u89a7\u3092\u901a\u77e5\u3057\u307e\u3059\u3002

  • \u901a\u77e5\u5148\u5bfe\u5fdc\u30a2\u30d7\u30ea LINE/Slack/discord/telegram

  • \u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u3068\u9023\u52d5\u3057\u3066\u304a\u308a\u307e\u3059\u306e\u3067\u3001\u307e\u3060\u8a2d\u5b9a\u3055\u308c\u3066\u306a\u3044\u5834\u5408\u306f\u30d6\u30ed\u30c3\u30af\u30ed\u30b0\u5c0e\u5165\u624b\u9806\u3092\u5148\u306b\u5c0e\u5165\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • \u4ee5\u4e0b\u306e\u4f5c\u696d\u306fguild-db\u304c\u5b58\u5728\u3059\u308bBP\u30b5\u30fc\u30d0\u30fc\u306e\u307f\u3067\u5b9f\u65bd\u3057\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u306a\u3044\u30bf\u30a4\u30df\u30f3\u30b0\u3067\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • \u8a2d\u5b9a\u306f\u4efb\u610f\u3067\u3059\u3002(\u8a2d\u5b9a\u3057\u306a\u304f\u3066\u3082\u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5f71\u97ff\u306f\u3042\u308a\u307e\u305b\u3093)

\u66f4\u65b0\u5c65\u6b74\u25bc
  • 1.9.5\u3000\u30fbLINE\u901a\u77e5\u4e0d\u5177\u5408\u4fee\u6b63
  • 1.9.4\u3000\u30fb\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u30b9\u30ed\u30c3\u30c8\u3092303300\uff5e317700\u9593\u3067\u30e9\u30f3\u30c0\u30e0\u5316
  • 1.9.0\u3000\u30fb\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u6642\u306e\u30a8\u30e9\u30fc\u4fee\u6b63
  • 1.8.9\u3000\u30fb\u30a8\u30dd\u30c3\u30af\u5883\u754c\u306e\u901a\u77e5\u5185\u5bb9\u4e0d\u5177\u5408\u4fee\u6b63 \u3000\u3000\u3000\u30fb\u901a\u77e5\u5185\u5bb9\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u5909\u66f4

  • 1.8.8 \u30fb\u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u30b5\u30fc\u30d3\u30b9\u8d77\u52d5\u6642\u306b\u901a\u77e5 \u3000\u3000\u3000\u30fb\u901a\u77e5\u5148\u30c8\u30fc\u30af\u30f3\u672a\u5165\u529b\u306e\u5834\u5408\u306b\u30b5\u30fc\u30d3\u30b9\u753b\u9762\u3067\u30a8\u30e9\u30fc\u6392\u51fa

  • 1.8.7 \u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u5f8c\u3001\u901a\u77e5\u3055\u308c\u306a\u3044\u4e0d\u5177\u5408\u3092\u4fee\u6b63
  • 1.8.6 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u81ea\u52d5\u5316\u5c0e\u5165(\u9078\u629e\u5f0f) \u3000\u3000\u3000\u30fb\u53d6\u5f97\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u4e00\u89a7\u901a\u77e5
  • 1.7 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u30bf\u30a4\u30df\u30f3\u30b0\u901a\u77e5 \u3000\u3000\u3000\u30fb\u751f\u6210\u30d6\u30ed\u30c3\u30af\u306ePooltool\u30ea\u30f3\u30af\u8ffd\u52a0
  • 1.6 \u30d6\u30ed\u30c3\u30af\u672a\u751f\u6210\u30d7\u30fc\u30eb\u3067\u4f7f\u7528\u3059\u308b\u5834\u5408\u306e\u8d77\u52d5\u6642\u30a8\u30e9\u30fc\u3092\u4fee\u6b63
  • 1.5 10\u5206\u4ee5\u5185\u306b\u8907\u6570\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u3042\u308b\u5834\u5408\u306e\u901a\u77e5\u30d0\u30b0\u4fee\u6b63
  • 1.4 \u6b21\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3092\u8868\u793a
  • 1.3 \u30ce\u30fc\u30c9\u518d\u8d77\u52d5\u6642\u306e\u4e0d\u5177\u5408\u3092\u4fee\u6b63
  • 1.2.3 \u30a8\u30dd\u30c3\u30af\u53d6\u5f97\u30d5\u30ed\u30fc\u4fee\u6b63
  • 1.2.2 \u901a\u77e5\u30d0\u30b0\u4fee\u6b63
  • 1.2 \u30fbTelegram\u3001Slack\u306b\u5bfe\u5fdc \u3000\u3000\u3000\u30fb\u901a\u77e5\u57fa\u6e96\u8a2d\u5b9a( \u5168\u3066/confirm\u4ee5\u5916\u5168\u3066/Missed\u3068ivaild\u306e\u307f) \u3000\u3000\u3000\u30fb\u901a\u77e5\u5185\u5bb9\u3092\u5909\u66f4(X\u756a\u76ee/\u30c8\u30fc\u30bf\u30eb\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u6570)
  • 1.1 \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u6642\u3001\u305d\u306e\u4ed6\u901a\u77e5\u5224\u5b9a\u4fee\u6b63
  • 1.0.1 \u8efd\u5fae\u306a\u4fee\u6b63
  • 1.0 \u521d\u7248\u30ea\u30ea\u30fc\u30b9
"},{"location":"setup/11-blocknotify-setup/#11-1","title":"11-1. \u4f9d\u5b58\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b","text":""},{"location":"setup/11-blocknotify-setup/#python","title":"Python\u74b0\u5883\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3059\u308b","text":"

python\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u78ba\u8a8d\u3059\u308b

python3 -V\n

Python 3.8.10\u4ee5\u4e0a

\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u66f4\u65b0\u3059\u308b

sudo apt update -y\n

sudo apt install -y python3-watchdog python3-tz python3-dateutil python3-requests build-essential libssl-dev libffi-dev python3-dev python3-pip\n
pip install discordwebhook python-dotenv slackweb\n

"},{"location":"setup/11-blocknotify-setup/#_2","title":"\u5b9f\u884c\u30b9\u30af\u30ea\u30d7\u30c8\u3068\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b","text":"
cd $NODE_HOME/guild-db/blocklog\nwget -N https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/block_check.py\nwget -N https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/.env\nchmod 755 block_check.py\n
"},{"location":"setup/11-blocknotify-setup/#cnclish","title":"cncli.sh\u9069\u7528\u72b6\u614b\u78ba\u8a8d","text":"

** cncli.sh\u9069\u7528\u72b6\u614b\u3092\u78ba\u8a8d\u3059\u308b** \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u81ea\u52d5\u5316\u306b\u306fKOIOS-API\u5bfe\u5fdc\u306ecncli.sh\u304c\u5fc5\u8981\u3068\u306a\u308a\u307e\u3059\u3002\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cat $NODE_HOME/scripts/cncli.sh | grep -o '#USE_KOIOS_API=Y'\n

\u623b\u308a\u5024\u78ba\u8a8d

\u623b\u308a\u5024\u3042\u308a\u623b\u308a\u5024\u306a\u3057

#USE_KOIOS_API=Y \u306e\u623b\u308a\u5024\u304c\u3042\u308c\u3070\u3001\u5bfe\u5fdc\u3059\u308bcncli.sh\u304c\u9069\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002 \u6b21\u3078\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002

  • cardano-node1.35.5\u3078\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30ce\u30fc\u30c91.35.5\u9069\u7528\u6e08\u306e\u65b9\u306fGuild\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
"},{"location":"setup/11-blocknotify-setup/#11-2","title":"11-2. \u901a\u77e5\u30a2\u30d7\u30ea\u306e\u8a2d\u5b9a","text":"

\u901a\u77e5\u3055\u305b\u305f\u3044\u30a2\u30d7\u30ea\u306e\u30bf\u30d6\u3092\u30af\u30ea\u30c3\u30af\u3057\u8a2d\u5b9a\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

LINEDiscordTelegramSlack
  • 1.LINE\u30b0\u30eb\u30fc\u30d7\u3092\u4f5c\u6210\u3059\u308b

  • 2.\u300cLine Notify\u300d\u3092\u8ffd\u52a0\u3059\u308b

  • 3.\u4efb\u610f\u306e\u30b0\u30eb\u30fc\u30d7\u540d\u3092\u8a2d\u5b9a\u3057\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 4.LINE Notify\u30de\u30a4\u30da\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b

  • 5.\u30c8\u30fc\u30af\u30f3\u3092\u767a\u884c\u3059\u308b\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059

  • 6.\u30c8\u30fc\u30af\u30f3\u540d\u300c\u30d6\u30ed\u30c3\u30af\u751f\u6210\u901a\u77e5\u300d(\u4efb\u610f)\u3092\u5165\u529b\u3057\u30013\u3067\u4f5c\u6210\u3057\u305f\u30b0\u30eb\u30fc\u30d7\u540d\u3092\u9078\u629e\u3059\u308b

  • 7.\u300c\u767a\u884c\u3059\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 8.\u8868\u793a\u3055\u308c\u305f\u30c8\u30fc\u30af\u30f3\u3092\u30b3\u30d4\u30fc\u3057\u3001\u4e00\u65e6\u30e1\u30e2\u5e33\u306a\u3069\u306b\u8cbc\u308a\u4ed8\u3051\u308b \uff08\u767a\u884c\u3055\u308c\u305f\u30c8\u30fc\u30af\u30f3\u3092\u9589\u3058\u308b\u30682\u5ea6\u3068\u78ba\u8a8d\u3067\u304d\u307e\u305b\u3093\u306e\u3067\u3054\u6ce8\u610f\u304f\u3060\u3055\u3044\uff09

  • 1.\u30b5\u30fc\u30d0\u30fc\u3092\u8ffd\u52a0\u3059\u308b

  • 2.\u300c\u30aa\u30ea\u30b8\u30ca\u30eb\u306e\u4f5c\u6210\u300d\u3092\u9078\u629e\u3059\u308b

  • 3.\u300c\u81ea\u5206\u3068\u53cb\u9054\u306e\u305f\u3081\u300d\u3092\u9078\u629e\u3059\u308b

  • 4.\u4efb\u610f\u306e\u30b5\u30fc\u30d0\u30fc\u540d\u3092\u5165\u529b\u3057\u3066\u300c\u65b0\u898f\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 5.\u901a\u77e5\u3057\u305f\u3044\u30c1\u30e3\u30f3\u30cd\u30eb\u306e\u6b6f\u8eca\u30de\u30fc\u30af\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 6.\u300c\u9023\u643a\u30b5\u30fc\u30d3\u30b9\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u300c\u30a6\u30a7\u30d6\u30d5\u30c3\u30af\u3092\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 7.\u300c\u30a6\u30a7\u30d6\u30d5\u30c3\u30afURL\u3092\u30b3\u30d4\u30fc\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u4e00\u65e6\u30e1\u30e2\u5e33\u306a\u3069\u306b\u8cbc\u308a\u4ed8\u3051\u308b

  • 1.Telegram\u306e\u691c\u7d22\u6b04\u3067\u300c@botFather\u300d\u3092\u691c\u7d22\u3057\u3066\u8a8d\u8a3c\u30de\u30fc\u30af\u4ed8\u304d\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 2.\u300cSTART\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 3.\u300c/newbot\u300d\u30b3\u30de\u30f3\u30c9\u3092\u5165\u529b\u3059\u308b

  • 4.\u4efb\u610f\u306ebot\u540d\u3092\u5165\u529b\u3059\u308b \u4f8b\uff09\u300cbtbf_bot\u300d\u6700\u5f8c\u306f\u5fc5\u305a_bot\u3067\u7d42\u308f\u308b\u3088\u3046\u306b\u3059\u308b

  • 5.\u7dd1\u3067\u96a0\u3057\u305f\u90e8\u5206\u306eAPI\u30c8\u30fc\u30af\u30f3\u3092\u30e1\u30e2\u5e33\u306b\u63a7\u3048\u308b

  • 6.\u8d64\u67a0\u3067\u56f2\u3063\u305fbot\u30c1\u30e3\u30f3\u30cd\u30eb\u306b\u53c2\u52a0\u3059\u308b

  • 7.\u691c\u7d22\u6b04\u3067\u300c@RawDataBot\u300d\u3092\u691c\u7d22\u3057\u3066\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 8.\u300cSTART\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

  • 9.\u300cChat id\u300d\u3092\u30e1\u30e2\u5e33\u306b\u63a7\u3048\u308b

  • 1.Slack\u3092\u8d77\u52d5\u3057\u3001\u901a\u77e5\u7528\u306e\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3068\u30c1\u30e3\u30f3\u30cd\u30eb\u3092\u8a2d\u5b9a\u3059\u308b

  • 2.Incoming Webhook\u306e\u8a2d\u5b9a\u30da\u30fc\u30b8\u3078\u30a2\u30af\u30bb\u30b9\u3059\u308b

  • 3.\u901a\u77e5\u3057\u305f\u3044\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3068\u30c1\u30e3\u30f3\u30cd\u30eb\u3092\u9078\u629e\u3059\u308b

  • 4.\u300cWebhook URL\u300d\u3092\u30e1\u30e2\u5e33\u306b\u63a7\u3048\u308b

  • 5.\u30da\u30fc\u30b8\u4e0b\u90e8\u306e\u300c\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3059\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

"},{"location":"setup/11-blocknotify-setup/#11-3","title":"11-3. \u901a\u77e5\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u8a2d\u5b9a","text":""},{"location":"setup/11-blocknotify-setup/#_3","title":"\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u7de8\u96c6","text":"
cd $NODE_HOME/guild-db/blocklog\nnano .env\n

.env\u306f\u96a0\u3057\u30d5\u30a1\u30a4\u30eb\u306b\u306a\u3063\u3066\u3044\u308b\u306e\u3067\u3001ls -a\u30b3\u30de\u30f3\u30c9\u3067\u4e00\u89a7\u8868\u793a\u3055\u308c\u307e\u3059\u3002

env\u30d5\u30a1\u30a4\u30eb\u5185\u5bb9\u8a73\u7d30

\u9805\u76ee \u4f7f\u7528\u7528\u9014 ticker \u30d7\u30fc\u30eb\u30c6\u30a3\u30c3\u30ab\u30fc\u540d\u3092\u5165\u529b\u3059\u308b line_notify_token Line Notify\u30c8\u30fc\u30af\u30f3\u3092\u5165\u529b\u3059\u308b dc_notify_url Discord\u30a6\u30a7\u30d6\u30d5\u30c3\u30afURL\u3092\u5165\u529b\u3059\u308b slack_notify_url Slack\u30a6\u30a7\u30d6\u30d5\u30c3\u30afURL\u3092\u5165\u529b\u3059\u308b teleg_token Telegram API\u30c8\u30fc\u30af\u30f3\u3092\u5165\u529b\u3059\u308b teleg_id Telegram ChatID\u3092\u5165\u529b\u3059\u308b b_timezone \u304a\u4f4f\u3044\u306e\u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u3092\u6307\u5b9a\u3059\u308b bNotify \u901a\u77e5\u5148\u3092\u6307\u5b9a\u3059\u308b bNotify_st \u901a\u77e5\u57fa\u6e96\u3092\u8a2d\u5b9a\u3059\u308b auto_leader \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u65b9\u6cd5\u3092\u8a2d\u5b9a\u3059\u308b
  • \u5404\u81ea\u306e\u904b\u7528\u65b9\u91dd\u306b\u5408\u305b\u3066\u3001\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb \u300c\u81ea\u52d5\u53d6\u5f97\u300d\u307e\u305f\u306f \u300c\u624b\u52d5\u53d6\u5f97\u300d \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u300c\u81ea\u52d5\u53d6\u5f97\u300d \u306f\u3001\u30a8\u30dd\u30c3\u30af\u30b9\u30ed\u30c3\u30c8\u304c\u7d04302400\u3092\u904e\u304e\u3066\u304b\u3089\u81ea\u52d5\u7684\u306b\u767a\u52d5\u3057\u307e\u3059\u3002
  • \u300c\u624b\u52d5\u53d6\u5f97\u300d \u306f\u3001\u624b\u52d5\u3067\u306e\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u306b\u3088\u308b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u3068\u306a\u308a\u307e\u3059\u3002
"},{"location":"setup/11-blocknotify-setup/#_4","title":"\u30b5\u30fc\u30d3\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u8a2d\u5b9a\u3059\u308b","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cat > $NODE_HOME/service/cnode-blockcheck.service << EOF \n# file: /etc/systemd/system/cnode-blockcheck.service\n\n[Unit]\nDescription=Cardano Node - CNCLI blockcheck\nBindsTo=cnode-cncli-sync.service\nAfter=cnode-cncli-sync.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nRestart=on-failure\nRestartSec=20\nUser=$(whoami)\nWorkingDirectory=$NODE_HOME\nExecStart=/usr/bin/tmux new -d -s blockcheck\nExecStartPost=/usr/bin/tmux send-keys -t blockcheck 'cd $NODE_HOME/guild-db/blocklog' Enter\nExecStartPost=/usr/bin/tmux send-keys -t blockcheck python3 Space block_check.py Enter\nExecStop=/usr/bin/tmux kill-session -t blockcheck\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nSuccessExitStatus=143\nStandardOutput=syslog\nStandardError=syslog\nSyslogIdentifier=cnode-blockcheck\nTimeoutStopSec=5\n\n[Install]\nWantedBy=cnode-cncli-sync.service\nEOF\n
sudo cp $NODE_HOME/service/cnode-blockcheck.service /etc/systemd/system/cnode-blockcheck.service\nsudo chmod 644 /etc/systemd/system/cnode-blockcheck.service\n

sudo systemctl daemon-reload\nsudo systemctl enable cnode-blockcheck.service\n
\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b
sudo systemctl reload-or-restart cardano-node\n

"},{"location":"setup/11-blocknotify-setup/#_5","title":"\u8d77\u52d5\u78ba\u8a8d","text":"
tmux a -t blockcheck\n

\u300cGuild-db monitoring started\u300d \u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308c\u3070OK\u3067\u3059 \u4efb\u610f\u306e\u901a\u77e5\u5148\u306b\u901a\u77e5\u304c\u5c4a\u3044\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044 cnode-cncli-sync.service\u3068\u540c\u3058\u304f\u3001node\u518d\u8d77\u52d5\u30fb\u505c\u6b62\u3068\u9023\u52d5\u3057\u307e\u3059

"},{"location":"setup/11-blocknotify-setup/#_6","title":"\u901a\u77e5\u78ba\u8a8d","text":"

\u30d6\u30ed\u30c3\u30af\u751f\u6210\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u4e88\u5b9a\u6642\u523b\u304c\u904e\u304e\u3066\u304b\u3089\u3001\u7d0415\u5206\u4ee5\u5185\u306b\u901a\u77e5\u304c\u5c4a\u304d\u307e\u3059\u3002

"},{"location":"setup/11-blocknotify-setup/#11-4","title":"11-4. \u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u624b\u9806","text":"

\u30b5\u30fc\u30d3\u30b9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop cnode-blockcheck.service\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

cd $NODE_HOME/guild-db/blocklog\ncat block_check.py | grep -HnI -m1 -r btbf\n

\u30d0\u30fc\u30b8\u30e7\u30f31.7\u4ee5\u4e0b\u306e\u5834\u5408\u306f\u3053\u3061\u3089\u3092\u5148\u306b\u5b9f\u884c\u3059\u308b(\u30af\u30ea\u30c3\u30af\u3057\u3066\u958b\u304f)

1) cncli.sh\u9069\u7528\u72b6\u614b\u3092\u78ba\u8a8d\u3059\u308b \u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u81ea\u52d5\u5316\u306b\u306fKOIOS-API\u5bfe\u5fdc\u306ecncli.sh\u304c\u5fc5\u8981\u3068\u306a\u308a\u307e\u3059\u3002\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cat $NODE_HOME/scripts/cncli.sh | grep -o '#USE_KOIOS_API=Y'\n

\u623b\u308a\u5024\u78ba\u8a8d

\u623b\u308a\u5024\u3042\u308a\u623b\u308a\u5024\u306a\u3057

#USE_KOIOS_API=Y \u306e\u623b\u308a\u5024\u304c\u3042\u308c\u3070\u3001\u5bfe\u5fdc\u3059\u308bcncli.sh\u304c\u9069\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002 2)\u3078\u9032\u3093\u3067\u304f\u3060\u3055\u3044\u3002

  • cardano-node1.35.5\u3078\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u30ce\u30fc\u30c91.35.5\u9069\u7528\u6e08\u306e\u65b9\u306fGuild\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u30a2\u30c3\u30d7\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

2) \u30b9\u30c6\u30fc\u30bf\u30b9\u901a\u77e5\u7528.env\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u3059\u308b

  • \u5404\u81ea\u306e\u904b\u7528\u65b9\u91dd\u306b\u5408\u305b\u3066\u3001\u6b21\u30a8\u30dd\u30c3\u30af\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb \u300c\u81ea\u52d5\u53d6\u5f97\u300d\u307e\u305f\u306f \u300c\u624b\u52d5\u53d6\u5f97\u300d \u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  • \u300c\u81ea\u52d5\u53d6\u5f97\u300d \u306f\u3001\u30a8\u30dd\u30c3\u30af\u30b9\u30ed\u30c3\u30c8\u304c\u7d04302400\u3092\u904e\u304e\u3066\u304b\u3089\u81ea\u52d5\u7684\u306b\u767a\u52d5\u3057\u307e\u3059\u3002
  • \u300c\u624b\u52d5\u53d6\u5f97\u300d \u306f\u3001\u624b\u52d5\u3067\u306e\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u306b\u3088\u308b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u53d6\u5f97\u3068\u306a\u308a\u307e\u3059\u3002
\u81ea\u52d5\u53d6\u5f97\u306b\u3059\u308b\u5834\u5408\u624b\u52d5\u53d6\u5f97\u306b\u3059\u308b\u5834\u5408
sed -i $NODE_HOME/guild-db/blocklog/.env \\\n-e '1,73s!###############################!\\n#\u30ea\u30fc\u30c0\u30fc\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u81ea\u52d5\u53d6\u5f97 \u81ea\u52d5:1 \u624b\u52d5:0\\nauto_leader = \"1\"!'\n
sed -i $NODE_HOME/guild-db/blocklog/.env \\\n-e '1,73s!###############################!\\n#\u30ea\u30fc\u30c0\u30fc\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u81ea\u52d5\u53d6\u5f97 \u81ea\u52d5:1 \u624b\u52d5:0\\nauto_leader = \"0\"!'\n

\u53c2\u8003

\u4e0a\u8a18\u3067\u5b9f\u884c\u3059\u308b\u30b3\u30de\u30f3\u30c9\u306f\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u81ea\u52d5/\u624b\u52d5\u5316\u306b\u5bfe\u5fdc\u3059\u308b\u30d5\u30e9\u30b0\u3092.env\u306b\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002

#\u30ea\u30fc\u30c0\u30fc\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u81ea\u52d5\u53d6\u5f97 \u81ea\u52d5:1 \u624b\u52d5:0\nauto_leader = \"1\"\n

\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

cd $NODE_HOME/guild-db/blocklog\nwget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/block_check.py -O block_check.py\n
\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d
cd $NODE_HOME/guild-db/blocklog\ncat block_check.py | grep -HnI -m1 -r btbf\n
\u73fe\u5728\u306e\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3

\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl start cnode-blockcheck.service\n

\u30b5\u30fc\u30d3\u30b9\u8d77\u52d5\u78ba\u8a8d

tmux a -t blockcheck\n

\u300cGuild-db monitoring started\u300d \u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308c\u3070OK\u3067\u3059\u3002(\u30c7\u30bf\u30c3\u30c1\u3057\u3066\u623b\u308b) \u4efb\u610f\u306e\u901a\u77e5\u5148\u306b\u901a\u77e5\u304c\u5c4a\u3044\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

"},{"location":"setup/11-blocknotify-setup/#20230928-v195-btbf","title":"2023/09/28 v1.9.5 @btbf","text":""},{"location":"setup/11-blocknotify-setup/#11-5","title":"11-5.\u901a\u77e5\u3092\u505c\u6b62(\u30a2\u30f3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb)\u3059\u308b\u624b\u9806","text":"
sudo systemctl stop cnode-blockcheck.service\nsudo systemctl disable cnode-blockcheck.service\nsudo rm /etc/systemd/system/cnode-blockcheck.service\n
"},{"location":"setup/2-node-setup/","title":"2. \u30ce\u30fc\u30c9\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30d0\u30fc\u30b8\u30e7\u30f3

Node CLI GHC Cabal 8.7.3 8.17.0.0 8.10.7 3.8.1.0
  • \u8907\u6570\u884c\u306e\u30b3\u30fc\u30c9\u3092\u30b3\u30fc\u30c9\u30dc\u30c3\u30af\u30b9\u306e\u30b3\u30d4\u30fc\u30dc\u30bf\u30f3\u3092\u4f7f\u7528\u3057\u3066\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u306b\u8cbc\u308a\u4ed8\u3051\u308b\u5834\u5408\u306f\u3001\u6700\u5f8c\u306e\u884c\u304c\u81ea\u52d5\u5b9f\u884c\u3055\u308c\u306a\u3044\u305f\u3081\u78ba\u8a8d\u306e\u4e0aEnter\u3092\u62bc\u3057\u3066\u30b3\u30fc\u30c9\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002
"},{"location":"setup/2-node-setup/#2-1","title":"2-1. \u4f9d\u5b58\u95a2\u4fc2\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30bf\u30fc\u30df\u30ca\u30eb\u3092\u8d77\u52d5\u3057\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5165\u529b\u3057\u307e\u3057\u3087\u3046\uff01

\u65b0\u3057\u3044TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u958b\u304f

tmux new -s build\n

\u307e\u305a\u306f\u3058\u3081\u306b\u3001\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u66f4\u65b0\u3057Ubuntu\u3092\u6700\u65b0\u306e\u72b6\u614b\u306b\u4fdd\u3061\u307e\u3059\u3002

sudo apt update -y && sudo apt upgrade -y\n
sudo apt install git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y\n

"},{"location":"setup/2-node-setup/#libsodium","title":"Libsodium\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
mkdir $HOME/git\ncd $HOME/git\ngit clone https://github.com/IntersectMBO/libsodium\ncd libsodium\ngit checkout dbb48cc\n./autogen.sh\n./configure\nmake\nmake check\nsudo make install\n

make\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u5f8c\u534a\u306b\u51fa\u73fe\u3059\u308b warning \u306f\u7121\u8996\u3057\u3066\u5927\u4e08\u592b\u3067\u3059\u3002

"},{"location":"setup/2-node-setup/#secp256k1","title":"Secp256k1\u30e9\u30a4\u30d6\u30e9\u30ea\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"
cd $HOME/git\ngit clone https://github.com/bitcoin-core/secp256k1.git\n
cd secp256k1/\ngit checkout ac83be33\n./autogen.sh\n./configure --prefix=/usr --enable-module-schnorrsig --enable-experimental\nmake\nmake check\n

\u623b\u308a\u5024\u78ba\u8a8d

Testsuite summary for libsecp256k1 0.1.0-pre\n============================================================================\n# TOTAL: 2\n# PASS:  2\n# SKIP:  0\n# XFAIL: 0\n# FAIL:  0\n# XPASS: 0\n# ERROR: 0\n============================================================================\n

PASS:2\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30b3\u30de\u30f3\u30c9\u3092\u5fc5\u305a\u5b9f\u884c\u3059\u308b

sudo make install\n

"},{"location":"setup/2-node-setup/#blst","title":"blst\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

1.blst\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9

cd $HOME/git\ngit clone https://github.com/supranational/blst\ncd blst\ngit checkout v0.3.10\n./build.sh\n

2.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210

\u3053\u306e\u30dc\u30c3\u30af\u30b9\u306f\u3059\u3079\u3066\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

cat > libblst.pc << EOF\nprefix=/usr/local\nexec_prefix=\\${prefix}\nlibdir=\\${exec_prefix}/lib\nincludedir=\\${prefix}/include\n\nName: libblst\nDescription: Multilingual BLS12-381 signature library\nURL: https://github.com/supranational/blst\nVersion: 0.3.10\nCflags: -I\\${includedir}\nLibs: -L\\${libdir} -lblst\nEOF\n

3.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u30b3\u30d4\u30fc

\u3053\u306e\u30dc\u30c3\u30af\u30b9\u306f1\u884c\u305a\u3064\u30b3\u30d4\u30fc\u3057\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044

sudo cp libblst.pc /usr/local/lib/pkgconfig/\nsudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp  /usr/local/include/\nsudo cp libblst.a /usr/local/lib\nsudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}\n
"},{"location":"setup/2-node-setup/#ghcup","title":"GHCUP\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5909\u6570\u8a2d\u5b9a

cd $HOME\nBOOTSTRAP_HASKELL_NONINTERACTIVE=1\nBOOTSTRAP_HASKELL_NO_UPGRADE=1\nBOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes\nBOOTSTRAP_HASKELL_ADJUST_BASHRC=1\nunset BOOTSTRAP_HASKELL_INSTALL_HLS\nexport BOOTSTRAP_HASKELL_NONINTERACTIVE BOOTSTRAP_HASKELL_INSTALL_STACK BOOTSTRAP_HASKELL_ADJUST_BASHRC\n

\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | bash\n

Cabal/GHC\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u3064\u3044\u3066

\u6700\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306fcardano-node/cli\u306e\u30d3\u30eb\u30c9\u306b\u5931\u6557\u3059\u308b\u305f\u3081\u5fc5\u305a\u4ee5\u4e0b\u3067\u6307\u5b9a\u3055\u308c\u305f\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cabal\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

source ~/.bashrc\nghcup upgrade\nghcup install cabal 3.8.1.0\nghcup set cabal 3.8.1.0\n

GHC\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

ghcup install ghc 8.10.7\nghcup set ghc 8.10.7\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

cabal update\ncabal --version\nghc --version\n

\u30c1\u30a7\u30c3\u30af

Cabal\u30d0\u30fc\u30b8\u30e7\u30f3\uff1a\u300c3.8.1.0\u300d GHC\u30d0\u30fc\u30b8\u30e7\u30f3\uff1a\u300c8.10.7\u300d\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u74b0\u5883\u5909\u6570\u3092\u8a2d\u5b9a\u3057\u30d1\u30b9\u3092\u901a\u3057\u307e\u3059\u3002 \u30ce\u30fc\u30c9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306f $NODE_HOME(\u4f8b\uff1a/home/user/cnode) \u306b\u8a2d\u5b9a\u3055\u308c\u307e\u3059\u3002

echo PATH=\"$HOME/.local/bin:$PATH\" >> $HOME/.bashrc\necho export LD_LIBRARY_PATH=\"/usr/local/lib:$LD_LIBRARY_PATH\" >> $HOME/.bashrc\necho export PKG_CONFIG_PATH=\"/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH\" >> $HOME/.bashrc\necho export NODE_HOME=$HOME/cnode >> $HOME/.bashrc\n

\u74b0\u5883\u5909\u6570\u306b\u63a5\u7d9a\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u6307\u5b9a\u3059\u308b

echo export NODE_CONFIG=mainnet >> $HOME/.bashrc\necho export NODE_NETWORK='\"--mainnet\"' >> $HOME/.bashrc\necho export CARDANO_NODE_NETWORK_ID=mainnet >> $HOME/.bashrc\n

\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u306e\u5834\u5408\u306f\u3053\u3061\u3089 Preview(\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8)PreProd(\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8)
echo export NODE_CONFIG=preview >> $HOME/.bashrc\necho export NODE_NETWORK='\"--testnet-magic 2\"' >> $HOME/.bashrc\necho export CARDANO_NODE_NETWORK_ID=2 >> $HOME/.bashrc\n
echo export NODE_CONFIG=preprod >> $HOME/.bashrc\necho export NODE_NETWORK='\"--testnet-magic 1\"' >> $HOME/.bashrc\necho export CARDANO_NODE_NETWORK_ID=1 >> $HOME/.bashrc\n

bashrc\u518d\u8aad\u307f\u8fbc\u307f

source $HOME/.bashrc\n

"},{"location":"setup/2-node-setup/#2-2","title":"2-2. \u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9","text":"

\u78ba\u8a8d

\u30d0\u30a4\u30ca\u30ea\u30fc\u30d5\u30a1\u30a4\u30eb\u306f\u5fc5\u305a\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3059\u308b\u3088\u3046\u306b\u3057\u3001\u6574\u5408\u6027\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002IOG\u306f\u73fe\u5728ARM\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u7528\u306e\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u3092\u63d0\u4f9b\u3057\u3066\u3044\u307e\u305b\u3093\u3002Raspberry Pi\u3092\u4f7f\u7528\u3057\u3066\u30d7\u30fc\u30eb\u3092\u69cb\u7bc9\u3059\u308b\u5834\u5408\u306f\u3001ARM\u7528\u30b3\u30f3\u30d1\u30a4\u30e9\u3067\u30b3\u30f3\u30d1\u30a4\u30eb\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

Git\u304b\u3089\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3001\u6700\u65b0\u306e\u30bf\u30b0\u306b\u5207\u308a\u66ff\u3048\u307e\u3059\u3002

cd $HOME/git\ngit clone https://github.com/IntersectMBO/cardano-node.git\ncd cardano-node\ngit fetch --all --recurse-submodules --tags\ngit checkout tags/8.7.3\n

Cabal\u306e\u30d3\u30eb\u30c9\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u69cb\u6210\u3057\u307e\u3059\u3002

cabal clean\ncabal update\ncabal configure --with-compiler=ghc-8.10.7\n

\u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002

cabal build cardano-cli cardano-node\n

\u30d2\u30f3\u30c8

\u30b5\u30fc\u30d0\u30b9\u30da\u30c3\u30af\u306b\u3088\u3063\u3066\u3001\u30d3\u30eb\u30c9\u5b8c\u4e86\u307e\u3067\u306b\u6570\u5206\u304b\u3089\u6570\u6642\u9593\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002

cardano-cli\u30d5\u30a1\u30a4\u30eb\u3068 cardano-node\u30d5\u30a1\u30a4\u30eb\u3092bin\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name \"cardano-cli\") /usr/local/bin/cardano-cli\n
sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name \"cardano-node\") /usr/local/bin/cardano-node\n

cardano-cli \u3068 cardano-node\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u6700\u65b0Git\u30bf\u30b0\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cardano-node version\ncardano-cli version\n

\u4ee5\u4e0b\u306e\u623b\u308a\u5024\u3092\u78ba\u8a8d\u3059\u308b

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10 git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

TMUX\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u9589\u3058\u308b

exit\n
"},{"location":"setup/2-node-setup/#2-3","title":"2-3. \u30ce\u30fc\u30c9\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4fee\u6b63","text":"

\u30ce\u30fc\u30c9\u69cb\u6210\u306b\u5fc5\u8981\u306a\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002 config.json\u3001genesis.json\u3001topology.json

mkdir $NODE_HOME\ncd $NODE_HOME\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/byron-genesis.json -O ${NODE_CONFIG}-byron-genesis.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/topology-legacy.json -O ${NODE_CONFIG}-topology.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/shelley-genesis.json -O ${NODE_CONFIG}-shelley-genesis.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/alonzo-genesis.json -O ${NODE_CONFIG}-alonzo-genesis.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/conway-genesis.json -O ${NODE_CONFIG}-conway-genesis.json\nwget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/config.json -O ${NODE_CONFIG}-config.json\n

\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3092\u5b9f\u884c\u3057 config.json\u30d5\u30a1\u30a4\u30eb\u3092\u66f4\u65b0\u3057\u307e\u3059\u3002

\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304d\u63db\u3048\u308b

sed -i ${NODE_CONFIG}-config.json \\\n    -e 's!\"EnableP2P\": true!\"EnableP2P\": false!' \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e \"s/TraceMempool\\\": false/TraceMempool\\\": true/g\" \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e 's!\"rpKeepFilesNum\": 10!\"rpKeepFilesNum\": 30!' \\\n    -e 's!\"rpMaxAgeHours\": 24!\"rpMaxAgeHours\": 48!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n
\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u306e\u5834\u5408\u306f\u3053\u3061\u3089
sed -i ${NODE_CONFIG}-config.json \\\n    -e 's!\"EnableP2P\": true!\"EnableP2P\": false!' \\\n    -e 's!\"AlonzoGenesisFile\": \"alonzo-genesis.json\"!\"AlonzoGenesisFile\": \"'${NODE_CONFIG}'-alonzo-genesis.json\"!' \\\n    -e 's!\"ByronGenesisFile\": \"byron-genesis.json\"!\"ByronGenesisFile\": \"'${NODE_CONFIG}'-byron-genesis.json\"!' \\\n    -e 's!\"ShelleyGenesisFile\": \"shelley-genesis.json\"!\"ShelleyGenesisFile\": \"'${NODE_CONFIG}'-shelley-genesis.json\"!' \\\n    -e 's!\"ConwayGenesisFile\": \"conway-genesis.json\"!\"ConwayGenesisFile\": \"'${NODE_CONFIG}'-conway-genesis.json\"!' \\\n    -e 's!\"TraceBlockFetchDecisions\": false!\"TraceBlockFetchDecisions\": true!' \\\n    -e '/\"defaultScribes\": \\[/a\\    \\[\\n      \"FileSK\",\\n      \"'${NODE_HOME}'/logs/node.json\"\\n    \\],' \\\n    -e '/\"setupScribes\": \\[/a\\    \\{\\n      \"scFormat\": \"ScJson\",\\n      \"scKind\": \"FileSK\",\\n      \"scName\": \"'${NODE_HOME}'/logs/node.json\"\\n    \\},' \\\n    -e \"s/127.0.0.1/0.0.0.0/g\"\n

\u74b0\u5883\u5909\u6570\u3092\u8ffd\u52a0\u3057\u3001.bashrc\u30d5\u30a1\u30a4\u30eb\u3092\u66f4\u65b0\u3057\u307e\u3059\u3002

echo export CARDANO_NODE_SOCKET_PATH=\"$NODE_HOME/db/socket\" >> $HOME/.bashrc\nsource $HOME/.bashrc\n
"},{"location":"setup/2-node-setup/#2-4","title":"2-4. \u30ce\u30fc\u30c9\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u4f5c\u6210","text":"

\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u306b\u306f\u3001\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3001\u30dd\u30fc\u30c8\u756a\u53f7\u3001DB\u30d1\u30b9\u3001\u69cb\u6210\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u306a\u3069\u3001\u30ab\u30eb\u30c0\u30ce\u30ce\u30fc\u30c9\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u5909\u6570\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002

\u5168\u884c\u3092\u30b3\u30d4\u30fc\u3057\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u306b\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u4f7f\u7528\u3059\u308b\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u6307\u5b9a\u3057\u3066\u30bf\u30fc\u30df\u30ca\u30eb\u3067\u5b9f\u884c\u3059\u308b

PORT=6000\n

\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

cat > $NODE_HOME/startRelayNode1.sh << EOF \n#!/bin/bash\nDIRECTORY=$NODE_HOME\nPORT=${PORT}\nHOSTADDR=0.0.0.0\nTOPOLOGY=\\${DIRECTORY}/${NODE_CONFIG}-topology.json\nDB_PATH=\\${DIRECTORY}/db\nSOCKET_PATH=\\${DIRECTORY}/db/socket\nCONFIG=\\${DIRECTORY}/${NODE_CONFIG}-config.json\n/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A16m -F1.5 -H2500M -RTS run --topology \\${TOPOLOGY} --database-path \\${DB_PATH} --socket-path \\${SOCKET_PATH} --host-addr \\${HOSTADDR} --port \\${PORT} --config \\${CONFIG}\nEOF\n

\u6ce8\u610f

  • BP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u306f\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u9ad8\u3081\u308b\u305f\u3081\u306b\u300149513\uff5e65535\u307e\u3067\u306e\u4efb\u610f\u756a\u53f7\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u3053\u3067\u8a2d\u5b9a\u3059\u308b\u756a\u53f7\u306f1-3\u3067\u8a2d\u5b9a\u3057\u305fSSH\u30dd\u30fc\u30c8\u756a\u53f7\u3068\u306f\u5225\u306e\u756a\u53f7\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044.

BP\u30ce\u30fc\u30c9\u3067\u4f7f\u7528\u3059\u308b\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u6307\u5b9a\u3057\u3066\u30bf\u30fc\u30df\u30ca\u30eb\u3067\u5b9f\u884c\u3059\u308b

PORT=xxxxx\n

\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b

cat > $NODE_HOME/startBlockProducingNode.sh << EOF \n#!/bin/bash\nDIRECTORY=$NODE_HOME\nPORT=${PORT}\nHOSTADDR=0.0.0.0\nTOPOLOGY=\\${DIRECTORY}/${NODE_CONFIG}-topology.json\nDB_PATH=\\${DIRECTORY}/db\nSOCKET_PATH=\\${DIRECTORY}/db/socket\nCONFIG=\\${DIRECTORY}/${NODE_CONFIG}-config.json\n/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A16m -F1.5 -H2500M -RTS run --topology \\${TOPOLOGY} --database-path \\${DB_PATH} --socket-path \\${SOCKET_PATH} --host-addr \\${HOSTADDR} --port \\${PORT} --config \\${CONFIG}\nEOF\n

"},{"location":"setup/2-node-setup/#2-5","title":"2-5. \u30ce\u30fc\u30c9\u8d77\u52d5","text":"

\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u306b\u5b9f\u884c\u6a29\u9650\u3092\u4ed8\u4e0e\u3057\u3001\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306e\u540c\u671f\u3092\u958b\u59cb\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u304b\u3089\u5b9f\u65bd\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nchmod +x startRelayNode1.sh\n./startRelayNode1.sh\n
cd $NODE_HOME\nchmod +x startBlockProducingNode.sh\n./startBlockProducingNode.sh\n

\u52e2\u3044\u3088\u304f\u30ed\u30b0\u304c\u6d41\u308c\u3066\u3044\u305f\u3089\u8d77\u52d5\u6210\u529f\u3067\u3059

\u4e00\u65e6\u30ce\u30fc\u30c9\u3092\u505c\u6b62\u3057\u307e\u3059\u3002

Ctrl+C\n

"},{"location":"setup/2-node-setup/#2-6-systemd","title":"2-6. \u81ea\u52d5\u8d77\u52d5\u306e\u8a2d\u5b9a(systemd)","text":"

\u5148\u7a0b\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u3060\u3051\u3067\u306f\u3001\u30bf\u30fc\u30df\u30ca\u30eb\u753b\u9762\u3092\u9589\u3058\u308b\u3068\u30ce\u30fc\u30c9\u304c\u7d42\u4e86\u3057\u3066\u3057\u307e\u3046\u306e\u3067\u3001\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u30b5\u30fc\u30d3\u30b9\u3068\u3057\u3066\u767b\u9332\u3057\u3001\u81ea\u52d5\u8d77\u52d5\u3059\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u3087\u3046

\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306bsystemd\u3092\u4f7f\u7528\u3059\u308b\u30e1\u30ea\u30c3\u30c8

  1. \u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u3084\u505c\u96fb\u306a\u3069\u3001\u81ea\u52d5\u7684\u306b\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u304c\u518d\u8d77\u52d5\u3057\u305f\u3068\u304d\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u81ea\u52d5\u8d77\u52d5\u3057\u307e\u3059\u3002
  2. \u30af\u30e9\u30c3\u30b7\u30e5\u3057\u305f\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u30d7\u30ed\u30bb\u30b9\u3092\u81ea\u52d5\u7684\u306b\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002
  3. \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306e\u7a3c\u50cd\u6642\u9593\u3068\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u30ec\u30d9\u30eb\u30a2\u30c3\u30d7\u3055\u305b\u307e\u3059\u3002

\u59cb\u3081\u308b\u524d\u306b\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u304c\u505c\u6b62\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

killall -s 2 cardano-node\n

\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u30e6\u30cb\u30c3\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cat > $NODE_HOME/cardano-node.service << EOF \n# The Cardano node service (part of systemd)\n# file: /etc/systemd/system/cardano-node.service \n\n[Unit]\nDescription     = Cardano node service\nWants           = network-online.target\nAfter           = network-online.target \n\n[Service]\nUser            = ${USER}\nType            = simple\nWorkingDirectory= ${NODE_HOME}\nExecStart       = /bin/bash -c '${NODE_HOME}/startRelayNode1.sh'\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nTimeoutStopSec=300\nLimitNOFILE=32768\nRestart=always\nRestartSec=5\nSyslogIdentifier=cardano-node\n\n[Install]\nWantedBy    = multi-user.target\nEOF\n
cat > $NODE_HOME/cardano-node.service << EOF \n# The Cardano node service (part of systemd)\n# file: /etc/systemd/system/cardano-node.service \n\n[Unit]\nDescription     = Cardano node service\nWants           = network-online.target\nAfter           = network-online.target \n\n[Service]\nUser            = ${USER}\nType            = simple\nWorkingDirectory= ${NODE_HOME}\nExecStart       = /bin/bash -c '${NODE_HOME}/startBlockProducingNode.sh'\nKillSignal=SIGINT\nRestartKillSignal=SIGINT\nTimeoutStopSec=300\nLimitNOFILE=32768\nRestart=always\nRestartSec=5\nSyslogIdentifier=cardano-node\n\n[Install]\nWantedBy    = multi-user.target\nEOF\n

/etc/systemd/system\u306b\u30e6\u30cb\u30c3\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3001\u6a29\u9650\u3092\u4ed8\u4e0e\u3057\u307e\u3059\u3002

sudo cp $NODE_HOME/cardano-node.service /etc/systemd/system/cardano-node.service\n
sudo chmod 644 /etc/systemd/system/cardano-node.service\n

\u6b21\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001OS\u8d77\u52d5\u6642\u306b\u30b5\u30fc\u30d3\u30b9\u306e\u81ea\u52d5\u8d77\u52d5\u3092\u6709\u52b9\u306b\u3057\u307e\u3059\u3002

sudo systemctl daemon-reload\nsudo systemctl enable cardano-node\nsudo systemctl start cardano-node\n
\u30b7\u30b9\u30c6\u30e0\u8d77\u52d5\u5f8c\u306b\u3001\u30ed\u30b0\u30e2\u30cb\u30bf\u30fc\u3092\u8868\u793a\u3057\u307e\u3059

journalctl --unit=cardano-node --follow\n

\u30b3\u30de\u30f3\u30c9\u5165\u529b\u306b\u623b\u308b\u5834\u5408\u306f\u300cCtrl\uff0bC\u300d\uff08\u3053\u306e\u5834\u5408\u30ce\u30fc\u30c9\u306f\u7d42\u4e86\u3057\u307e\u305b\u3093\uff09

"},{"location":"setup/2-node-setup/#_1","title":"\u4fbf\u5229\u306a\u30a8\u30a4\u30ea\u30a2\u30b9\u8a2d\u5b9a","text":"

\u30a8\u30a4\u30ea\u30a2\u30b9\u8a2d\u5b9a

\u30b9\u30af\u30ea\u30d7\u30c8\u3078\u306e\u30d1\u30b9\u3092\u901a\u3057\u3001\u4efb\u610f\u306e\u5358\u8a9e\u3067\u8d77\u52d5\u51fa\u6765\u308b\u3088\u3046\u306b\u3059\u308b\u3002

echo alias cnode='\"journalctl -u cardano-node -f\"' >> $HOME/.bashrc\necho alias cnstart='\"sudo systemctl start cardano-node\"' >> $HOME/.bashrc\necho alias cnrestart='\"sudo systemctl reload-or-restart cardano-node\"' >> $HOME/.bashrc\necho alias cnstop='\"sudo systemctl stop cardano-node\"' >> $HOME/.bashrc\nsource $HOME/.bashrc\n

\u5358\u8a9e\u3092\u5165\u529b\u3059\u308b\u3060\u3051\u3067\u3001\u8d77\u52d5\u72b6\u614b(\u30ed\u30b0)\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002

cnode \u30fb\u30fb\u30fb\u30ed\u30b0\u8868\u793a\ncnstart \u30fb\u30fb\u30fb\u30ce\u30fc\u30c9\u8d77\u52d5\ncnrestart \u30fb\u30fb\u30fb\u30ce\u30fc\u30c9\u518d\u8d77\u52d5\ncnstop \u30fb\u30fb\u30fb\u30ce\u30fc\u30c9\u505c\u6b62\n

"},{"location":"setup/2-node-setup/#2-7-gliveview","title":"2-7. gLiveView\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

cardano-node\u306f\u30ed\u30b0\u304c\u6d41\u308c\u308b\u753b\u9762\u3060\u3051\u3067\u306f\u4f55\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u306e\u304b\u3088\u304f\u308f\u304b\u308a\u307e\u305b\u3093\u3002 \u305d\u308c\u3092\u8996\u899a\u7684\u306b\u78ba\u8a8d\u3067\u304d\u308b\u30c4\u30fc\u30eb\u304cgLiveView\u3067\u3059\u3002

gLiveView\u306f\u91cd\u8981\u306a\u30ce\u30fc\u30c9\u30b9\u30c6\u30fc\u30bf\u30b9\u60c5\u5831\u3092\u8868\u793a\u3057\u3001systemd\u30b5\u30fc\u30d3\u30b9\u3068\u3046\u307e\u304f\u9023\u643a\u3057\u307e\u3059\u3002\u3053\u306e\u30c4\u30fc\u30eb\u3092\u4f5c\u6210\u3057\u305f Guild Operators \u306e\u529f\u7e3e\u306b\u3088\u308b\u3082\u306e\u3067\u3059\u3002

Guild LiveView\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002

mkdir $NODE_HOME/scripts\ncd $NODE_HOME/scripts\nsudo apt install bc tcptraceroute -y\n
curl -s -o gLiveView.sh https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh\ncurl -s -o env https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env\nchmod 755 gLiveView.sh\n

env \u30d5\u30a1\u30a4\u30eb\u5185\u306e\u5b9a\u7fa9\u3092\u4fee\u6b63\u3057\u307e\u3059

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
PORT=`grep \"PORT=\" $NODE_HOME/startRelayNode1.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"\u30ea\u30ec\u30fc\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n
PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n
sed -i $NODE_HOME/scripts/env \\\n    -e '1,73s!#CNODE_HOME=\"/opt/cardano/cnode\"!CNODE_HOME=${NODE_HOME}!' \\\n    -e '1,73s!#CNODE_PORT=6000!CNODE_PORT='${b_PORT}'!' \\\n    -e '1,73s!#UPDATE_CHECK=\"Y\"!UPDATE_CHECK=\"N\"!' \\\n    -e '1,73s!#CONFIG=\"${CNODE_HOME}/files/config.json\"!CONFIG=\"${CNODE_HOME}/'${NODE_CONFIG}'-config.json\"!' \\\n    -e '1,73s!#SOCKET=\"${CNODE_HOME}/sockets/node0.socket\"!SOCKET=\"${CNODE_HOME}/db/socket\"!'\n

Guild Liveview\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

./gLiveView.sh\n

GliveView\u8d77\u52d5\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\u30b3\u30fc\u30c9\u767b\u9332

\u30b9\u30af\u30ea\u30d7\u30c8\u3078\u306e\u30d1\u30b9\u3092\u901a\u3057\u3001\u4efb\u610f\u306e\u5358\u8a9e\u3067\u8d77\u52d5\u51fa\u6765\u308b\u3088\u3046\u306b\u3059\u308b\u3002

echo alias glive=\"'cd $NODE_HOME/scripts; ./gLiveView.sh'\" >> $HOME/.bashrc\nsource $HOME/.bashrc\n

\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u306bglive\u3068\u5165\u529b\u3059\u308b\u3060\u3051\u3067\u3001\u3069\u3053\u304b\u3089\u3067\u3082\u8d77\u52d5\u3067\u304d\u307e\u3059\u3002

gLiveView\u306b\u3064\u3044\u3066\u25bc
  • \u3053\u306e\u30c4\u30fc\u30eb\u3092\u7acb\u3061\u4e0a\u3052\u3066\u3082\u30ce\u30fc\u30c9\u306f\u8d77\u52d5\u3057\u307e\u305b\u3093\u3002\u30ce\u30fc\u30c9\u306f\u5225\u9014\u8d77\u52d5\u3057\u3066\u304a\u304f\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
  • \u30ea\u30ec\u30fc\uff0fBP\u306e\u81ea\u52d5\u5224\u5225\u306f\u3001\u624b\u98064-5\u7d42\u4e86\u5f8c\u306b\u884c\u308f\u308c\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002
  • \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u306f\u57fa\u672c\u60c5\u5831\u306b\u52a0\u3048\u3001\u30c8\u30dd\u30ed\u30b8\u30fc\u63a5\u7d9a\u72b6\u6cc1\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002
  • BP\u30ce\u30fc\u30c9\u3067\u306f\u57fa\u672c\u60c5\u5831\u306b\u52a0\u3048\u3001KES\u6709\u52b9\u671f\u9650\u3001\u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u6cc1\u3092\u78ba\u8a8d\u3067\u304d\u307e\u3059\u3002
CONECTIONS\u306b\u3064\u3044\u3066\u25bc

\u30ce\u30fc\u30c9\u306bping\u3092\u9001\u4fe1\u3059\u308b\u969bICMPping\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u63a5\u7d9a\u5148\u30ce\u30fc\u30c9\u306e\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u304cICMP\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u53d7\u3051\u4ed8\u3051\u308b\u5834\u5408\u306e\u307f\u6a5f\u80fd\u3057\u307e\u3059\u3002

\u91cd\u8981\uff1a\u30ce\u30fc\u30c9\u540c\u671f\u306b\u3064\u3044\u3066

0\u30a8\u30dd\u30c3\u30af\u304b\u3089\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u30c7\u30fc\u30bf\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u540c\u671f\u3057\u307e\u3059\u3002\u6700\u65b0\u30a8\u30dd\u30c3\u30af\u307e\u3067\u8ffd\u3044\u3064\u304f\u307e\u3067\u306b1\u65e5\u534a\uff5e2\u65e5\u304b\u304b\u308a\u3001\u5b8c\u5168\u306b\u540c\u671f\u3059\u308b\u307e\u3067\u6b21\u306e\u9805\u76ee\u306b\u306f\u9032\u3081\u307e\u305b\u3093\u3002 BP\u30b5\u30fc\u30d0\u30fc\u30842\u3064\u76ee\u306e\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u3067\u3082\u540c\u3058\u4f5c\u696d\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\uff1cMithril-Client\u306b\u3088\u308bDB\u540c\u671f(\u30d9\u30fc\u30bf\u7248)\uff1e Mithril-Client\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u7d042\u65e5\u304b\u304b\u3063\u3066\u3044\u305f\u521d\u56de\u306eDB\u540c\u671f\u6642\u9593\u3092\u7d0430\u5206\u4ee5\u5185\u306b\u307e\u3067\u77ed\u7e2e\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 \u624b\u9806\u306f\u3053\u3061\u3089\u2192DB\u540c\u671f(Mithril)

"},{"location":"setup/2-node-setup/#2-8","title":"2-8. \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3068\u306f\uff1f

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306f\u300c\u30b3\u30fc\u30eb\u30c9\u74b0\u5883\u300d\u3068\u547c\u3070\u308c\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b\u304a\u3044\u3066\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u9ad8\u3081\u308b\u65b9\u6cd5\u306e\u4e00\u3064\u3002 \u5b89\u5168\u306b\u3057\u305f\u3044\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u3084\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u3084\u5b89\u5168\u3067\u306a\u3044LAN\u3068\u3044\u3063\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u7269\u7406\u7684\u306b\u9694\u96e2\u3059\u308b\u3053\u3068\u3092\u6307\u3059\u3002

  • \u30d7\u30fc\u30eb\u904b\u55b6\u306b\u304a\u3044\u3066\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u3092\u7ba1\u7406\u3057\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u7f72\u540d\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002
  • \u30ad\u30fc\u30ed\u30ae\u30f3\u30b0\u653b\u6483\u3001\u30de\u30eb\u30a6\u30a8\u30a2\uff0f\u30a6\u30a4\u30eb\u30b9\u30d9\u30fc\u30b9\u306e\u653b\u6483\u3001\u305d\u306e\u4ed6\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3084\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30fc\u306e\u60aa\u7528\u304b\u3089\u4fdd\u8b77\u3057\u307e\u3059\u3002
  • \u6709\u7dda\u30fb\u7121\u7dda\u306e\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u306b\u306f\u63a5\u7d9a\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
  • \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u4e0a\u306b\u3042\u308bVM\u30de\u30b7\u30f3\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
  • \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u306b\u3064\u3044\u3066\u66f4\u306b\u8a73\u3057\u304f\u77e5\u308a\u305f\u3044\u5834\u5408\u306f\u3001\u3053\u3061\u3089\u3092\u53c2\u7167\u4e0b\u3055\u3044\u3002

\uff11\uff0e2-1. \u4f9d\u5b58\u95a2\u4fc2\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30682-2. \u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u304b\u3089\u30d3\u30eb\u30c9\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3067\u5b9f\u884c\u3059\u308b

\uff12\uff0e\u4ee5\u4e0b\u306e\u30d1\u30b9\u3092\u74b0\u5883\u5909\u6570\u306b\u30bb\u30c3\u30c8\u3057\u3001\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc\necho export PKG_CONFIG_PATH=\"/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH\" >> $HOME/.bashrc\necho export NODE_NETWORK=\"--mainnet\" >> $HOME/.bashrc\necho export CARDANO_NODE_NETWORK_ID=mainnet >> $HOME/.bashrc\nsource $HOME/.bashrc\nmkdir -p $NODE_HOME\n
\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u306e\u5834\u5408\u306f\u3053\u3061\u3089 Preview

echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc echo export PKG_CONFIG_PATH=\"/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH\" >> $HOME/.bashrc echo export NODE_CONFIG=preview >> $HOME/.bashrc echo export NODE_NETWORK='\"--testnet-magic 2\"' >> $HOME/.bashrc echo export CARDANO_NODE_NETWORK_ID=2 >> $HOME/.bashrc source $HOME/.bashrc mkdir -p $NODE_HOME

PreProd

echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc echo export PKG_CONFIG_PATH=\"/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH\" >> $HOME/.bashrc echo export NODE_CONFIG=preview >> $HOME/.bashrc echo export NODE_NETWORK='\"--testnet-magic 1\"' >> $HOME/.bashrc echo export CARDANO_NODE_NETWORK_ID=1 >> $HOME/.bashrc source $HOME/.bashrc mkdir -p $NODE_HOME

"},{"location":"setup/3-relay-bp-setup/","title":"3. \u30ea\u30ec\u30fc\u3068BP\u3092\u63a5\u7d9a\u3059\u308b","text":"

\u524d\u63d0\u6761\u4ef6

\u4ee5\u4e0b\u306e\u9805\u76ee\u3092\u5b9f\u65bd\u3059\u308b\u524d\u306b\u30ea\u30ec\u30fc/BP\u30ce\u30fc\u30c9\u304c\u8d77\u52d5\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cardano-cli query tip --mainnet | grep syncProgress\n

\u623b\u308a\u5024\u78ba\u8a8d \"syncProgress\": \"100.00\"

\u623b\u308a\u5024\u304c99\u4ee5\u4e0b\u306e\u5834\u5408\u306f100(\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u307e\u3067\u540c\u671f)\u306b\u306a\u308b\u307e\u3067\u5f85\u3061\u307e\u3057\u3087\u3046\u3002

BP\u3068\u30ea\u30ec\u30fc\u306e\u5f79\u5272

  • \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9(BP) \u30d6\u30ed\u30c3\u30af\u751f\u6210\u306b\u5fc5\u8981\u306a\u30ad\u30fc\u3068\u8a3c\u660e\u66f8 (node.cert, kes.skey vrf.skey)\u3092\u7528\u3044\u3066\u8d77\u52d5\u3057\u307e\u3059\u3002\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306e\u307f\u306b\u63a5\u7d9a\u3057\u307e\u3059\u3002

  • \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9(\u30ea\u30ec\u30fc) \u81ea\u8eab\u306eBP\u3068\u4ed6\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3068\u306e\u7e4b\u304c\u308a\u3092\u6301\u3061\u6700\u65b0\u30b9\u30ed\u30c3\u30c8\u3092\u53d6\u5f97\u3057\u30d6\u30ed\u30c3\u30af\u4f1d\u64ad\u306e\u5f79\u5272\u3092\u679c\u305f\u3057\u307e\u3059\u3002

"},{"location":"setup/3-relay-bp-setup/#3-1","title":"3-1. \u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u306e\u8a2d\u5b9a\u5909\u66f4","text":""},{"location":"setup/3-relay-bp-setup/#3-1-1","title":"3-1-1. \u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u3092\u5909\u66f4","text":"

\u8a2d\u5b9a\u524d\u306e\u6ce8\u610f\u4e8b\u9805

\u3054\u5229\u7528\u306eVPS\u306b\u3088\u3063\u3066\u306f\u7ba1\u7406\u753b\u9762\u304b\u3089FW\u3092\u8a2d\u5b9a\u3059\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\uff08\u4f8bAWS\u7cfb\u306a\u3069\uff09 \u305d\u306e\u5834\u5408\u306f\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3092\u884c\u308f\u305a\u3001VPS\u30de\u30a4\u30da\u30fc\u30b8\u7ba1\u7406\u753b\u9762\u306a\u3069\u304b\u3089\u500b\u5225\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u4f7f\u7528\u3059\u308b 6000 \u756a\u30dd\u30fc\u30c8\u306e\u30a4\u30f3\u30d0\u30a6\u30f3\u30c9\u901a\u4fe1\u3092\u8a31\u53ef\u3059\u308b\u3002\u4efb\u610f\u306e\u756a\u53f7\u3067\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u305d\u306e\u756a\u53f7\u3092\u8a31\u53ef\u3059\u308b\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
sudo ufw allow 6000/tcp\nsudo ufw reload\n
"},{"location":"setup/3-relay-bp-setup/#3-1-2-topology","title":"3-1-2. Topology\u30d5\u30a1\u30a4\u30eb\u5909\u66f4","text":"

topology.json \u3068\u306f\uff1f

  • P2P(\u30d4\u30a2\u30c4\u30fc\u30d4\u30a2)\u63a5\u7d9a\u306b\u304a\u3051\u308b\u63a5\u7d9a\u5148\u30ce\u30fc\u30c9\u3092\u8a18\u8ff0\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u3067\u3059\u3002

  • \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u306f\u3001\u30d1\u30d6\u30ea\u30c3\u30af\u30ce\u30fc\u30c9 (IOHK\u3084\u4ed6\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9) \u53ca\u3073\u3001\u81ea\u8eab\u306e\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u60c5\u5831\u3092\u8a18\u8ff0\u3057\u307e\u3059\u3002

  • \u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u3067\u306f\u3001\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u60c5\u5831\u306e\u307f\u8a18\u8ff0\u3057\u307e\u3059\u3002

  • \u300cxxx.xxx.xxx.xxx\u300d\u306f\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044

  • \u30dd\u30fc\u30c8\u756a\u53f7\u3092\u5909\u66f4\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9

\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u304b\u3089\u63a5\u7d9a\u3059\u308b\u30ce\u30fc\u30c9\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002 \u300cxxx.xxx.xxx.xxx\u300d\u306fBP\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u30682-4\u3067\u8a2d\u5b9a\u3057\u305fBP\u30dd\u30fc\u30c8\u756a\u53f7\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044\u3002

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF \n {\n    \"Producers\": [\n      {\n        \"addr\": \"relays-new.cardano-mainnet.iohk.io\",\n        \"port\": 3001,\n        \"valency\": 2\n      },\n      {\n        \"addr\": \"xxx.xxx.xxx.xxx\",\n        \"port\": xxxxx,\n        \"valency\": 1\n      }\n    ]\n  }\nEOF\n

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl reload-or-restart cardano-node\n

"},{"location":"setup/3-relay-bp-setup/#3-2-bp","title":"3-2. BP\u30b5\u30fc\u30d0\u30fc\u306e\u8a2d\u5b9a\u5909\u66f4","text":""},{"location":"setup/3-relay-bp-setup/#3-2-1","title":"3-2-1. \u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u8a2d\u5b9a\u3092\u5909\u66f4","text":"

BP\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3

BP\u30b5\u30fc\u30d0\u30fc\u306b\u306f\u30d7\u30fc\u30eb\u904b\u55b6\u306e\u79d8\u5bc6\u9375\u3092\u4fdd\u7ba1\u3059\u308b\u305f\u3081\u3001\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3067\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u306e\u901a\u4fe1\u306e\u307f\u306b\u9650\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

BP\u30ce\u30fc\u30c9\u306b\u8a2d\u5b9a\u3057\u305f\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u78ba\u8a8d\u3059\u308b

PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n

BP\u30ce\u30fc\u30c9\u3067\u4f7f\u7528\u3059\u308b\u30dd\u30fc\u30c8(\u4e0a\u8a18\u3067\u8868\u793a\u3055\u308c\u305f\u756a\u53f7)\u306e\u901a\u4fe1\u3092\u8a31\u53ef\u3059\u308b\u3002

<\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306eIP> \u306e <>\u3092\u9664\u3044\u3066IP\u306e\u307f\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002

BP(\u30ea\u30ec\u30fc1\u53f0\u306e\u5834\u5408)BP(\u30ea\u30ec\u30fc2\u53f0\u306e\u5834\u5408)
sudo ufw allow from <\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306eIP> to any port ${b_PORT}\nsudo ufw reload\n
sudo ufw allow from <\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306eIP> to any port ${b_PORT}\nsudo ufw allow from <\u30ea\u30ec\u30fc\u30ce\u30fc\u30c92\u306eIP> to any port ${b_PORT}\nsudo ufw reload\n

\u4e0a\u8a18\u306fBP\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u306b\u5bfe\u3057\u30ea\u30ec\u30fcIP\u304b\u3089\u306e\u901a\u4fe1\u306e\u307f\u8a31\u53ef\u3059\u308b\u3068\u3044\u3046\u8a2d\u5b9a\u306b\u306a\u308a\u307e\u3059

"},{"location":"setup/3-relay-bp-setup/#3-2-2-topology","title":"3-2-2. Topology\u30d5\u30a1\u30a4\u30eb\u5909\u66f4","text":"

\u30d2\u30f3\u30c8

\u81ea\u8eab\u306eBP\u30ce\u30fc\u30c9\u304b\u3089\u63a5\u7d9a\u3059\u308b\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306eIP\u3068\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002 \u3042\u3089\u304b\u3058\u3081\u3001\u300cxxx.xxx.xxx.xxx\u300d\u306f\u3054\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u30b5\u30fc\u30d0\u30fc\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u3068\u30dd\u30fc\u30c8\u756a\u53f7\u3000\u306b\u7f6e\u304d\u63db\u3048\u3066\u304b\u3089\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002\u30ea\u30ec\u30fc\u53f0\u6570\u5206\u8a18\u8f09\u3057\u307e\u3059\u3002

BP(\u30ea\u30ec\u30fc1\u53f0\u306e\u5834\u5408)BP(\u30ea\u30ec\u30fc2\u53f0\u306e\u5834\u5408)
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF \n{\n    \"Producers\": [\n      {\n        \"addr\": \"xxx.xxx.xxx.xxx\",\n        \"port\": 6000,\n        \"valency\": 1\n      }\n    ]\n  }\nEOF\n
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF \n{\n    \"Producers\": [\n      {\n        \"addr\": \"aa.xxx.xxx.xxx\",\n        \"port\": 6000,\n        \"valency\": 1\n      },\n      {\n        \"addr\": \"bb.xxx.xxx.xxx\",\n        \"port\": 6000,\n        \"valency\": 1\n      }\n    ]\n  }\nEOF\n

BP\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl reload-or-restart cardano-node\n

"},{"location":"setup/4-bp-setup/","title":"4.BP\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u4e8b\u524d\u78ba\u8a8d

\u4ee5\u4e0b\u306e\u9805\u76ee\u3092\u5b9f\u65bd\u3059\u308b\u524d\u306bBP\u30ce\u30fc\u30c9\u304c\u8d77\u52d5\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

cardano-cli query tip --mainnet | grep syncProgress\n

\u623b\u308a\u5024\u78ba\u8a8d \"syncProgress\": \"100.00\" \u623b\u308a\u5024\u304c99\u4ee5\u4e0b\u306e\u5834\u5408\u306f100(\u6700\u65b0\u30d6\u30ed\u30c3\u30af\u307e\u3067\u540c\u671f)\u306b\u306a\u308b\u307e\u3067\u5f85\u3061\u307e\u3057\u3087\u3046\u3002

BP\u8d77\u52d5\u306b\u5fc5\u8981\u306a\u30d5\u30a1\u30a4\u30eb\u3068\u306f\uff1f

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u3067\u306f\uff13\u3064\u306e\u30ad\u30fc\u3092\u751f\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

  • \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306e\u904b\u7528\u8a3c\u660e\u66f8 (node.cert)
  • \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ad\u30fc (kes.skey)
  • \u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306eVRF\u30ad\u30fc (vrf.skey)
"},{"location":"setup/4-bp-setup/#1kes","title":"1.KES\u30ad\u30fc\u306e\u4f5c\u6210","text":"

KES\u30ad\u30fc\u306b\u3064\u3044\u3066

(KES=Key Evolving Signature)\u306e\u7565 \u30ad\u30fc\u3092\u60aa\u7528\u3059\u308b\u30cf\u30c3\u30ab\u30fc\u304b\u3089\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u3092\u4fdd\u8b77\u3059\u308b\u305f\u3081\u306b\u4f5c\u6210\u3055\u308c\u300190\u65e5\u3054\u3068\u306b\u518d\u751f\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u8a73\u7d30\u306f\u904b\u7528\u30de\u30cb\u30e5\u30a2\u30eb\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli node key-gen-KES \\\n    --verification-key-file kes.vkey \\\n    --signing-key-file kes.skey\n
"},{"location":"setup/4-bp-setup/#2","title":"2.\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u306e\u4f5c\u6210","text":"

\u6ce8\u610f

\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u306f\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u3067\u751f\u6210\u3057\u4fdd\u7ba1\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059 \u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u30d7\u30fc\u30eb\u904b\u55b6\u3067\u91cd\u8981\u306a\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u3067\u3059\u3002\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3067\u4f5c\u6210\u3057\u30aa\u30f3\u30e9\u30a4\u30f3\u74b0\u5883\u306b\u4fdd\u7ba1\u3057\u306a\u3044\u3088\u3046\u3054\u6ce8\u610f\u4e0b\u3055\u3044\u3002 \u5916\u90e8\u306b\u6d41\u51fa\u3059\u308b\u3068\u30d7\u30fc\u30eb\u304c\u4e57\u3063\u53d6\u3089\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u7ba1\u7406\u306b\u306f\u5341\u5206\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044 \u307e\u305f\u8907\u6570\u306eUSB\u306b\u4fdd\u7ba1\u3057\u3001\u7d76\u5bfe\u306b\u4e0a\u66f8\u304d\u30fb\u524a\u9664\u3057\u306a\u3044\u3088\u3046\u3054\u6ce8\u610f\u4e0b\u3055\u3044\u3002\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u306f\u6b21\u306e\u30d1\u30b9\u306b\u683c\u7d0d\u3055\u308c\u307e\u3059 $HOME/cold-keys

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
mkdir $HOME/cold-keys\n

\u30b3\u30fc\u30eb\u30c9\u30ad\u30fc\u306e\u30da\u30a2\u30ad\u30fc\u3068\u30ab\u30a6\u30f3\u30bf\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

cd $HOME/cold-keys\ncardano-cli node key-gen \\\n    --cold-verification-key-file node.vkey \\\n    --cold-signing-key-file node.skey \\\n    --operational-certificate-issue-counter node.counter\n
\u30a2\u30af\u30bb\u30b9\u6a29\u3092\u8aad\u307f\u53d6\u308a\u5c02\u7528\u306b\u66f4\u65b0\u3057\u307e\u3059\u3002
chmod 400 node.vkey\nchmod 400 node.skey\n

\u91cd\u8981

\u3059\u3079\u3066\u306e\u30ad\u30fc\u3092\u5225\u306e\u5b89\u5168\u306a\u30b9\u30c8\u30ec\u30fc\u30b8\u30c7\u30d0\u30a4\u30b9(USB)\u306a\u3069\u306b\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3057\u307e\u3057\u3087\u3046\uff01\u8907\u6570\u306e\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u3092\u304a\u3059\u3059\u3081\u3057\u307e\u3059\u3002

"},{"location":"setup/4-bp-setup/#3","title":"3.\u30d7\u30fc\u30eb\u904b\u7528\u8a3c\u660e\u66f8\u306e\u4f5c\u6210","text":"

\u4e8b\u524d\u78ba\u8a8d

\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u3068\u5b8c\u5168\u306b\u540c\u671f\u3057\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u540c\u671f\u304c\u9014\u4e2d\u306e\u5834\u5408\u3001\u6b63\u3057\u3044slotsPerKESPeriod\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002 \u3042\u306a\u305f\u306eBP\u30ce\u30fc\u30c9\u304c\u5b8c\u5168\u306b\u540c\u671f\u3055\u308c\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u306b\u306f\u3001\u30ab\u30eb\u30c0\u30ce\u30a8\u30af\u30b9\u30d7\u30ed\u30fc\u30e9\u30fc\u3067\u81ea\u8eab\u306e\u540c\u671f\u6e08\u307f\u30a8\u30dd\u30c3\u30af\u3068\u30b9\u30ed\u30c3\u30c8\u304c\u4e00\u81f4\u3057\u3066\u3044\u308b\u304b\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

\u30b8\u30a7\u30cd\u30b7\u30b9\u30d5\u30a1\u30a4\u30eb\u304b\u3089slotsPerKESPeriod\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

cd $NODE_HOME\nslotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')\necho slotsPerKESPeriod: ${slotsPerKESPeriod}\n
\u540c\u671f\u6e08\u307fslotNo\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002
slotNo=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho slotNo: ${slotNo}\n

startKesPeriod\u3092\u7b97\u51fa\u3057\u307e\u3059\u3002

kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))\necho kesPeriod: ${kesPeriod}\nstartKesPeriod=${kesPeriod}\necho startKesPeriod: ${startKesPeriod}\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306ekes.skey\u3068kes.vkey \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|kes.skey / kes.vkey| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067kes.vkey\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nsha256sum kes.vkey\n

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u8868\u793a\u3055\u308c\u305f\u623b\u308a\u5024\u3092\u6bd4\u8f03\u3057\u3066\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070OK

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nsha256sum kes.vkey\n

\u78ba\u8a8d

\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u30aa\u30da\u30ec\u30fc\u30bf\u306f\u3001\u30d7\u30fc\u30eb\u3092\u5b9f\u884c\u3059\u308b\u6a29\u9650\u304c\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u305f\u3081\u306e\u904b\u7528\u8a3c\u660e\u66f8\u3092\u767a\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u8a3c\u660e\u66f8\u306b\u306f\u3001\u30aa\u30da\u30ec\u30fc\u30bf\u306e\u7f72\u540d\u304c\u542b\u307e\u308c\u30d7\u30fc\u30eb\u306b\u95a2\u3059\u308b\u60c5\u5831\uff08\u30a2\u30c9\u30ec\u30b9\u3001\u30ad\u30fc\u306a\u3069\uff09\u304c\u542b\u307e\u308c\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nread -p \"BP\u3067\u7b97\u51fa\u3057\u305fstartKesPeriod\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044:\" kes\n

\u2191\u3053\u306e\u307e\u307e\u30b3\u30de\u30f3\u30c9\u306b\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044 \u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u5f8c\u306b\u3001\u6570\u5b57\u5165\u529b\u30e2\u30fc\u30c9\u306b\u306a\u308a\u307e\u3059\u306e\u3067 \u305d\u3053\u3067BP\u3067\u7b97\u51fa\u3057\u305fstartKesPeriod\u306e\u6570\u5b57\u3092\u5165\u529b\u3057\u307e\u3059

\u5165\u529b\u3057\u305f\u6570\u5b57\u304c\u623b\u308a\u5024\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u8a3c\u660e\u66f8\u3092\u4f5c\u6210\u3059\u308b

echo \"\u5165\u529b\u3057\u305f\u6570\u5b57\u306f$kes\u3067\u3059\"\n

cardano-cli node issue-op-cert \\\n    --kes-verification-key-file kes.vkey \\\n    --cold-signing-key-file $HOME/cold-keys/node.skey \\\n    --operational-certificate-issue-counter $HOME/cold-keys/node.counter \\\n    --kes-period $kes \\\n    --out-file node.cert\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306enode.cert \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|node.cert| B[BP];

** BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067node.cert\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b **

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nsha256sum node.cert\n

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u8868\u793a\u3055\u308c\u305f\u623b\u308a\u5024\u3092\u6bd4\u8f03\u3057\u3066\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070OK

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\nsha256sum node.cert\n
"},{"location":"setup/4-bp-setup/#4vrf","title":"4.VRF\u30ad\u30fc\u306e\u4f5c\u6210","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli node key-gen-VRF \\\n    --verification-key-file vrf.vkey \\\n    --signing-key-file vrf.skey\n

vrf\u30ad\u30fc\u306e\u30a2\u30af\u30bb\u30b9\u6a29\u3092\u8aad\u307f\u53d6\u308a\u5c02\u7528\u306b\u66f4\u65b0\u3057\u307e\u3059\u3002

chmod 400 vrf.skey\nchmod 400 vrf.vkey\n

\u6ce8\u610f

vrf\u30ad\u30fc\u3092\u8aa4\u3063\u3066\u524a\u9664\u3057\u306a\u3044\u3088\u3046\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/4-bp-setup/#5bp","title":"5.BP\u30ce\u30fc\u30c9\u3068\u3057\u3066\u518d\u8d77\u52d5","text":"

BP\u30ce\u30fc\u30c9\u3092\u4e00\u65e6\u505c\u6b62\u3059\u308b

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
sudo systemctl stop cardano-node\n

\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u756a\u53f7\u3092\u78ba\u8a8d\u3059\u308b

PORT=`grep \"PORT=\" $NODE_HOME/startBlockProducingNode.sh`\nb_PORT=${PORT#\"PORT=\"}\necho \"BP\u30dd\u30fc\u30c8\u306f${b_PORT}\u3067\u3059\"\n

\u2191\u305d\u306e\u307e\u307e\u5b9f\u884c\u3057\u3001BP\u306e\u30dd\u30fc\u30c8\u756a\u53f7\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b

\u8d77\u52d5\u30b9\u30af\u30ea\u30d7\u30c8\u306bKES\u3001VRF\u3001\u904b\u7528\u8a3c\u660e\u66f8\u306e\u30d1\u30b9\u3092\u8ffd\u8a18\u3057\u66f4\u65b0\u3057\u307e\u3059\u3002

cat > $NODE_HOME/startBlockProducingNode.sh << EOF \n#!/bin/bash\nDIRECTORY=$NODE_HOME\nPORT=${b_PORT}\nHOSTADDR=0.0.0.0\nTOPOLOGY=\\${DIRECTORY}/${NODE_CONFIG}-topology.json\nDB_PATH=\\${DIRECTORY}/db\nSOCKET_PATH=\\${DIRECTORY}/db/socket\nCONFIG=\\${DIRECTORY}/${NODE_CONFIG}-config.json\nSNAPSHOT=43200\nKES=\\${DIRECTORY}/kes.skey\nVRF=\\${DIRECTORY}/vrf.skey\nCERT=\\${DIRECTORY}/node.cert\n/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A32m -n4m -F1.5 -H2500M -T -S -RTS run --topology \\${TOPOLOGY} --database-path \\${DB_PATH} --socket-path \\${SOCKET_PATH} --host-addr \\${HOSTADDR} --port \\${PORT} --config \\${CONFIG} --shelley-kes-key \\${KES} --shelley-vrf-key \\${VRF} --shelley-operational-certificate \\${CERT} --snapshot-interval \\${SNAPSHOT}\nEOF\n

BP\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo systemctl start cardano-node\n

BP\u3068\u3057\u3066\u8d77\u52d5\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

cd $NODE_HOME/scripts\n./gLiveView.sh\n

\u30c1\u30a7\u30fc\u30f3\u540c\u671f\u5f8c\u306bCore\u306e\u8868\u793a\u304c\u3042\u308c\u3070OK

\u6ce8\u610f\u4e8b\u9805

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u306f\u3001\u4ee5\u4e0b\u306e\uff13\u3064\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u5fc5\u8981\u3067\u3059\u3002\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u304c\u63c3\u3063\u3066\u3044\u306a\u3044\u5834\u5408\u3084\u8d77\u52d5\u6642\u306b\u6307\u5b9a\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u30d6\u30ed\u30c3\u30af\u304c\u751f\u6210\u3067\u304d\u307e\u305b\u3093\u3002

  • kes.skey
  • vrf.skey
  • node.cert
"},{"location":"setup/5-generate-address/","title":"5.\u30d7\u30fc\u30eb\u904b\u55b6\u3067\u4f7f\u7528\u3059\u308b\u30a2\u30c9\u30ec\u30b9\u3092\u4f5c\u6210\u3059\u308b","text":"

\u6ce8\u610f

\u30d7\u30fc\u30eb\u767b\u9332\u5f8c\u3001\u4ee5\u4e0b\u306e\u624b\u9806\u3092\u3084\u308a\u76f4\u3057\u3059\u308b\u3068\u5909\u66f4\u624b\u7d9a\u304d\u304c\u9762\u5012\u306b\u306a\u308b\u306e\u3067\u3054\u6ce8\u610f\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/5-generate-address/#1","title":"1.\u30d7\u30ed\u30c8\u30b3\u30eb\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u53d6\u5f97","text":"\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli query protocol-parameters \\\n    $NODE_NETWORK \\\n    --out-file params.json\n

\u904b\u7528\u4e0a\u306e\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306b\u95a2\u3059\u308b\u91cd\u8981\u306a\u30a2\u30c9\u30d0\u30a4\u30b9

\u30ad\u30fc\u306e\u751f\u6210\u306f\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u3067\u751f\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u63a5\u7d9a\u304c\u7121\u304f\u3066\u3082\u751f\u6210\u53ef\u80fd\u3067\u3059\u3002 payment\u30ad\u30fc\u306f\u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9\u306b\u4f7f\u7528\u3055\u308c\u3001stake\u30ad\u30fc\u306f\u30d7\u30fc\u30eb\u59d4\u4efb\u30a2\u30c9\u30ec\u30b9\u7528\u306e\u7ba1\u7406\u306b\u4f7f\u7528\u3055\u308c\u307e\u3059\u3002

"},{"location":"setup/5-generate-address/#2","title":"2.\u652f\u6255\u3044\u30a2\u30c9\u30ec\u30b9\u30ad\u30fc\u306e\u4f5c\u6210","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli address key-gen \\\n    --verification-key-file payment.vkey \\\n    --signing-key-file payment.skey\n
"},{"location":"setup/5-generate-address/#3","title":"3. \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u30ad\u30fc\u306e\u4f5c\u6210","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli stake-address key-gen \\\n    --verification-key-file stake.vkey \\\n    --signing-key-file stake.skey\n
"},{"location":"setup/5-generate-address/#4","title":"4.\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u306e\u4f5c\u6210","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli stake-address build \\\n    --stake-verification-key-file stake.vkey \\\n    --out-file stake.addr \\\n    $NODE_NETWORK\n
"},{"location":"setup/5-generate-address/#5_1","title":"5.\u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9\u306e\u4f5c\u6210","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cardano-cli address build \\\n    --payment-verification-key-file payment.vkey \\\n    --stake-verification-key-file stake.vkey \\\n    --out-file payment.addr \\\n    $NODE_NETWORK\n

\u4e0a\u66f8\u304d\u30fb\u524a\u9664\u3055\u308c\u306a\u3044\u3088\u3046\u30d1\u30fc\u30df\u30c3\u30b7\u30e7\u30f3\u3092\u5909\u66f4\u3059\u308b\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
chmod 400 payment.vkey\nchmod 400 payment.skey\nchmod 400 stake.vkey\nchmod 400 stake.skey\nchmod 400 stake.addr\nchmod 400 payment.addr\n
\u30d5\u30a1\u30a4\u30eb \u7528\u9014 payment.vkey payment\u30a2\u30c9\u30ec\u30b9\u516c\u958b\u9375 payment.skey payment\u30a2\u30c9\u30ec\u30b9\u79d8\u5bc6\u9375 payment.addr payment\u30a2\u30c9\u30ec\u30b9\u30d5\u30a1\u30a4\u30eb stake.vkey \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u516c\u958b\u9375 stake.skey \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u79d8\u5bc6\u9375 stake.addr \u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u30d5\u30a1\u30a4\u30eb

\u6ce8\u610f

\u3053\u308c\u3089\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u7d1b\u5931\u3057\u306a\u3044\u3088\u3046\u306b\u3054\u6ce8\u610f\u304f\u3060\u3055\u3044\u3002\u7279\u306b.vkey/.skey\u3092\u7121\u304f\u3057\u305f\u5834\u5408\u3001\u30d7\u30fc\u30eb\u5831\u916c\u3084\u8a93\u7d04\u91d1\u3092\u5f15\u304d\u51fa\u305b\u306a\u304f\u306a\u308a\u307e\u3059\u3002\u8907\u6570\u306e\u5916\u90e8\u30c7\u30d0\u30a4\u30b9\u306b\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u53d6\u3063\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/5-generate-address/#6","title":"6.\u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9\u306b\u5165\u91d1\u3059\u308b","text":"

\u6b21\u306e\u30b9\u30c6\u30c3\u30d7\u306f\u3001\u3042\u306a\u305f\u306e\u652f\u6255\u3044\u30a2\u30c9\u30ec\u30b9\u306b\u9001\u91d1\u3059\u308b\u624b\u9806\u3067\u3059\u3002

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306epayment.addr\u3068stake.addr \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|payment.addr / stake.addr| B[BP];

\u30e1\u30a4\u30f3\u30cd\u30c3\u30c8\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8

\u4ee5\u4e0b\u306e\u30a6\u30a9\u30ec\u30c3\u30c8\u304b\u3089\u9001\u91d1\u304c\u53ef\u80fd\u3067\u3059

  • \u30c0\u30a4\u30c0\u30ed\u30b9 / \u30e8\u30ed\u30a4\u30a6\u30a9\u30ec\u30c3\u30c8 / nami / ccvault.io

\u652f\u6255\u3044\u30a2\u30c9\u30ec\u30b9\u3092\u8868\u793a\u3055\u305b\u3001\u3053\u306e\u30a2\u30c9\u30ec\u30b9\u306b\u9001\u91d1\u3057\u307e\u3059\u3002

echo \"$(cat $NODE_HOME/payment.addr)\"\n

\u4f55ADA\u5165\u91d1\u3057\u305f\u3089\u3044\u3044\uff1f

\u521d\u56de\u306f\u30c6\u30b9\u30c8\u3067\u5c11\u984d\u304b\u3089\u5165\u91d1\u3057\u3066\u304f\u3060\u3055\u3044

payment.addr\u306f\u4ee5\u4e0b\u306e\u5f79\u5272\u304c\u3042\u308b\u305f\u3081\u5fc5\u8981\u5206\u5165\u91d1\u3057\u3066\u304f\u3060\u3055\u3044 \u25cf\u30d7\u30fc\u30eb\u767b\u9332\u6599\u306e\u652f\u6255\u3044(500ADA) \u25cf\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u767b\u9332\u6599\u306e\u652f\u6255\u3044(2ADA) \u25cf\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u624b\u6570\u6599\u306e\u652f\u6255\u3044(\u6570ADA) \u25cf\u8a93\u7d04\u91d1\u306e\u9810\u3051\u5148(\u8a93\u7d04\u3068\u3057\u3066\u8a2d\u5b9a\u3057\u305f\u3044\u984d)

\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u7528ADA\u306e\u8acb\u6c42

\u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u7528\u53e3\u5ea7\u306b\u3042\u306a\u305f\u306e\u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9\u3092\u30ea\u30af\u30a8\u30b9\u30c8\u3057\u307e\u3059\u3002 \u30c6\u30b9\u30c8\u30cd\u30c3\u30c8\u7528\u53e3\u5ea7\u306f24\u6642\u9593\u3054\u3068\u306b1000tADA\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002

\u6b21\u306e\u30b3\u30fc\u30c9\u3092\u5b9f\u884c\u3057\u3002\u652f\u6255\u3044\u30a2\u30c9\u30ec\u30b9\u3092\u8868\u793a\u3055\u305b\u307e\u3059\u3002

echo \"$(cat $NODE_HOME/payment.addr)\"\n

\u3053\u306e\u30a2\u30c9\u30ec\u30b9\u3092\u4e0a\u8a18\u30da\u30fc\u30b8\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u6b04\u306b\u8cbc\u308a\u4ed8\u3051\u307e\u3059\u3002

\u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9\u306b\u9001\u91d1\u5f8c\u3001\u6b8b\u9ad8\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30ce\u30fc\u30c9\u3092\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u3068\u5b8c\u5168\u306b\u540c\u671f\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u5b8c\u5168\u306b\u540c\u671f\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u3001\u6b8b\u9ad8\u304c\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK\n

\u6b21\u306e\u3088\u3046\u306b\u8868\u793a\u3055\u308c\u305f\u3089\u5165\u91d1\u5b8c\u4e86\u3067\u3059\u3002

                        TxHash                                 TxIx        Lovelace\n----------------------------------------------------------------------------------------\n100322a39d02c2ead....                                              0        1000000000\n
"},{"location":"setup/6-register-stakeaddress/","title":"6.\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u306e\u767b\u9332","text":""},{"location":"setup/6-register-stakeaddress/#1","title":"1.\u30b9\u30c6\u30fc\u30af\u8a3c\u660e\u66f8\u3092\u4f5c\u6210\u3059\u308b","text":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli stake-address registration-certificate \\\n    --stake-verification-key-file stake.vkey \\\n    --out-file stake.cert\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306estake.cert \u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|stake.cert| B[BP];

"},{"location":"setup/6-register-stakeaddress/#2","title":"2.\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u3092\u767b\u9332\u3059\u308b","text":"

\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u306e\u767b\u9332\u306b\u306f2000000 lovelace (2ADA)\u304c\u5fc5\u8981\u3067\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

keyDeposit\u306e\u5024\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakeAddressDeposit')\necho keyDeposit: $keyDeposit\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4eee\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+0 \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --out-file tx.tmp \\\n    --certificate stake.cert\n

\u73fe\u5728\u306e\u6700\u4f4e\u624b\u6570\u6599\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 2 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u8a08\u7b97\u7d50\u679c\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${keyDeposit}-${fee}))\necho Change Output: ${txOut}\n

\u30b9\u30c6\u30fc\u30af\u30a2\u30c9\u30ec\u30b9\u3092\u767b\u9332\u3059\u308b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --certificate-file stake.cert \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

payment\u3068stake\u306e\u79d8\u5bc6\u9375\u3067\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u306b\u7f72\u540d\u3057\u307e\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306etx.signed\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u7f72\u540d\u3055\u308c\u305f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

"},{"location":"setup/7-register-stakepool/","title":"7.\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306e\u767b\u9332","text":"

\u6982\u8981

\u3053\u3061\u3089\u306e\u624b\u9806\u306f\u521d\u56de\u30d7\u30fc\u30eb\u767b\u9332\u6642\u306e\u307f\u6709\u52b9\u3067\u3059\u3002 \u30d7\u30fc\u30eb\u767b\u9332\u5f8c\u306b\u30e1\u30bf\u60c5\u5831\u3001\u8a93\u7d04\u3001\u56fa\u5b9a\u8cbb\u3001\u5909\u52d5\u8cbb\u3001\u30ea\u30ec\u30fc\u60c5\u5831\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u306f\u3001\u30d7\u30fc\u30eb\u60c5\u5831(pool.cert)\u306e\u66f4\u65b0\u306e\u5909\u66f4\u624b\u9806\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30d7\u30fc\u30eb\u767b\u9332\u6599

\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u767b\u9332\u306b\u306f500ADA\u306e\u767b\u9332\u6599\u304c\u5fc5\u8981\u3067\u3059\u3002payment.addr\u306b\u5165\u91d1\u3055\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002

"},{"location":"setup/7-register-stakepool/#1","title":"1.\u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u4f5c\u6210","text":"

\u30db\u30fc\u30e0\u30da\u30fc\u30b8\u3092\u6301\u3063\u3066\u3044\u306a\u3044\u5834\u5408

\u300cjson\u30d5\u30a1\u30a4\u30eb\u3092Github\u3067\u30db\u30b9\u30c8\u3059\u308b\u65b9\u6cd5\u300d\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044

json\u30d5\u30a1\u30a4\u30eb\u3092Github\u3067\u30db\u30b9\u30c8\u3059\u308b\u65b9\u6cd5\u3054\u81ea\u8eab\u306e\u30db\u30fc\u30e0\u30da\u30fc\u30b8\u30b5\u30fc\u30d0\u3067\u30db\u30b9\u30c8\u3059\u308b\u65b9\u6cd5

1.Github\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u4f5c\u6210\u3057\u30ed\u30b0\u30a4\u30f3\u3057\u307e\u3059 https://github.com/ \u30e6\u30fc\u30b6\u30fc\u540d\u3092\u6700\u592713\u6587\u5b57\u4ee5\u5185\u3067\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044

2.Repositories\u30bf\u30d6\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u53f3\u4e0a\u306eNew \u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

3.\u30ea\u30dd\u30b8\u30c8\u30ea\u4f5c\u6210

  • Repository name\u306b\u4efb\u610f\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u540d(\u6700\u592713\u6587\u5b57\u4ee5\u5185)\u3092\u5165\u529b
  • Public\u3092\u9078\u629e
  • Create repository\u3092\u30af\u30ea\u30c3\u30af

4.\u5c0f\u3055\u3044\u6587\u5b57\u3067\u66f8\u304b\u308c\u305f\"creating a new file\"\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5.\u30d5\u30a1\u30a4\u30eb\u540d\u3092 poolMetaData.json \u3068\u3057\u3066\u5165\u529b\u3057 json \u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u8cbc\u308a\u4ed8\u3051\u307e\u3059\u3002

{\n\"name\": \"MyPoolName\",\n\"description\": \"My pool description\",\n\"ticker\": \"MPN\",\n\"homepage\": \"https://myadapoolnamerocks.com\"\n}\n

\u4f5c\u6210\u6642\u306e\u6ce8\u610f

  • \u4e0b\u8a18\u306f\u53c2\u8003\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3068\u306a\u308a\u307e\u3059\u3002\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u540d\u3001Ticker\u540d\u306b\u66f8\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044
  • \u307e\u3060homepage\u30a2\u30c9\u30ec\u30b9\u304c\u7121\u3044\u5834\u5408\u306f\u3001\u3054\u81ea\u8eab\u306eTwitter\u30a2\u30c9\u30ec\u30b9\u3067\u3082\u5927\u4e08\u592b\u3067\u3059\u3002
  • ticker\u540d\u306e\u9577\u3055\u306f3\uff5e5\u6587\u5b57\u4ee5\u5185\u3067\u3001A-Z\u30680-9\u306e\u307f\u3067\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
  • description\u306e\u9577\u3055\u306f255\u6587\u5b57\u4ee5\u5185(255byte)\u3068\u306a\u308a\u307e\u3059\u3002\uff08\u3072\u3089\u304c\u306a\u3001\u6f22\u5b57\u3001\u30ab\u30bf\u30ab\u30ca\u306f1\u6587\u5b572byte\uff09

6.Commit Changes...\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

7.\u4e0a\u90e8\u306e\u30e1\u30cb\u30e5\u30fc\u30bf\u30d6\u304b\u3089Settings\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059

8.GitPages\u8a2d\u5b9a

  • \u5de6\u30e1\u30cb\u30e5\u30fc\u304b\u3089Pages\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002
  • Branch\u306e\u30d7\u30eb\u30c0\u30a6\u30f3\u304b\u3089main /root\u3092\u9078\u629e\u3059\u308b
  • Save\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059

9.URL\u306e\u751f\u6210

  • \u5de6\u30e1\u30cb\u30e5\u30fc\u304b\u3089Pages\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002
  • \u4e0a\u90e8\u306b\u3053\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u516c\u958bURL\u304c\u8868\u793a\u3055\u308c\u305f\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059
  • \u8d64\u67a0\u306eURL\u3092\u30b3\u30d4\u30fc\u3057\u307e\u3059

10.\u30e1\u30bf\u30c7\u30fc\u30bfURL\u306e\u751f\u6210

9\u3067\u30b3\u30d4\u30fc\u3057\u305fURL\u306bpoolMetaData.json\u3092\u7e4b\u3052\u307e\u3059

\u4f8b\uff09https://btbf.github.io/sjg/poolMetaData.json

\u3053\u306eURL\u306e\u6587\u5b57\u5217\u304c64\u6587\u5b57\u4ee5\u5185\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044

11\uff0e\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9\u3067json\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u3059\u308b\u3002

URL\u3092\u66f8\u304d\u63db\u3048\u3066\u304b\u3089\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044

10\u3067\u4f5c\u6210\u3057\u305f\u30e1\u30bf\u30c7\u30fc\u30bfURL\u3092\u7528\u3044\u3066\u4e0b\u3055\u3044\u3002

cd $NODE_HOME\nwget -O poolMetaData.json https://xxx.github.io/xxx/poolMetaData.json \n

\u4e0b\u8a18\u306f\u53c2\u8003\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3068\u306a\u308a\u307e\u3059\u3002\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u540d\u3001Ticker\u540d\u306b\u66f8\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044

\u4f5c\u6210\u30eb\u30fc\u30eb

ticker\u540d\u306e\u9577\u3055\u306f3\uff5e5\u6587\u5b57\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u6587\u5b57\u306fA-Z\u30680-9\u306e\u307f\u3067\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 description\u306e\u9577\u3055\u306f255\u6587\u5b57\u4ee5\u5185(255byte)\u3068\u306a\u308a\u307e\u3059\u3002\uff08\u3072\u3089\u304c\u306a\u3001\u6f22\u5b57\u3001\u30ab\u30bf\u30ab\u30ca\u306f1\u6587\u5b572byte\uff09

\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3059\u308b\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncat > poolMetaData.json << EOF\n{\n\"name\": \"MyPoolName\",\n\"description\": \"My pool description\",\n\"ticker\": \"MPN\",\n\"homepage\": \"https://myadapoolnamerocks.com\"\n}\nEOF\n

\u6ce8\u610f

poolMetaData.json\u3092\u3042\u306a\u305f\u306e\u516c\u958b\u7528WEB\u30b5\u30fc\u30d0\u3078\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30e1\u30bf\u30c7\u30fc\u30bfJSON\u3092\u30c1\u30a7\u30c3\u30af\u3059\u308b

cat $NODE_HOME/poolMetaData.json | jq .\n

\u623b\u308a\u5024\u306b\u30a8\u30e9\u30fc\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408

\u623b\u308a\u4fa1\u306bparse error:\u304c\u8868\u793a\u3055\u308c\u308b\u5834\u5408\u306f\u3001JSON\u69cb\u6587\u306b\u8aa4\u308a\u304c\u3042\u308a\u307e\u3059\u3002 \u4f5c\u6210\u3057\u305f\u30e1\u30bf\u30c7\u30fc\u30bfJSON\u30d5\u30a1\u30a4\u30eb\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002

\u30e1\u30bf\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb\u306e\u30cf\u30c3\u30b7\u30e5\u5024\u3092\u8a08\u7b97\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncardano-cli stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt\n
"},{"location":"setup/7-register-stakepool/#2","title":"2.\u30d7\u30fc\u30eb\u767b\u9332\u8a3c\u660e\u66f8\u306e\u4f5c\u6210","text":"

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306b\u3042\u308bvrf.vkey\u3068poolMetaDataHash.txt \u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->| vrf.vkey / poolMetaDataHash.txt | B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

** BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067vrf.vkey\u30d5\u30a1\u30a4\u30eb\u30cf\u30c3\u30b7\u30e5\u3092\u6bd4\u8f03\u3059\u308b **

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nsha256sum vrf.vkey\n

BP\u3068\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u3067\u8868\u793a\u3055\u308c\u305f\u623b\u308a\u5024\u3092\u6bd4\u8f03\u3057\u3066\u3001\u30cf\u30c3\u30b7\u30e5\u5024\u304c\u4e00\u81f4\u3057\u3066\u3044\u308c\u3070OK

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3
cd $NODE_HOME\nsha256sum vrf.vkey\n

\u6700\u5c0f\u30d7\u30fc\u30eb\u30b3\u30b9\u30c8(\u6700\u4f4e\u56fa\u5b9a\u8cbb)\u3092\u51fa\u529b\u3057\u307e\u3059\u3002

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
minPoolCost=$(cat $NODE_HOME/params.json | jq -r .minPoolCost)\necho minPoolCost: ${minPoolCost}\n

minPoolCost(\u6700\u4f4e\u56fa\u5b9a\u8cbb)\u306f 170000000 lovelace (170 ADA)\u3067\u3059\u3002

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3067pool.cert\u3092\u4f5c\u6210\u3059\u308b

pool.cert\u4f5c\u6210\u6642\u306e\u6ce8\u610f\u70b9\u25bc

pool.cert\u306f\u30d7\u30fc\u30eb\u767b\u9332\u8a3c\u660e\u66f8\u306e\u5f79\u5272\u3092\u679c\u305f\u3057\u3001\u30d7\u30fc\u30eb\u60c5\u5831\u3092\u8a18\u8f09\u3057\u307e\u3059\u3002\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u306f\u4ee5\u4e0b\u306e\u5024\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u3059\u3002

  • \u8a93\u7d04 100ADA \u3000(--pool-pledge) \u3000\u6ce8\u91c8\u2192(1)
  • \u56fa\u5b9a\u624b\u6570\u6599 170ADA (--pool-cost) \u3000\u6ce8\u91c8\u2192(2)
  • \u5909\u52d5\u624b\u6570\u65995% (--pool-margin) \u3000\u6ce8\u91c8\u2192(3)
  1. \u8a93\u7d04(Pledge)\u3068\u306f\uff1fPledge(\u8a93\u7d04)\u306f\u30b7\u30d3\u30eb\u653b\u6483\u3092\u9632\u3050\u76ee\u7684\u3067\u5c0e\u5165\u3055\u308c\u3066\u3044\u308b\u30d1\u30e9\u30e1\u30fc\u30bf\u3067\u3001SPO\u304c\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u306bADA\u3092\u3088\u308a\u9810\u3051\u308b\u3053\u3068\u3067\u59d4\u4efb\u8005\u69d8\u306e\u5831\u916c\u304c\u82e5\u5e72\u591a\u304f\u5206\u914d\u3055\u308c\u308b\u8a2d\u8a08\u306b\u306a\u3063\u3066\u304a\u308a\u3001\u8907\u6570\u30d7\u30fc\u30eb\u3092\u958b\u8a2d\u3059\u308b\u3088\u308a\u3082\u5358\u4e00\u30d7\u30fc\u30eb\u3067\u306e\u904b\u55b6\u30e1\u30ea\u30c3\u30c8\u4fc3\u3059\u305f\u3081\u306b\u8a2d\u3051\u3089\u308c\u305f\u5236\u5ea6\u3067\u3059\u30022022/02/16\u6642\u70b9\u3067\u306ePledge(\u8a93\u7d04)\u306e\u8a2d\u8a08\u306f\u3001SPO\u304c\u5dee\u3057\u51fa\u3059ADA(Pledge)\u304c10M ADA\u4ee5\u4e0a\u304b\u3089\u3058\u3083\u306a\u3044\u3068\u5831\u916c\u304c\u5897\u3048\u308b\u5272\u5408\u304c\u5909\u308f\u3089\u306a\u3044\u305f\u3081\u3001\u3042\u307e\u308a\u6a5f\u80fd\u3057\u3066\u3044\u306a\u3044\u306e\u304c\u5b9f\u60c5\u3067\u3059\u3002(\u73fe\u5728\u6539\u826f\u304c\u691c\u8a0e\u3055\u308c\u3066\u3044\u307e\u3059)
  2. \u56fa\u5b9a\u624b\u6570\u6599(cost)\u3068\u306f\uff1f\u30d7\u30fc\u30eb\u904b\u55b6\u306b\u304a\u3051\u308b\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c\u306e1\u3064\u3067\u3001\u6700\u4f4e170ADA\u304b\u3089\u8a2d\u5b9a\u53ef\u80fd
  3. \u5909\u52d5\u624b\u6570\u6599(margin)\u3068\u306f\uff1f\u30d7\u30fc\u30eb\u904b\u55b6\u306b\u304a\u3051\u308b\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c\u306e1\u3064\u3067 (\u7dcf\u5831\u916c-\u56fa\u5b9a\u624b\u6570\u6599\u8cbb)\u306b\u304a\u3051\u308b\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u5831\u916c\u7387
\u8a93\u7d04(Pledge)\u306b\u3064\u3044\u3066\u25bc

\u81ea\u5206\u306e\u30d7\u30fc\u30eb\u306b\u4fdd\u8a3c\u91d1\u3092\u9810\u3051\u308b\u3053\u3068\u3092Pledge(\u8a93\u7d04)\u3068\u547c\u3073\u307e\u3059

  • \u652f\u6255\u3044\u7528\u30a2\u30c9\u30ec\u30b9(payment.addr)\u306e\u6b8b\u9ad8\u306fPledge\u984d\u3088\u308a\u3082\u5927\u304d\u3044\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
  • \u8a93\u7d04\u91d1\u306fpayment.addr\u306b\u5165\u91d1\u3055\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
  • \u8a2d\u5b9a\u3057\u305f\u8a93\u7d04\u6570\u3088\u308apayment.addr\u306b\u5165\u91d1\u3055\u308c\u3066\u308bADA\u304c\u4e0b\u56de\u3063\u3066\u3044\u308b\u5834\u5408\u3001\u30d7\u30fc\u30eb\u5831\u916c\u304c\uff10\u306b\u306a\u308a\u307e\u3059\u3002
  • \u8a93\u7d04\u91d1\u306f\u30ed\u30c3\u30af\u3055\u308c\u307e\u305b\u3093\u3002\u3044\u3064\u3067\u3082\u81ea\u7531\u306b\u53d6\u308a\u51fa\u305b\u307e\u3059\u304c\u30d7\u30fc\u30eb\u767b\u9332\u8a3c\u660e\u66f8\u3092\u518d\u63d0\u51fa\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002
\u30ea\u30ec\u30fc(--pool-relay-ipv4)\u306e\u8a18\u8ff0\u306b\u3064\u3044\u3066\u25bc

\u4e0a\u8a18\u306epool.cert\u4f5c\u6210\u6642\u3001\u81ea\u8eab\u306e\u30ea\u30ec\u30fc\u60c5\u5831\u3092\u4ee5\u4e0b\u306e3\u30d1\u30bf\u30fc\u30f3\u306e\u8a18\u8ff0\u65b9\u6cd5\u304c\u3042\u308a\u307e\u3059\u3002

\u8907\u6570\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u69cb\u6210\u3059\u308b\u8a18\u8ff0\u65b9\u6cd5

IP\u30a2\u30c9\u30ec\u30b9\u65b9\u5f0f\uff1a 1\u30ce\u30fc\u30c91IP\u30a2\u30c9\u30ec\u30b9\u306e\u5834\u5408(\u5206\u304b\u3089\u306a\u3044\u5834\u5408\u306f\u3053\u3061\u3089) [xxx.xxx.xxx]\u3092\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u3078\u66f8\u304d\u63db\u3048

    --pool-relay-ipv4 xxx.xxx.xxx \\\n    --pool-relay-port 6000 \\\n    --pool-relay-ipv4 xxx.xxx.xxx \\\n    --pool-relay-port 6000 \\\n

DNS\u65b9\u5f0f\uff1a1\u3064\u306e\u30a8\u30f3\u30c8\u30ea\u30fc\u306e\u5834\u5408 [relay1.yourdomain.com]\u3092\u3042\u306a\u305f\u306e\u30c9\u30e1\u30a4\u30f3\u540d\u306b\u66f8\u304d\u63db\u3048

    --single-host-pool-relay relay1.yourdomain.com \\\n    --pool-relay-port 6000 \\\n    --single-host-pool-relay relay2.yourdomain.com \\\n    --pool-relay-port 6000 \\\n

\u30e9\u30a6\u30f3\u30c9\u30ed\u30d3\u30f3DNS\u30d9\u30fc\u30b9 SRV DNS record\u306e\u5834\u5408 [relay.yourdomain.com]\u3092\u3042\u306a\u305f\u306e\u30c9\u30e1\u30a4\u30f3\u540d\u306b\u66f8\u304d\u63db\u3048

    --multi-host-pool-relay relay.yourdomain.com \\\n    --pool-relay-port 6000 \\\n

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3(\u30ea\u30ec\u30fc1\u53f0\u306e\u5834\u5408)\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3(\u30ea\u30ec\u30fc2\u53f0\u306e\u5834\u5408)

\u4e0b\u8a18\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u306f\u4f8b\u3067\u3059\u3002\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u904b\u7528\u8a2d\u5b9a\u5024\u306b\u5909\u66f4\u3057\u3066\u304b\u3089\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u5024\u3092\u5909\u66f4\u3059\u308b

--pool-pledge \u8a93\u7d04\u6570 --pool-cost \u56fa\u5b9a\u624b\u6570\u6599 --pool-margin \u5909\u52d5\u624b\u6570\u6599 ***.***.***.***\u306f\u30ea\u30ec\u30fc1\u306eIP\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044 https://xxx.github.io/xxx/poolMetaData.json \u306f\u3054\u81ea\u8eab\u306e\u30e1\u30bf\u30c7\u30fc\u30bfURL\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044

cd $NODE_HOME\ncardano-cli stake-pool registration-certificate \\\n    --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n    --vrf-verification-key-file vrf.vkey \\\n    --pool-pledge 100000000 \\\n    --pool-cost 170000000 \\\n    --pool-margin 0.05 \\\n    --pool-reward-account-verification-key-file stake.vkey \\\n    --pool-owner-stake-verification-key-file stake.vkey \\\n    $NODE_NETWORK \\\n    --pool-relay-ipv4 ***.***.***.*** \\\n    --pool-relay-port 6000 \\\n    --metadata-url https://xxx.github.io/xxx/poolMetaData.json \\\n    --metadata-hash $(cat poolMetaDataHash.txt) \\\n    --out-file pool.cert\n

\u4e0b\u8a18\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u306f\u4f8b\u3067\u3059\u3002\u3054\u81ea\u8eab\u306e\u30d7\u30fc\u30eb\u904b\u7528\u8a2d\u5b9a\u5024\u306b\u5909\u66f4\u3057\u3066\u304b\u3089\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u5024\u3092\u5909\u66f4\u3059\u308b

--pool-pledge \u8a93\u7d04\u6570 --pool-cost \u56fa\u5b9a\u624b\u6570\u6599 --pool-margin \u5909\u52d5\u624b\u6570\u6599 ***.***.***.***\u306f\u30ea\u30ec\u30fc1\u3001\u30ea\u30ec\u30fc2\u306eIP\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044 https://xxx.github.io/xxx/poolMetaData.json \u306f\u3054\u81ea\u8eab\u306e\u30e1\u30bf\u30c7\u30fc\u30bfURL\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044

cd $NODE_HOME\ncardano-cli stake-pool registration-certificate \\\n    --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n    --vrf-verification-key-file vrf.vkey \\\n    --pool-pledge 100000000 \\\n    --pool-cost 170000000 \\\n    --pool-margin 0.05 \\\n    --pool-reward-account-verification-key-file stake.vkey \\\n    --pool-owner-stake-verification-key-file stake.vkey \\\n    $NODE_NETWORK \\\n    --pool-relay-ipv4 ***.***.***.*** \\\n    --pool-relay-port 6000 \\\n    --pool-relay-ipv4 ***.***.***.*** \\\n    --pool-relay-port 6000 \\\n    --metadata-url https://xxx.github.io/xxx/poolMetaData.json \\\n    --metadata-hash $(cat poolMetaDataHash.txt) \\\n    --out-file pool.cert\n

\u81ea\u8eab\u306e\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u306b\u59d4\u4efb\u3059\u308b\u8a3c\u660e\u66f8(deleg.cert)\u3092\u4f5c\u6210\u3057\u307e\u3059

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3
cardano-cli stake-address delegation-certificate \\\n    --stake-verification-key-file stake.vkey \\\n    --cold-verification-key-file $HOME/cold-keys/node.vkey \\\n    --out-file deleg.cert\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306epool.cert\u3068deleg.cert\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|pool.cert / deleg.cert| B[BP];

"},{"location":"setup/7-register-stakepool/#3","title":"3.\u30d7\u30fc\u30eb\u767b\u9332\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u9001\u4fe1","text":"

\u6700\u65b0\u306e\u30b9\u30ed\u30c3\u30c8\u756a\u53f7\u3092\u53d6\u5f97\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncurrentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')\necho Current Slot: $currentSlot\n

payment.addr\u306e\u6b8b\u9ad8\u3092\u51fa\u529b\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli query utxo \\\n    --address $(cat payment.addr) \\\n    $NODE_NETWORK > fullUtxo.out\n\ntail -n +3 fullUtxo.out | sort -k3 -nr > balance.out\n\ncat balance.out\n

UTXO\u3092\u7b97\u51fa\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
tx_in=\"\"\ntotal_balance=0\nwhile read -r utxo; do\n    in_addr=$(awk '{ print $1 }' <<< \"${utxo}\")\n    idx=$(awk '{ print $2 }' <<< \"${utxo}\")\n    utxo_balance=$(awk '{ print $3 }' <<< \"${utxo}\")\n    total_balance=$((${total_balance}+${utxo_balance}))\n    echo TxHash: ${in_addr}#${idx}\n    echo ADA: ${utxo_balance}\n    tx_in=\"${tx_in} --tx-in ${in_addr}#${idx}\"\ndone < balance.out\ntxcnt=$(cat balance.out | wc -l)\necho Total ADA balance: ${total_balance}\necho Number of UTXOs: ${txcnt}\n

poolDeposit\u3092\u51fa\u529b\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
poolDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakePoolDeposit')\necho poolDeposit: $poolDeposit\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4eee\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+$(( ${total_balance} - ${poolDeposit}))  \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee 0 \\\n    --certificate-file pool.cert \\\n    --certificate-file deleg.cert \\\n    --out-file tx.tmp\n

\u6700\u4f4e\u624b\u6570\u6599\u3092\u8a08\u7b97\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
fee=$(cardano-cli transaction calculate-min-fee \\\n    --tx-body-file tx.tmp \\\n    --tx-in-count ${txcnt} \\\n    --tx-out-count 1 \\\n    $NODE_NETWORK \\\n    --witness-count 3 \\\n    --byron-witness-count 0 \\\n    --protocol-params-file params.json | awk '{ print $1 }')\necho fee: $fee\n

\u8a08\u7b97\u7d50\u679c\u3092\u51fa\u529b\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
txOut=$((${total_balance}-${poolDeposit}-${fee}))\necho txOut: ${txOut}\n

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction build-raw \\\n    ${tx_in} \\\n    --tx-out $(cat payment.addr)+${txOut} \\\n    --invalid-hereafter $(( ${currentSlot} + 10000)) \\\n    --fee ${fee} \\\n    --certificate-file pool.cert \\\n    --certificate-file deleg.cert \\\n    --out-file tx.raw\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

BP\u306etx.raw\u3092\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[BP] -->|tx.raw| B[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306b\u7f72\u540d\u3057\u307e\u3059

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3
cd $NODE_HOME\ncardano-cli transaction sign \\\n    --tx-body-file tx.raw \\\n    --signing-key-file payment.skey \\\n    --signing-key-file $HOME/cold-keys/node.skey \\\n    --signing-key-file stake.skey \\\n    $NODE_NETWORK \\\n    --out-file tx.signed\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306etx.signed\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|tx.signed| B[BP];

\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cardano-cli transaction submit \\\n    --tx-file tx.signed \\\n    $NODE_NETWORK\n

Transacsion Successfully submitted\u3068\u8868\u793a\u3055\u308c\u308c\u3070\u6210\u529f

"},{"location":"setup/7-register-stakepool/#4","title":"4. \u30d7\u30fc\u30eb\u767b\u9332\u78ba\u8a8d","text":"

\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30ebID\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u51fa\u529b\u3067\u304d\u307e\u3059

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3
chmod u+rwx $HOME/cold-keys\ncardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format bech32 --out-file pool.id-bech32\ncardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format hex --out-file pool.id\nchmod a-rwx $HOME/cold-keys\n

\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306epool.id-bech32\u3068pool.id\u3092BP\u306ecnode\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002

graph LR\n    A[\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7] -->|pool.id-bech32 / pool.id| B[BP];

\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3001\u30d7\u30fc\u30eb\u60c5\u5831\u304c\u8868\u793a\u3055\u308c\u308c\u3070\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
curl -s -X POST \"https://api.koios.rest/api/v0/pool_info\" \\\n    -H \"Accept: application/json\" \\\n    -H \"Content-Type: application/json\" \\\n    -d '{\"_pool_bech32_ids\":[\"'$(cat $NODE_HOME/pool.id-bech32)'\"]}' | jq .\n

\u81ea\u5206\u306e\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u304cCardanoscan\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u307e\u3059

\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\ncat pool.id-bech32\n

\u8868\u793a\u3055\u308c\u305fPoolID\u3067\u3042\u306a\u305f\u306e\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u304c\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u304b\u3001\u6b21\u306e\u30b5\u30a4\u30c8\u3067\u78ba\u8a8d\u3059\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002 Cardanoscan

\u3042\u3068\u4e00\u606f\u3067\u3059\uff01

\u4e0a\u8a18\u30b5\u30a4\u30c8\u3067\u3042\u306a\u305f\u306e\u30d7\u30fc\u30eb\u30c6\u30a3\u30c3\u30ab\u30fc\u304c\u8868\u793a\u3055\u308c\u305f\u3089\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u306b\u767b\u9332\u3055\u308c\u307e\u3057\u305f\uff01\u3057\u304b\u3057\u307e\u3060\u30d6\u30ed\u30c3\u30af\u751f\u6210\u3067\u304d\u308b\u72b6\u614b\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u3053\u306e\u5f8c\u3082\u91cd\u8981\u306a\u4f5c\u696d\u304c\u7d9a\u304d\u307e\u3059\u304c\u3082\u3046\u5c11\u3057\u9811\u5f35\u3063\u3066\u304f\u3060\u3055\u3044\uff01

"},{"location":"setup/8.topology-setup/","title":"8.P2P\u30c8\u30dd\u30ed\u30b8\u30fc\u8a2d\u5b9a","text":"

\u524d\u63d0\u6761\u4ef6

\u3053\u306e\u9805\u76ee\u306f\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3067\u5b9f\u65bd\u3057\u307e\u3059 \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u304c\u8d77\u52d5\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044**

journalctl --unit=cardano-node --follow\n

\u91cd\u8981\uff1a\u30c8\u30dd\u30ed\u30b8\u30fc\u306e\u5f62\u6210\u306b\u3064\u3044\u3066

2022/01/07\u6642\u70b9\u3067\u306f\u624b\u52d5P2P(\u30d4\u30a2\u30fb\u30c4\u30fc\u30fb\u30d4\u30a2)\u30e2\u30fc\u30c9\u306e\u305f\u3081\u3001\u624b\u52d5\u3067\u30c8\u30dd\u30ed\u30b8\u30fc\u3092\u69cb\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u3053\u306e\u624b\u9806\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u3068\u751f\u6210\u3057\u305f\u30d6\u30ed\u30c3\u30af\u304c\u30d6\u30ed\u30c3\u30af\u30c1\u30a7\u30fc\u30f3\u5916\u3067\u5b64\u7acb\u3059\u308b\u305f\u3081\u3001\u5fc5\u9808\u306e\u8a2d\u5b9a\u9805\u76ee\u3068\u306a\u308a\u307e\u3059\u3002

"},{"location":"setup/8.topology-setup/#topologyupdater","title":"TopologyUpdater\u306e\u8a2d\u5b9a","text":"\u30d5\u30a1\u30a4\u30eb \u7528\u9014 topologyUpdater.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u767b\u9332\u30b9\u30af\u30ea\u30d7\u30c8 relay-topology_pull.sh \u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u751f\u6210\u30b9\u30af\u30ea\u30d7\u30c8

\u30ce\u30fc\u30c9\u60c5\u5831\u3092\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u306b\u767b\u9332\u3059\u308b\u30b9\u30af\u30ea\u30d7\u30c8\u300ctopologyUpdater.sh\u300d\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002

topologyUpdater.sh\u306b\u3064\u3044\u3066

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u60c5\u5831(IP\u30a2\u30c9\u30ec\u30b9\u3068\u30dd\u30fc\u30c8\u756a\u53f7\u3001\u30aa\u30f3/\u30aa\u30d5\u30e9\u30a4\u30f3\u72b6\u614b)\u3092\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u30781\u6642\u9593\u306b1\u56de\u9001\u4fe1\u3059\u308b\u3053\u3068\u3067\u3001\u4e16\u754c\u4e2d\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306b\u81ea\u30d7\u30fc\u30eb\u306e\u30ea\u30ec\u30fc\u60c5\u5831\u304c\u767b\u9332\u3055\u308c\u308b\u4ed5\u7d44\u307f\u3067\u3059

"},{"location":"setup/8.topology-setup/#_1","title":"\u30b9\u30af\u30ea\u30d7\u30c8\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210","text":"

\u6ce8\u610f

\u4ee5\u4e0b\u306f\u3001\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP\u3068\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u306b\u5408\u308f\u305b\u308b CNODE_HOSTNAME\u306e\u300cxxx.xxx.xxx.xx\u300d\u306f\u30ea\u30ec\u30fc\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044 \u30dd\u30fc\u30c8\u756a\u53f7\u30926000\u304b\u3089\u5909\u66f4\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044 \u203b26\u884c\u76ee\u306e\"CHANGE ME\"\u306f\u5909\u66f4\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cat > $NODE_HOME/topologyUpdater.sh << EOF\n#!/bin/bash\n# shellcheck disable=SC2086,SC2034\n\nUSERNAME=$(whoami)\nCNODE_PORT=6000\nCNODE_HOSTNAME=\"xxx.xxx.xxx.xx\"\nCNODE_BIN=\"/usr/local/bin\"\nCNODE_HOME=$NODE_HOME\nCNODE_LOG_DIR=\"\\${CNODE_HOME}/logs\"\nGENESIS_JSON=\"\\${CNODE_HOME}/${NODE_CONFIG}-shelley-genesis.json\"\nNETWORKID=\\$(jq -r .networkId \\$GENESIS_JSON)\nCNODE_VALENCY=1   # optional for multi-IP hostnames\nNWMAGIC=\\$(jq -r .networkMagic < \\$GENESIS_JSON)\n[[ \"\\${NETWORKID}\" = \"Mainnet\" ]] && HASH_IDENTIFIER=\"--mainnet\" || HASH_IDENTIFIER=\"--testnet-magic \\${NWMAGIC}\"\n[[ \"\\${NWMAGIC}\" = \"764824073\" ]] && NETWORK_IDENTIFIER=\"--mainnet\" || NETWORK_IDENTIFIER=\"--testnet-magic \\${NWMAGIC}\"\n\nexport PATH=\"\\${CNODE_BIN}:\\${PATH}\"\nexport CARDANO_NODE_SOCKET_PATH=\"\\${CNODE_HOME}/db/socket\"\n\nblockNo=\\$(/usr/local/bin/cardano-cli query tip \\${NETWORK_IDENTIFIER} | jq -r .block )\n\n# Note:\n# if you run your node in IPv4/IPv6 dual stack network configuration and want announced the\n# IPv4 address only please add the -4 parameter to the curl command below  (curl -4 -s ...)\nif [ \"\\${CNODE_HOSTNAME}\" != \"CHANGE ME\" ]; then\nT_HOSTNAME=\"&hostname=\\${CNODE_HOSTNAME}\"\nelse\nT_HOSTNAME=''\nfi\n\nif [ ! -d \\${CNODE_LOG_DIR} ]; then\nmkdir -p \\${CNODE_LOG_DIR};\nfi\n\ncurl -4 -s \"https://api.clio.one/htopology/v1/?port=\\${CNODE_PORT}&blockNo=\\${blockNo}&valency=\\${CNODE_VALENCY}&magic=\\${NWMAGIC}\\${T_HOSTNAME}\" | tee -a \\$CNODE_LOG_DIR/topologyUpdater_lastresult.json\nEOF\n

\u6a29\u9650\u3092\u8ffd\u52a0\u3057\u3001\u300ctopologyUpdater.sh\u300d\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nchmod +x topologyUpdater.sh\n./topologyUpdater.sh\n

topologyUpdater.sh\u304c\u6b63\u5e38\u306b\u5b9f\u884c\u3055\u308c\u305f\u5834\u5408\u3001\u4ee5\u4e0b\u306e\u5f62\u5f0f\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002

{ \"resultcode\": \"201\", \"datetime\":\"2020-07-28 01:23:45\", \"clientIp\": \"1.2.3.4\", \"iptype\": 4, \"msg\": \"nice to meet you\" }

\u6ce8\u610f

\u203btopologyUpdater.sh\u306f1\u6642\u9593\u4ee5\u5185\u306b2\u56de\u4ee5\u4e0a\u5b9f\u884c\u3057\u306a\u3044\u3067\u4e0b\u3055\u3044\u3002\u6700\u60aa\u306e\u5834\u5408\u30d6\u30e9\u30c3\u30af\u30ea\u30b9\u30c8\u306b\u8ffd\u52a0\u3055\u308c\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002\u30b9\u30af\u30ea\u30d7\u30c8\u304c\u5b9f\u884c\u3055\u308c\u308b\u305f\u3073\u306b\u3001$NODE_HOME/logs\u306b\u30ed\u30b0\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002

"},{"location":"setup/8.topology-setup/#cron","title":"Cron\u30b8\u30e7\u30d6\u306e\u8a2d\u5b9a","text":"

crontab\u30b8\u30e7\u30d6\u3092\u8ffd\u52a0\u3057\u3001\u300ctopologyUpdater.sh\u300d\u30921\u6642\u9593\u306b1\u56de\u81ea\u52d5\u5b9f\u884c\u3055\u308c\u308b\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u307e\u3059\u3002

\u6ce8\u610f

  • \u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u306f\u8907\u6570\u56de\u5b9f\u884c\u3057\u306a\u3044\u3067\u4e0b\u3055\u3044\u3002\u8907\u6570\u56de\u5b9f\u884c\u3057\u305f\u5834\u5408\u3001\u540c\u3058\u6642\u9593\u306b\u8907\u6570\u81ea\u52d5\u5b9f\u884c\u3055\u308c\u308b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u304c\u767b\u9332\u3055\u308c\u3066\u3057\u307e\u3046\u306e\u3067\u3001\u30d6\u30e9\u30c3\u30af\u30ea\u30b9\u30c8\u306b\u5165\u308a\u307e\u3059\u3002
  • \u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u306f\u6bce\u66425\u5206\u306b\u5b9f\u884c\u3055\u308c\u308b\u3088\u3046\u306b\u6307\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002 \u3000
\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cat > $NODE_HOME/crontab-fragment.txt << EOF\n5 * * * * ${NODE_HOME}/topologyUpdater.sh\nEOF\ncrontab -l | cat - crontab-fragment.txt >crontab.txt && crontab crontab.txt\nrm crontab-fragment.txt\n

no crontab for ~~ \u3068\u3044\u3046\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308b\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u304c\u3001Cron\u521d\u56de\u8a2d\u5b9a\u6642\u306b\u8868\u793a\u3055\u308c\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u3068\u306a\u308a\u307e\u3059\u306e\u3067\u3001\u554f\u984c\u3042\u308a\u307e\u305b\u3093\u3002

crontab -l\n
\u4ee5\u4e0b\u304c\u8fd4\u308a\u5024\u3068\u3057\u3066\u8868\u793a\u3055\u308c\u308c\u3070OK\u3002

\"5 * * * * /home/***/cnode/topologyUpdater.sh\"

\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u3078\u306e\u767b\u9332\u306b\u3064\u3044\u3066

4\u6642\u9593\u306e\u9593\u30674\u56de\u30b9\u30af\u30ea\u30d7\u30c8\u304c\u5b9f\u884c\u3055\u308c\u305f\u5f8c\u306b\u3001\u30ce\u30fc\u30c9\u304c\u30aa\u30f3\u30e9\u30a4\u30f3\u72b6\u614b\u3067\u6709\u308b\u3053\u3068\u304c\u8a8d\u3081\u3089\u308c\u305f\u5834\u5408\u306b\u30ce\u30fc\u30c9IP\u304c\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u306b\u767b\u9332\u3055\u308c\u307e\u3059\u3002\u4e0a\u8a18\u8a2d\u5b9a\u304b\u30894\u6642\u9593\u5f8c\u306b\u6b21\u306e\u9805\u76ee\u3092\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/8.topology-setup/#_2","title":"\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u767b\u9332\u78ba\u8a8d","text":"\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME/logs\ncat topologyUpdater_lastresult.json\n

\u4ee5\u4e0b\u306e\u5185\u5bb9\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308c\u3070\u767b\u9332\u6210\u529f \u6700\u5f8c\u306e\u4e00\u884c\u304c\u6700\u65b0\u306eresultcode\u306b\u306a\u308a\u3001400\u756a\u53f0\u30fb500\u756a\u53f0\u306e\u5834\u5408\u306f\u3001\u30b5\u30fc\u30d0\u8a2d\u5b9a\u306b\u554f\u984c\u304c\u3042\u308a\u307e\u3059\u3002

{ \"resultcode\": \"201\", \"datetime\":\"2021-01-10 18:30:06\", \"clientIp\": \"000.000.000.000\", \"iptype\": 4, \"msg\": \"nice to meet you\" }\n{ \"resultcode\": \"203\", \"datetime\":\"2021-01-10 19:30:03\", \"clientIp\": \"000.000.000.000\", \"iptype\": 4, \"msg\": \"welcome to the topology\" }\n{ \"resultcode\": \"204\", \"datetime\":\"2021-01-10 20:30:04\", \"clientIp\": \"000.000.000.000\", \"iptype\": 4, \"msg\": \"glad you're staying with us\" }\n

"},{"location":"setup/8.topology-setup/#_3","title":"\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u751f\u6210\u3059\u308b","text":"

\u524d\u63d0\u6761\u4ef6

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9IP\u304c\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a7\u30c3\u30c1\u30ea\u30b9\u30c8\u306b\u767b\u9332\u3055\u308c\u305f\u3053\u3068\u3092\u78ba\u8a8d\u5f8c\u3001\u4ee5\u4e0b\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3057\u3066\u4e0b\u3055\u3044\u3002

\u30c8\u30dd\u30ed\u30b8\u30fc\u306e\u5f62\u6210\u65b9\u6cd5\u25bc

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u66f4\u65b0\u3059\u308brelay-topology_pull.sh\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002 \u3053\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u4f5c\u6210\u30fb\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u3001\u4e16\u754c\u4e2d\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u60c5\u5831\u306e\u4e2d\u304b\u3089\u81ea\u5206\u306e\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u306b\u5bfe\u3057\u3066\u8fd1\u8ddd\u96e2\u30fb\u4e2d\u8ddd\u96e2\u30fb\u9060\u8ddd\u96e2\u306b\u5206\u6563\u3057\u305f\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u62bd\u51fa\u3057\u534a\u81ea\u52d5\u3067\u30c8\u30dd\u30ed\u30b8\u30fc\u3092\u5f62\u6210\u3067\u304d\u307e\u3059\u3002

\u500b\u5225\u306b\u8ffd\u52a0\u3057\u305f\u3044\u5834\u5408\u25bc

\u203b\u304a\u77e5\u308a\u5408\u3044\u306e\u30ce\u30fc\u30c9\u3084\u81ea\u30ce\u30fc\u30c9\u304c\u8907\u6570\u3042\u308b\u5834\u5408\u306f\u3001IOHK\u30ce\u30fc\u30c9\u60c5\u5831\u306e\u5f8c\u306b \"|\" \u3067\u533a\u5207\u3063\u3066IP\u30a2\u30c9\u30ec\u30b9:\u30dd\u30fc\u30c8\u756a\u53f7:Valency \u306e\u5f62\u5f0f\u3067\u8ffd\u52a0\u3067\u304d\u307e\u3059\u3002

|relays-new.cardano-mainnet.iohk.io:3001:2|relay1-eu.xstakepool.com:3001:1|00.000.000.00:3001:1\n

\u6ce8\u610f

\u4ee5\u4e0b\u306f\u3001BP\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP\u3068\u30ce\u30fc\u30c9\u30dd\u30fc\u30c8\u306b\u66f8\u304d\u63db\u3048\u3066\u304b\u3089\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3059\u308b BLOCKPRODUCING_IP\u306e\u300cxxx.xxx.xxx\u300d\u306fBP\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044 BLOCKPRODUCING_PORT\u306f\u4efb\u610f\u3067\u8a2d\u5b9a\u3057\u305f\u756a\u53f7\u306b\u7f6e\u304d\u63db\u3048\u3066\u304f\u3060\u3055\u3044\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cat > $NODE_HOME/relay-topology_pull.sh << EOF\n#!/bin/bash\nBLOCKPRODUCING_IP=xxx.xxx.xxx\nBLOCKPRODUCING_PORT=xxxxx\nPEERS=18\ncp $NODE_HOME/${NODE_CONFIG}-topology.json $NODE_HOME/${NODE_CONFIG}-topology-bk.json\ncurl -4 -s -o $NODE_HOME/${NODE_CONFIG}-topology.json \"https://api.clio.one/htopology/v1/fetch/?max=\\${PEERS}&customPeers=\\${BLOCKPRODUCING_IP}:\\${BLOCKPRODUCING_PORT}:1|relays-new.cardano-mainnet.iohk.io:3001:2\"\nEOF\n

sh\u30d5\u30a1\u30a4\u30eb\u306b\u6a29\u9650\u3092\u8ffd\u52a0\u3057\u3001relay-topology_pull.sh\u3092\u5b9f\u884c\u3059\u308b

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
cd $NODE_HOME\nchmod +x relay-topology_pull.sh\n./relay-topology_pull.sh\n

relay-topology_pull.sh\u3092\u5b9f\u884c\u3059\u308b\u3068\u65b0\u3057\u3044\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb(mainnet-topology.json)\u3092\u751f\u6210\u3057\u307e\u3059\u3002

\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u3092\u66f4\u65b0\u3057\u305f\u5834\u5408\u306f\u3001\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b\u3053\u3068\u3092\u5fd8\u308c\u306a\u3044\u3067\u4e0b\u3055\u3044\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9
sudo systemctl reload-or-restart cardano-node\n

\u91cd\u8981\u306a\u78ba\u8a8d\u4e8b\u9805

\u30d6\u30ed\u30c3\u30af\u3092\u751f\u6210\u3059\u308b\u306b\u306f\u3001\u300cTotal Tx\u300d\u304c\u5897\u52a0\u3057\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u4e07\u4e00\u3001\u5897\u52a0\u3057\u3066\u3044\u306a\u3044\u5834\u5408\u306b\u306f\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3084\u30c8\u30dd\u30ed\u30b8\u30fc\u30d5\u30a1\u30a4\u30eb\u306e\u5185\u5bb9\u3092\u518d\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u300cP2P\u300d\u6570\u306f\u30ce\u30fc\u30c9\u304c\u4ed6\u30ce\u30fc\u30c9\u3068\u63a5\u7d9a\u3057\u3066\u3044\u308b\u6570\u3092\u8868\u3057\u3066\u3044\u307e\u3059\u3002

\ud83d\udee0 \u30ea\u30ec\u30fc\u30ce\u30fc\u30c9/BP\u3067gLiveView \u3092\u78ba\u8a8d

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9/BP
cd $NODE_HOME/scripts\n./gLiveView.sh\n

\u300cTotal Tx\u300d\u304c\u5897\u52a0\u3057\u3066\u3044\u308b\u304b\u78ba\u8a8d\u3059\u308b

\u304a\u3081\u3067\u3068\u3046\u3054\u3056\u3044\u307e\u3059\uff01

Total Tx\u306e\u5897\u52a0\u304c\u78ba\u8a8d\u3067\u304d\u308c\u3070\u3001\u30d6\u30ed\u30c3\u30af\u3092\u4f5c\u6210\u3059\u308b\u6e96\u5099\u304c\u51fa\u6765\u3066\u3044\u307e\u3059\u3002

"},{"location":"setup/8.topology-setup/#_4","title":"\u30ce\u30fc\u30c9\u8d77\u52d5\u6700\u7d42\u8abf\u6574","text":""},{"location":"setup/8.topology-setup/#_5","title":"\u30d6\u30ed\u30c3\u30af\u751f\u6210\u53ef\u80fd\u72b6\u614b\u30c1\u30a7\u30c3\u30af","text":"

SPO JAPAN GUILD TOOL\u3092\u5c0e\u5165\u3059\u308b

\u5c0e\u5165\u624b\u9806\u306f\u30d7\u30fc\u30eb\u69cb\u7bc9\u30de\u30cb\u30e5\u30a2\u30eb\u5185\u306eSJG TOOL\u3092\u3054\u53c2\u7167\u304f\u3060\u3055\u3044

TOOL\u3092\u5b9f\u884c\u3059\u308b

gtool\n

[2] \u30d6\u30ed\u30c3\u30af\u751f\u6210\u72b6\u614b\u30c1\u30a7\u30c3\u30af \u3092\u9078\u629e\u3059\u308b

"},{"location":"setup/8.topology-setup/#tracemempool","title":"Tracemempool\u7121\u52b9","text":"

\u91cd\u8981\u306a\u6700\u7d42\u8abf\u6574

\u30ce\u30fc\u30c9\u7a3c\u50cd\u6642\u306e\u3001CPU/\u30e1\u30e2\u30ea\u6d88\u8cbb\u3092\u6291\u3048\u308b\u305f\u3081\u30ce\u30fc\u30c9\u8a2d\u5b9a\u3092\u8abf\u6574\u3057\u307e\u3059\u3002 \u3053\u306e\u8abf\u6574\u306f\u30d7\u30fc\u30eb\u904b\u55b6\u306e\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u5de6\u53f3\u3057\u307e\u3059\u306e\u3067\u63a8\u5968\u8a2d\u5b9a\u3068\u306a\u308a\u307e\u3059\u3002

  • \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u6d41\u5165\u30ed\u30b0\u3092\u30c8\u30ec\u30fc\u30b9(\u8a18\u9332)\u3059\u308b\u3053\u3068\u3067\u3001CPU/\u30e1\u30e2\u30ea\u6d88\u8cbb\u3092\u5897\u52a0\u3055\u305b\u308b\u539f\u56e0\u3068\u306a\u308b\u3053\u3068\u304c\u308f\u304b\u3063\u3066\u3044\u308b\u305f\u3081\u3001\u3053\u306e\u6a5f\u80fd\u3092\u7121\u52b9\u306b\u3057\u307e\u3059\u3002
  • \u3053\u306e\u8a2d\u5b9a\u3092\u884c\u3046\u3068\u3001\u4e0a\u8a18\u3067\u78ba\u8a8d\u3057\u305f\u300cTotal TX\u300d\u300cPending Tx\u300d\u306f\u5897\u52a0\u3057\u306a\u304f\u306a\u308a\u307e\u3059\u304c\u3001\u8a2d\u5b9a\u524d\u306b\u5897\u52a0\u304c\u78ba\u8a8d\u3067\u304d\u3066\u3044\u308c\u3070\u554f\u984c\u3054\u3056\u3044\u307e\u305b\u3093
\u30ea\u30ec\u30fc/BP
sed -i $NODE_HOME/${NODE_CONFIG}-config.json \\\n    -e \"s/TraceMempool\\\": true/TraceMempool\\\": false/g\"\n

** \u30ce\u30fc\u30c9\u3092\u518d\u8d77\u52d5\u3059\u308b **

sudo systemctl reload-or-restart cardano-node\n

\u30ce\u30fc\u30c9\u30ed\u30b0\u306b\u30a8\u30e9\u30fc\u304c\u51fa\u3066\u3044\u306a\u3044\u304b\u78ba\u8a8d\u3059\u308b

journalctl --unit=cardano-node --follow\n

\uff01\u91cd\u8981\uff01

\u30d7\u30fc\u30eb\u904b\u7528\u30de\u30cb\u30e5\u30a2\u30eb\u904b\u7528\u30ac\u30a4\u30c9\u3092\u5fc5\u305a\u78ba\u8a8d\u3057\u3001\u30d7\u30fc\u30eb\u904b\u55b6\u306b\u3064\u3044\u3066\u5b66\u7fd2\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/9-monitoring-tools-setup/","title":"9.\u76e3\u8996\u30c4\u30fc\u30eb\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7","text":"

\u30d7\u30ed\u30e1\u30c6\u30a6\u30b9\u306f\u30bf\u30fc\u30b2\u30c3\u30c8\u306b\u6307\u5b9a\u3057\u305f\u30e1\u30c8\u30ea\u30c3\u30afHTTP\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3057\u3001\u60c5\u5831\u3092\u53ce\u96c6\u3059\u308b\u76e3\u8996\u30c4\u30fc\u30eb\u3067\u3059\u3002\u30aa\u30d5\u30a3\u30b7\u30e3\u30eb\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306f\u3053\u3061\u3089 \u30b0\u30e9\u30d5\u30a1\u30ca\u306f\u53ce\u96c6\u3055\u308c\u305f\u30c7\u30fc\u30bf\u3092\u8996\u899a\u7684\u306b\u8868\u793a\u3055\u305b\u308b\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u30c4\u30fc\u30eb\u3067\u3059\u3002

"},{"location":"setup/9-monitoring-tools-setup/#9-1","title":"9-1.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u6982\u8981

\u300cprometheus\u300d\u304a\u3088\u3073\u300cprometheus node exporter\u300d\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002 \u3053\u306e\u624b\u9806\u3067\u306f\u3001\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u3067prometheus\u3068Grafana\u672c\u4f53\u3092\u7a3c\u50cd\u3055\u305b\u3001\u5404\u30b5\u30fc\u30d0\u30fc\u306e\u60c5\u5831\u3092\u53d6\u5f97\u3059\u308b\u65b9\u6cd5\u3067\u3059\u3002

\u69cb\u6210\u56f3

    flowchart TB\n        bp[\u30ed\u30fc\u30ab\u30ebPC] -- 3000\u30dd\u30fc\u30c8\u958b\u653e --> a1[Grafana] \n        a2[prometheus] -- \u30ea\u30ec\u30fc1IP\u6307\u5b9a\u3067<br>9100/12798\u30dd\u30fc\u30c8\u958b\u653e --> ide2[BP] & ide3[\u30ea\u30ec\u30fc2]\n        subgraph ide1[\u30ea\u30ec\u30fc1]\n            a1[Grafana] <--> a2[prometheus]\n        end\n        subgraph ide2[BP]\n            a3[node-exporter]\n        end\n        subgraph ide3[\u30ea\u30ec\u30fc2]\n            a4[node-exporter]\n        end

prometheus\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91BP\u307e\u305f\u306f\u30ea\u30ec\u30fc2\u4ee5\u964d
sudo apt install -y prometheus prometheus-node-exporter\n
sudo apt install -y prometheus-node-exporter\n

grafana\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91

sudo apt-get install -y apt-transport-https software-properties-common\n
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key\n
echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main\" > grafana.list\nsudo mv grafana.list /etc/apt/sources.list.d/grafana.list\n
sudo apt update && sudo apt install -y grafana\n

\u30b5\u30fc\u30d3\u30b9\u6709\u52b9\u5316\u3068\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3092\u8a2d\u5b9a\u3059\u308b\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91BP\u307e\u305f\u306f\u30ea\u30ec\u30fc2\u4ee5\u964d
sudo systemctl enable grafana-server.service\nsudo systemctl enable prometheus.service\nsudo systemctl enable prometheus-node-exporter.service\n

FW\u8a2d\u5b9a\u3067Grafana\u30dd\u30fc\u30c8\u3092\u958b\u653e\u3059\u308b

sudo ufw allow 3000/tcp\nsudo ufw reload\n

sudo systemctl enable prometheus-node-exporter.service\n

FW\u8a2d\u5b9a\u3067Prometheus\u30e1\u30c8\u30ea\u30af\u30b9\u30dd\u30fc\u30c8\u3092\u30ea\u30ec\u30fc1\u306eIP\u9650\u5b9a\u3067\u958b\u653e\u3059\u308b

sudo ufw allow from <\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306eIP> to any port 12798\nsudo ufw allow from <\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306eIP> to any port 9100\nsudo ufw reload\n

prometheus-node-exporter\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c9/BP

prometheus-node-exporter\u306e\u30d1\u30b9\u3092\u53d6\u5f97\u3059\u308b

cd $HOME/git\nnodeexPath=`which prometheus-node-exporter`\n

1.5.0\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b

wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz\n

\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u51cd\u3059\u308b

tar xvf node_exporter-1.5.0.linux-amd64.tar.gz\n

\u30b5\u30fc\u30d3\u30b9\u3092\u505c\u6b62\u3059\u308b

sudo systemctl stop prometheus-node-exporter.service\n

\u30d0\u30a4\u30ca\u30ea\u30d5\u30a1\u30a4\u30eb\u3092\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30eb\u30c0\u3078\u30b3\u30d4\u30fc\u3059\u308b

cd node_exporter-1.5.0.linux-amd64\nsudo cp node_exporter $nodeexPath\n

\u30b5\u30fc\u30d3\u30b9\u3092\u30b9\u30bf\u30fc\u30c8\u3059\u308b

sudo systemctl start prometheus-node-exporter.service\n

\u30d0\u30fc\u30b8\u30e7\u30f3\u78ba\u8a8d

prometheus-node-exporter --version\n

\u623b\u308a\u50241\u884c\u76ee\u304cnode_exporter, version 1.5.0\u306a\u3089OK

"},{"location":"setup/9-monitoring-tools-setup/#9-2","title":"9-2.\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210","text":"

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u305fPrometheus\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002\u3053\u3053\u306b\u8a18\u8f09\u3055\u308c\u305f\u30b5\u30fc\u30d0\u30fc\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91(\u30ea\u30ec\u30fc1\u53f0\u306e\u5834\u5408)\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91(\u30ea\u30ec\u30fc2\u53f0\u306e\u5834\u5408)

\u6ce8\u610f

targets:\u306e\u300cxxx.xxx.xxx\u300d\u306f\u3001BP\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044

cat > $HOME/prometheus.yml << EOF\nglobal:\n  scrape_interval:     15s # By default, scrape targets every 15 seconds.\n\n  # Attach these labels to any time series or alerts when communicating with\n  # external systems (federation, remote storage, Alertmanager).\n  external_labels:\n    monitor: 'codelab-monitor'\n\n# A scrape configuration containing exactly one endpoint to scrape:\n# Here it's Prometheus itself.\nscrape_configs:\n  # The job name is added as a label job=<job_name> to any timeseries scraped from this config.\n  - job_name: 'prometheus'\n\n    static_configs:\n      - targets: ['localhost:9100']\n        labels:\n          alias: 'relaynode1'\n          type:  'system'\n      - targets: ['xxx.xxx.xxx.xxx:9100']\n        labels:\n          alias: 'block-producing-node'\n          type:  'system'\n      - targets: ['xxx.xxx.xxx.xxx:12798']\n        labels:\n          alias: 'block-producing-node'\n          type:  'cardano-node'\n      - targets: ['localhost:12798']\n        labels:\n          alias: 'relaynode1'\n          type:  'cardano-node'\nEOF\n

\u6ce8\u610f

targets:\u306e\u300cxxx.xxx.xxx\u300d\u306f\u3001BP\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044\u3002 targets:\u306e\u300cbb.xxx.xxx\u300d\u306f\u3001\u30ea\u30ec\u30fc2\u306e\u30d1\u30d6\u30ea\u30c3\u30afIP(\u9759\u7684)\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u3066\u4e0b\u3055\u3044\u3002

cat > $HOME/prometheus.yml << EOF\nglobal:\n  scrape_interval:     15s # By default, scrape targets every 15 seconds.\n\n  # Attach these labels to any time series or alerts when communicating with\n  # external systems (federation, remote storage, Alertmanager).\n  external_labels:\n    monitor: 'codelab-monitor'\n\n# A scrape configuration containing exactly one endpoint to scrape:\n# Here it's Prometheus itself.\nscrape_configs:\n  # The job name is added as a label job=<job_name> to any timeseries scraped from this config.\n  - job_name: 'prometheus'\n\n    static_configs:\n      - targets: ['localhost:9100']\n        labels:\n          alias: 'relaynode1'\n          type:  'system'\n      - targets: ['bb.xxx.xxx.xxx:9100']\n        labels:\n          alias: 'relaynode2'\n          type:  'system'\n      - targets: ['xx.xxx.xxx.xxx:9100']\n        labels:\n          alias: 'block-producing-node'\n          type:  'system'\n      - targets: ['xxx.xxx.xxx.xxx:12798']\n        labels:\n          alias: 'block-producing-node'\n          type:  'cardano-node'\n      - targets: ['localhost:12798']\n        labels:\n          alias: 'relaynode1'\n          type:  'cardano-node'\n      - targets: ['bb.xxx.xxx.xxx:12798']\n        labels:\n          alias: 'relaynode2'\n          type:  'cardano-node'\nEOF\n

prometheus.yml\u69cb\u6587\u30c1\u30a7\u30c3\u30af

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91
sudo promtool check config $HOME/prometheus.yml\n

\u623b\u308a\u5024\u78ba\u8a8d

\u69cb\u6587\u30a8\u30e9\u30fc\u306a\u3057\u306e\u5834\u5408

Checking /home/user/prometheus.yml\nSUCCESS: 0 rule files found\n

\u69cb\u6587\u30a8\u30e9\u30fc\u306e\u5834\u5408(\u4e00\u4f8b)

Checking /home/user/prometheus.yml\nFAILED: parsing YAML file /home/user/prometheus.yml: yaml: line XX: did not find expected '-' indicator\n

\u203b/home/user/prometheus.yml\uff08user\u306f\u5404\u81ea\u3067\u8a2d\u5b9a\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u540d\uff09

\u69cb\u6587\u30a8\u30e9\u30fc\u3060\u3063\u305f\u5834\u5408\u306f\u3001$HOME/prometheus.yml\u3092\u958b\u3044\u3066\u4f59\u5206\u306a\u30b9\u30da\u30fc\u30b9\u3084\u8a18\u53f7\u306e\u6709\u7121\u306a\u3069\u3092\u78ba\u8a8d\u3057\u3001\u4fee\u6b63\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo nano $HOME/prometheus.yml\n

\u4fee\u6b63\u3057\u305f\u3089\u3001Ctrl + O\u3067\u4fdd\u5b58\u3057\u3001Enter\u3002\u305d\u306e\u5f8cCtrl + X\u3067\u9589\u3058\u308b

prometheus.yml\u3092\u79fb\u52d5\u3057\u307e\u3059

sudo mv $HOME/prometheus.yml /etc/prometheus/prometheus.yml\n

Grafana\u30d7\u30e9\u30b0\u30a4\u30f3\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b

sudo grafana-cli plugins install yesoreyeram-infinity-datasource\n

\u30b5\u30fc\u30d3\u30b9\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91
sudo systemctl restart grafana-server.service\nsudo systemctl restart prometheus.service\nsudo systemctl restart prometheus-node-exporter.service\n

\u30b5\u30fc\u30d3\u30b9\u304c\u6b63\u3057\u304f\u5b9f\u884c\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91
sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service\n

\u623b\u308a\u5024\u78ba\u8a8d

  • grafana-server.service
  • prometheus.service
  • prometheus-node-exporter.service \u4e0a\u8a183\u3064\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u304c \u7dd1\u8272 active (running) \u306b\u306a\u3063\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002
"},{"location":"setup/9-monitoring-tools-setup/#_1","title":"\u65e2\u5b58\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u66f4\u65b0\u3059\u308b\u5834\u5408","text":"
sudo nano /etc/prometheus/prometheus.yml\n

\u4fee\u6b63\u3057\u305f\u3089\u3001Ctrl + O\u3067\u4fdd\u5b58\u3057\u3001Enter\u3002\u305d\u306e\u5f8cCtrl + X\u3067\u9589\u3058\u308b

prometheus.yml\u69cb\u6587\u30c1\u30a7\u30c3\u30af

\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91
sudo promtool check config /etc/prometheus/prometheus.yml\n

\u623b\u308a\u5024\u78ba\u8a8d

\u69cb\u6587\u30a8\u30e9\u30fc\u306a\u3057\u306e\u5834\u5408

Checking /etc/prometheus/prometheus.yml\nSUCCESS: 0 rule files found\n

\u69cb\u6587\u30a8\u30e9\u30fc\u306e\u5834\u5408(\u4e00\u4f8b)

Checking /etc/prometheus/prometheus.yml\nFAILED: parsing YAML file /etc/prometheus/prometheus.yml: yaml: line XX: did not find expected '-' indicator\n
/etc/prometheus/prometheus.yml\u3092\u958b\u3044\u3066\u4f59\u5206\u306a\u30b9\u30da\u30fc\u30b9\u3084\u8a18\u53f7\u306e\u6709\u7121\u306a\u3069\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u30b5\u30fc\u30d3\u30b9\u3092\u518d\u8d77\u52d5\u3059\u308b

sudo systemctl restart prometheus.service\n

"},{"location":"setup/9-monitoring-tools-setup/#9-3grafana","title":"9-3.Grafana\u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u306e\u8a2d\u5b9a","text":"
  1. \u30ed\u30fc\u30ab\u30ebPC\u306e\u30d6\u30e9\u30a6\u30b6\u304b\u3089 http://<\u30ea\u30ec\u30fc\u30ce\u30fc\u30c91IP\u30a2\u30c9\u30ec\u30b9>:3000 \u3092\u958b\u304d\u307e\u3059\u3002
  2. \u30ed\u30b0\u30a4\u30f3\u540d\u30fbPW\u306f admin / admin
  3. \u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5909\u66f4\u3057\u307e\u3059\u3002
  4. \u5de6\u4e0a\u306e\u4e09\u672c\u7dda\u30e1\u30cb\u30e5\u30fc\u3092\u958b\u304d\u300cConnections\u300d\u2192\u300cData sources\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002
  5. \u300cAdd new data source\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u300cPrometheus\u300d\u3092\u9078\u629e\u3057\u307e\u3059\u3002
  6. \u540d\u524d\u306f Prometheus\u3068\u3057\u3066\u304f\u3060\u3055\u3044\u3002
  7. URL \u3092 http://localhost:9090\u306b\u8a2d\u5b9a\u3057\u307e\u3059\u3002
  8. Save & Test\u3092\u30af\u30ea\u30c3\u30af\u3057Successfully queried the Prometheus API.\u3068\u8868\u793a\u3055\u308c\u305f\u3089\u518d\u5ea6Data sources\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002
  9. \u300cAdd new data source\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u4e0b\u90e8\u306b\u3042\u308b\u300cInfinity\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002
  10. \u8a2d\u5b9a\u5185\u5bb9\u3092\u5909\u66f4\u3059\u308b\u3053\u3068\u306a\u304f\u3001Save & Test\u3092\u30af\u30ea\u30c3\u30af\u3057Settings saved\u3068\u8868\u793a\u3055\u308c\u305f\u3089OK\u3002
  11. BP\u30b5\u30fc\u30d0\u30fc\u3067\u30d1\u30cd\u30eb\u7528JSON\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002
\u30d6\u30ed\u30c3\u30af\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u30ce\u30fc\u30c9

curl -s -o $NODE_HOME/SJG_Grafana_Dashboard.json https://raw.githubusercontent.com/akyo3/Extends-SJG-Knowledge/main/SJG_Grafana_Dashboard.json\n
\u4e00\u90e8\u30d5\u30a1\u30a4\u30eb\u5185\u5bb9\u3092\u66f8\u304d\u63db\u3048\u308b
sed -i $NODE_HOME/SJG_Grafana_Dashboard.json \\\n    -e \"s/bech32_id_of_your_pool/$(cat $NODE_HOME/pool.id-bech32)/g\"\n
12. BP\u306ecnode\u30d5\u30a9\u30eb\u30c0\u306b\u3042\u308bSJG_Grafana_Dashboard.json\u3092\u30ed\u30fc\u30ab\u30ebPC\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059 13. \u5de6\u30e1\u30cb\u30e5\u30fc\u306e\u300cDashboards\u300d\u2192\u300cNew\u300d\u2192\u300c+import\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002 14. \u300cUpload JSON file\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u300110\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fSJG_Grafana_Dashboard.json\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002 15. \u300cPrometheus\u300d\u3068\u300cInfinity\u300d\u306e\u30d7\u30eb\u30c0\u30a6\u30f3\u3092\u9078\u629e\u3057Import\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\ud83c\udf8a\u304a\u3081\u3067\u3068\u3046\u3054\u3056\u3044\u307e\u3059\ud83c\udf8a

\u3053\u308c\u3067\u57fa\u672c\u7684\u306a\u76e3\u8996\u8a2d\u5b9a\u306f\u5b8c\u4e86\u3067\u3059\u3002

\u4ee5\u4e0b\u306e\u8ffd\u52a0\u8a2d\u5b9a\u3082\u5b9f\u65bd\u3057\u3066\u304f\u3060\u3055\u3044\u3002

  • \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u5f37\u5316\u8a2d\u5b9a
  • \u7570\u5e38\u6642\u306b\u901a\u77e5\u3059\u308b\u30a2\u30e9\u30fc\u30c8\u8a2d\u5b9a
"},{"location":"setup/99-donation-credit/","title":"\uff0a\u5bc4\u4ed8\u3068\u30af\u30ec\u30b8\u30c3\u30c8","text":"

SPO JAPAN GUILD\u3067\u306f\u3001\u30b9\u30c6\u30fc\u30af\u30d7\u30fc\u30eb\u69cb\u7bc9\u30de\u30cb\u30e5\u30a2\u30eb\u306e\u6574\u5099\u3001\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306e\u904b\u55b6\u3001\u30db\u30fc\u30e0\u30da\u30fc\u30b8\u3067\u306e\u8a8d\u77e5\u6d3b\u52d5\u306a\u3069\u7686\u69d8\u306e\u30d7\u30fc\u30eb\u904b\u55b6\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u304a\u308a\u307e\u3059\u3002 \u4eca\u5f8c\u3082\u30ab\u30eb\u30c0\u30ce\u5206\u6563\u5316\u3092\u4fc3\u9032\u3059\u308b\u305f\u3081\u306b\u3082\u3001\u7d99\u7d9a\u6027\u306e\u3042\u308b\u6d3b\u52d5\u3092\u884c\u3063\u3066\u307e\u3044\u308a\u307e\u3059\u3002 \u5bc4\u4ed8\u3057\u3066\u9802\u3044\u305f\u8cc7\u91d1\u306f\u3001\u30db\u30fc\u30e0\u30da\u30fc\u30b8\u30b5\u30fc\u30d0\u30fc\u4ee3\u3001\u30c9\u30e1\u30a4\u30f3\u4ee3\u3001\u958b\u767a\u8cbb\u3001\u4eba\u4ef6\u8cbb\u3001\u30de\u30fc\u30b1\u30c6\u30a3\u30f3\u30b0\u8cbb\u306b\u4f7f\u7528\u3055\u305b\u3066\u3044\u305f\u3060\u304d\u307e\u3059\u3002

"},{"location":"setup/99-donation-credit/#spo-japan-guild","title":"SPO JAPAN GUILD\u30d7\u30fc\u30eb\u3078\u306e\u59d4\u4efb","text":"

\u79c1\u9054\u3092\u30b5\u30dd\u30fc\u30c8\u9802\u3051\u308b\u65b9\u306f\u5f53\u30d7\u30fc\u30eb\u3078\u59d4\u4efb\u9802\u3051\u307e\u3059\u3068\u5e78\u3044\u3067\u3059\u3002

Ticker\uff1aSJG

pool1sqpksswmxpgk6yxllyq9ad4qhtnt5qyz2pv5xmz6kkt5ujrgqwf\n
[SJG] SPO JAPAN GUILD POOLpool1sqpksswmxpgk6yxllyq9ad4qhtnt5qyz2pv5xmz6kkt5ujrgqwf

  • \u56fa\u5b9a\u624b\u6570\u6599\uff1a340ADA
  • \u5909\u52d5\u624b\u6570\u6599\uff1a20%\uff5e
"},{"location":"setup/99-donation-credit/#spo-japan-guild_1","title":"SPO JAPAN GUILD\u3078\u306e\u5bc4\u4ed8","text":"

ADA\u30a2\u30c9\u30ec\u30b9

addr1qxq6jar2wtktu3nlak78ghugtd8vcxcze33wsk2ehlwkavp2f4gnzre574n6an99yql25wcy09ygededc7e6f77jutvs0lgxef\n

ADA Handle

ADA Handle\u5bfe\u5fdc\u30a6\u30a9\u30ec\u30c3\u30c8\u304b\u3089\u306a\u3089 \u300c$spojapanguild\u300d\u5b9b\u3066\u3067\u3082\u5bc4\u4ed8\u3044\u305f\u3060\u3051\u307e\u3059\uff01

$spojapanguild\n

"},{"location":"setup/air-gap-guid/","title":"\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u306e\u4f5c\u6210","text":"

\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30de\u30b7\u30f3\u3068\u306f\uff1f

\u30d7\u30fc\u30eb\u904b\u55b6\u3067\u4f7f\u7528\u3059\u308b\u30a6\u30a9\u30ec\u30c3\u30c8\u306e\u79d8\u5bc6\u9375\u3084\u30d7\u30fc\u30eb\u904b\u55b6\u306e\u79d8\u5bc6\u9375\u3092\u30aa\u30d5\u30e9\u30a4\u30f3\u4e0a\u3067\u7ba1\u7406\u3057\u3001\u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u3067CLI\u3092\u8d77\u52d5\u3057\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u306b\u7f72\u540d\u3059\u308b\u4f5c\u696d\u306b\u4f7f\u7528\u3057\u307e\u3059\u3002

  • \u30a6\u30a9\u30ec\u30c3\u30c8\u306e\u79d8\u5bc6\u9375\u3084\u30d7\u30fc\u30eb\u904b\u55b6\u306e\u79d8\u5bc6\u9375\u3092\u30d7\u30fc\u30eb\u904b\u55b6\u306e\u30aa\u30f3\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u4e0a\u306b\u4fdd\u7ba1\u3059\u308b\u3068\u3001\u30cf\u30c3\u30ad\u30f3\u30b0\u306a\u3069\u306e\u969b\u306b\u8cc7\u91d1\u76d7\u96e3\u306e\u30ea\u30b9\u30af\u304c\u3042\u308a\u307e\u3059\u3002
"},{"location":"setup/air-gap-guid/#windows","title":"Windows\u306e\u5834\u5408","text":"

\u8ca2\u732e\u8005

[SA8] SMAN8 \u3055\u3093\u306b\u5c0e\u5165\u624b\u9806\u3092\u4f5c\u6210\u9802\u304d\u307e\u3057\u305f\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\uff01

"},{"location":"setup/air-gap-guid/#_2","title":"\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u8981\u4ef6","text":"

\u74b0\u5883

  • Windows11 Home
  • \u5b9f\u88c5RAM 8.00 GB

\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9/\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb

  • Ubuntu Desktop 20.04.x LTS
  • VirtualBox-7.0.4
"},{"location":"setup/air-gap-guid/#1-os-ubuntu","title":"1- OS Ubuntu\u306e\u5165\u624b","text":"

1-1.\u4e0b\u306e\u753b\u50cf\u306e\u8d64\u3044\u56db\u89d2\u306e\u3068\u3053\u308d\u3092\u30bf\u30c3\u30d7\u3057\u3066\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002

  • Ubuntu20.04.4 LTS\u306e\u5165\u624b

1-2.\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fubuntu-20.04.4-desktop-amd64\u3092\u4f5c\u6210\u3057\u305f\u30d5\u30a9\u30eb\u30c0(\u3053\u3053\u3067\u306fTest_CNode\u3068\u3044\u3046\u30d5\u30a9\u30eb\u30c0)\u306b\u79fb\u52d5\u3057\u3066\u304a\u304f\u3002

"},{"location":"setup/air-gap-guid/#2-virtualbox","title":"2- VirtualBox\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9","text":"

2-1. VirtualBox\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30b5\u30a4\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001Windows hosts\u3092\u30bf\u30c3\u30d7\u3057\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u3002

  • VirtualBox\u306e\u5165\u624b
"},{"location":"setup/air-gap-guid/#3-virtualbox","title":"3- VirtualBox\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

3-1.\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fvirtualbox6.1.36\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30e9\u3092\u30c0\u30d6\u30eb\u30af\u30ea\u30c3\u30af\u3067\u8d77\u52d5\u3059\u308b\u3002

\u30d5\u30a1\u30a4\u30eb\u540d VirtualBox-7.0.4-154605-Win.exe

3-2.\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001\u5de6\u4e0b\u306e\u8d64\u3044\u56db\u89d2\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30e9\u30fc\u3092\u30bf\u30c3\u30d7\u3057\u3066\u8d77\u52d5\u3059\u308b\u3002

3-3.\u3053\u306e\u753b\u9762\u306b\u306a\u3063\u305f\u3089\u3001Next>\u3092\u30bf\u30c3\u30d7\u3002

3-4.\u7d9a\u3051\u3066\u305d\u306e\u307e\u307eNext>\u3092\u30bf\u30c3\u30d7\u3057\u3001\u753b\u50cf\u306e\u9806\u756a\u306b\u9032\u307f\u6700\u5f8c\u306bInstall\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3002

3-5.Windows\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u304c\u4f5c\u52d5\u3057\u3001\u30c7\u30d0\u30a4\u30b9\u306e\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u304b\uff1f\u3068\u805e\u304b\u308c\u305f\u3089\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb(I)\u3092\u30bf\u30c3\u30d7\u3057\u3001\u4e0b\u306e\u753b\u50cf\u306e\u8d64\u3044\u56db\u89d2\u3067\u56f2\u307e\u308c\u305fFinish\u3092\u30bf\u30c3\u30d7\u3059\u308b\u3002

3-6.VirtualBox\u306e\u7ba1\u7406\u753b\u9762\u304c\u7acb\u3061\u4e0a\u304c\u308a\u3001\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002

"},{"location":"setup/air-gap-guid/#4-virtualbox","title":"4- VirtualBox\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u4f5c\u6210","text":"

4-1.\u30de\u30b7\u30f3\u3092\u4f5c\u6210\u3059\u308b\u70ba\u306b\u4e0b\u306e\u753b\u50cf\u306e\u8d64\u3044\u56db\u89d2\u306e\u65b0\u898f(N)\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3002

4-2.\u30de\u30b7\u30f3\u8a2d\u5b9a \u540d\u524d\u30fb\u30fb\u30fb\u4efb\u610f\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u540d ISO Imagae\u30fb\u30fb\u30fb1\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fUbuntu-ISO\u30d5\u30a1\u30a4\u30eb\u3092\u6307\u5b9a\u3059\u308b \u300cSkip Unattended Installation\u300d\u306b\u30c1\u30a7\u30c3\u30af\u3057\u3066\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3002

4-3.\u30e1\u30a4\u30f3\u30e1\u30e2\u30ea\u30924096MB\u3001Processoros\u30922\u306b\u8a2d\u5b9a\u3057\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af

4-4.DiskSize\u309250.00GB\u306b\u8a2d\u5b9a\u3057\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af

4-5.\u30d0\u30fc\u30c1\u30e3\u30eb\u30de\u30b7\u30f3\u4f5c\u6210\u6982\u8981\u306e\u78ba\u8a8d\u3002\u300c\u5b8c\u4e86\u300d\u3092\u30af\u30ea\u30c3\u30af

"},{"location":"setup/air-gap-guid/#5-virtualbox","title":"5- VirtualBox\u306e\u4eee\u60f3\u30de\u30b7\u30f3\u306e\u74b0\u5883\u8a2d\u5b9a","text":"

5-1.\u4f7f\u7528\u3059\u308b\u4eee\u60f3\u30de\u30b7\u30f3(\u3053\u3053\u3067\u306fAirGap)\u3092\u9078\u629e\u3057\u3001\u300c\u8a2d\u5b9a\u300d\u30a2\u30a4\u30b3\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b

\u4e00\u822c 5-2.\u300c\u4e00\u822c\u300d\u2192\u300c\u9ad8\u5ea6\u300d\u30bf\u30d6\u304b\u3089\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306e\u5171\u6709\u3068\u30c9\u30e9\u30c3\u30b0&\u30c9\u30ed\u30c3\u30d7\u3092\u300c\u53cc\u65b9\u5411\u300d\u306b\u5909\u66f4\u3057\u3066OK\u3092\u30af\u30ea\u30c3\u30af

\u30b7\u30b9\u30c6\u30e0 5-3.\u300c\u30b7\u30b9\u30c6\u30e0\u300d\u2192\u300c\u30de\u30b6\u30fc\u30dc\u30fc\u30c9\u300d\u30bf\u30d6\u306e\u300c\u30d5\u30ed\u30c3\u30d4\u30fc\u300d\u306e\u30c1\u30a7\u30c3\u30af\u3092\u5916\u3059\u3002\u30c1\u30c3\u30d7\u30bb\u30c3\u30c8\u3092ICH9\u306b\u5909\u66f4\u3057\u3066OK\u3092\u30af\u30ea\u30c3\u30af

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u8a2d\u5b9a

5-4.Windows\u3068Ubuntu\u9593\u306e\u5171\u6709\u30d5\u30a9\u30eb\u30c0(Share)\u3092\u4f5c\u6210\u3059\u308b(\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d5\u30a9\u30eb\u30c0\u306a\u3069\u306e\u4efb\u610f\u306e\u5834\u6240)

5-5.\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u30fc\u304b\u3089\u65b0\u898f\u8ffd\u52a0\u30a2\u30a4\u30b3\u30f3\u3092\u30af\u30ea\u30c3\u30af

  • \u300c\u30d5\u30a9\u30eb\u30c0\u30fc\u306e\u30d1\u30b9\u300d\u306b5-4\u3067\u4f5c\u6210\u3057\u305f\u30d5\u30a9\u30eb\u30c0\u3092\u6307\u5b9a\u3059\u308b
  • \u30de\u30a6\u30f3\u30c8\u30dd\u30a4\u30f3\u30c8\u306b/media/share_win\u3092\u5165\u529b\u3059\u308b
  • \u300c\u81ea\u52d5\u30de\u30a6\u30f3\u30c8\u300d\u306b\u30c1\u30a7\u30c3\u30af\u3059\u308b

"},{"location":"setup/air-gap-guid/#6-ubuntu","title":"6- Ubuntu\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

6-1.\u8d77\u52d5\u3092\u30af\u30ea\u30c3\u30af\u3002

6-2.\u4e0b\u306e\u753b\u50cf\u306e\u3088\u3046\u306b\u30c7\u30a3\u30b9\u30af\u304c\u8d77\u52d5\u3057\u59cb\u3081\u307e\u3059\u3002

6-3.\u5de6\u306e\u67a0\u306e\u4e2d\u304b\u3089\u65e5\u672c\u8a9e\u3092\u9078\u629e\u3057Ubuntu\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

6-5.\u65e5\u672c\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u65b9\u306f\u3001\u4e21\u65b9\u3068\u3082\u300cJapanese\u300d\u3092\u9078\u629e\u3057\u3001\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

US\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u65b9\u306f\u300c\u30ad\u30fc\u30dc\u30fc\u30c9\u30ec\u30a4\u30a2\u30a6\u30c8\u300d\u2192\u300c\u30ad\u30fc\u30dc\u30fc\u30c9\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u691c\u51fa\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u203b \u753b\u9762\u304c\u898b\u5207\u308c\u3066\u3044\u308b\u5834\u5408\u306e\u5bfe\u51e6\u6cd5\uff1aAlt\uff0bF7\u3092\u62bc\u3059\u3068\u30de\u30a6\u30b9\u3067\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u79fb\u52d5\u3067\u304d\u307e\u3059)

6-6.\u4e0b\u306e\u753b\u50cf\u306e\u72b6\u614b\u306e\u307e\u307e\u3001\u7d9a\u3051\u308b\u3092\u30af\u30ea\u30c3\u30af

6-7.\u4e0b\u306e\u753b\u50cf\u306e\u72b6\u614b\u306e\u307e\u307e\u3001\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3002

6-8.\u7d9a\u3051\u308b\u3092\u30af\u30ea\u30c3\u30af\u3002

6-9.\u304a\u4f4f\u307e\u3044\u306e\u5730\u57df\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u7d9a\u3051\u308b\u3092\u30af\u30ea\u30c3\u30af\u3002

6-10.\u3042\u306a\u305f\u306e\u540d\u524d\u306f\u30de\u30b7\u30f3\u540d\u3092\u5165\u308c\u308b\u3068\u3001\u305d\u306e\u4e0b\u306e\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u306e\u540d\u524d\u3001\u30e6\u30fc\u30b6\u30fc\u540d\u306e\u5165\u529b\u306b\u3082\u81ea\u52d5\u3067\u5165\u529b\u3055\u308c\u307e\u3059\u3002\u305d\u3057\u3066\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u3054\u81ea\u8eab\u3067\u6c7a\u3081\u3066\u5165\u529b\u3092\u6e08\u307e\u305b\u3066\u4e0b\u3055\u3044\u3002\u7d42\u308f\u308a\u307e\u3057\u305f\u3089\u3001\u7d9a\u3051\u308b\u3092\u30bf\u30c3\u30d7\u3002

6-11.Ubuntu\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304c\u59cb\u307e\u308a\u307e\u3057\u305f\u3002\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002

6-12.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5b8c\u4e86\u5f8c\u3001\u518d\u8d77\u52d5\u3092\u884c\u3063\u3066\u4e0b\u3055\u3044

6-13.\u30ed\u30b0\u30a4\u30f3\u3057\u307e\u3059

6-14.\u30aa\u30f3\u30e9\u30a4\u30f3\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u63a5\u7d9a\u306f\u3001\u53f3\u4e0a\u306e\u30b9\u30ad\u30c3\u30d7(S)\u3092\u30af\u30ea\u30c3\u30af\u3002

6-15.\u6b21\u3078\u3092\u30bf\u30c3\u30d7\u3057\u307e\u3059\u3002

6-16.\u305d\u306e\u307e\u307e\u3001\u6b21\u3078\uff08N)\u3092\u30bf\u30c3\u30d7\u3002

6-17.\u3044\u3044\u3048\u3001\u9001\u4fe1\u3057\u307e\u305b\u3093\u3092\u9078\u629e\u3057\u3001\u53f3\u4e0a\u306e\u6b21\u3078(N)\u3092\u30bf\u30c3\u30d7\u3057\u307e\u3059\u3002

6-18.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304c\u7d42\u308f\u308a\u307e\u3057\u305f\u3002\u5b8c\u4e86\u3092\u30af\u30ea\u30c3\u30af\u3002

6-19.\u65b0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u300c\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u306a\u3044\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059

6-20.OK\u3092\u30af\u30ea\u30c3\u30af\u3002

6-21.\u3053\u306e\u64cd\u4f5c\u3092\u4eca\u3059\u3050\u5b9f\u884c\u3092\u30af\u30ea\u30c3\u30af\u3002

6-22.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3002

6-23.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3002

6-23.\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5b8c\u4e86\u5f8c\u5168\u4f53\u306b\u9069\u7528\u3059\u308b\u3092\u30af\u30ea\u30c3\u30af\u3057\u9589\u3058\u308b

"},{"location":"setup/air-gap-guid/#7-guest-additions","title":"7- Guest Additions\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

\u30a2\u30d7\u30ea\u4e00\u89a7\u304b\u3089\u30bf\u30fc\u30df\u30ca\u30eb(\u7aef\u672b)\u3092\u8d77\u52d5\u3057\u4ee5\u4e0b\u30b3\u30de\u30f3\u30c9\u3092\u624b\u52d5\u5165\u529b\u3059\u308b\u3002

sudo apt update -y\nsudo apt upgrade -y\nsudo apt install gcc make perl -y\n

\u307e\u3060\u30b3\u30d4\u30fc\u30a2\u30f3\u30c9\u30da\u30fc\u30b9\u30c8\u304c\u5229\u7528\u3067\u304d\u306a\u3044\u305f\u3081\u3001\u30bf\u30a4\u30d7\u30df\u30b9\u306b\u7559\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002

7-1.\u30db\u30b9\u30c8\u30e1\u30a4\u30f3\u753b\u9762\u4e0a\u90e8\u306e\u300cDevices\u300d\u30bf\u30d6\u304b\u3089\u300cInsert Guest Additions CD image...\u300d\u21d2OK\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

7-2.\u4ee5\u4e0b\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u305f\u3089\u5b9f\u884c\u3092\u30af\u30ea\u30c3\u30af\u3057\u305f\u5f8c\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u307e\u3059\u3002

7-3\u51e6\u7406\u5b8c\u4e86\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u307e\u3057\u305f\u3089Enter\u30ad\u30fc\u3092\u30bf\u30c3\u30d7\u3057\u307e\u3059\u3002

7-4.\u30bf\u30fc\u30df\u30ca\u30eb(\u7aef\u672b)\u3092\u8d77\u52d5\u3057\u30e6\u30fc\u30b6\u30fc\u3092\u30b0\u30eb\u30fc\u30d7\u5316\u3059\u308b\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3002

sudo adduser $USER vboxsf\n

7-5.\u30d5\u30a9\u30eb\u30c0\u306bshere_win\u304c\u8868\u793a\u3055\u308c\u3066\u3044\u308c\u3070\u30015\u306e\u300c\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u300d\u3067\u8a2d\u5b9a\u3057\u305f\u30ed\u30fc\u30ab\u30ebPC\u306e\u30d5\u30a9\u30eb\u30c0\u3068\u540c\u671f\u3057\u307e\u3059\u3002

7-6.\u30b3\u30d4\u30fc\uff06\u30da\u30fc\u30b9\u30c8\u3067\u304d\u308b\u304b\u30db\u30b9\u30c8PC\u3067\u30b3\u30de\u30f3\u30c9\u3092\u30b3\u30d4\u30fc\u3057\u3066\u30b2\u30b9\u30c8OS\u306e\u7aef\u672b\u3067\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066\u8cbc\u308a\u4ed8\u3051\u3057\u3066\u307f\u308b\u3002\u554f\u984c\u306a\u3051\u308c\u3070\u3001\u3053\u308c\u3067\u7d42\u4e86\u3067\u3059\u3002\u304a\u75b2\u308c\u69d8\u3067\u3057\u305f\uff01

7-7.\u300c\u8868\u793a\u300d\u2192\u300cAuto-resize\u3000Guest\u3000Display\u300d\u306b\u30c1\u30a7\u30c3\u30af\u304c\u5165\u3063\u3066\u3044\u308b\u4e8b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u4e0a\u8a18\u624b\u9806\u3092\u884c\u306a\u3063\u3066\u3082\u3001\u300c\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u304c\u8868\u793a\u3055\u308c\u306a\u3044\u300d\u300c\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u300d\u5834\u5408\u306f\u3001\u4e00\u5ea6VBox_GAs_6.1.36\u3092\u30a2\u30f3\u30de\u30a6\u30f3\u30c8\u3057\u3066\u304b\u3089\u518d\u5ea6\u633f\u5165\u3057\u3001\u518d\u8d77\u52d5\u3059\u308b\u3068\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u306f\u5b8c\u4e86\u3057\u307e\u3059\u3002\u305d\u308c\u3067\u3082\u30c0\u30e1\u306a\u3089GUI\u64cd\u4f5c\u3067Guest Additions\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u306a\u304b\u3063\u305f\u5834\u5408\u3092\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002

"},{"location":"setup/air-gap-guid/#8-swap","title":"8- Swap\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210","text":"

8-1. \u65e2\u5b58Swap\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664

sudo swapoff /swapfile\n
sudo rm /swapfile\n

8-2. \u65b0\u898fSwap\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210

cd $HOME\nsudo fallocate -l 6G /swapfile\n
sudo chmod 600 /swapfile\n
sudo mkswap /swapfile\nsudo swapon /swapfile\nsudo swapon --show\n
sudo cp /etc/fstab /etc/fstab.bak\necho '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab\necho 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf\necho 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf\ncat /proc/sys/vm/vfs_cache_pressure\ncat /proc/sys/vm/swappiness\n

"},{"location":"setup/air-gap-guid/#mac","title":"Mac\u306e\u5834\u5408","text":"

\u8ca2\u732e\u8005

[AKYO] AKYO Akyo\u3055\u3093\u306b\u5c0e\u5165\u624b\u9806\u3092\u4f5c\u6210\u9802\u304d\u307e\u3057\u305f\u3002\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\uff01

"},{"location":"setup/air-gap-guid/#_3","title":"\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u8981\u4ef6","text":"

\u74b0\u5883 - macOS Ventura version13.0

\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9/\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb - VirtualBox \u30d0\u30fc\u30b8\u30e7\u30f3 7.0.4 - Ubuntu Desktop 20.04.5 LTS (Focal Fossa)

"},{"location":"setup/air-gap-guid/#1-ubuntu","title":"1- Ubuntu\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9","text":"

1-1. \u4ee5\u4e0b\u306e\u30ea\u30f3\u30af\u5148\u304b\u3089ISO\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002

  • Ubuntu\u3092\u5165\u624b\u3059\u308b \u203b \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5b8c\u4e86\u307e\u3067\u5c11\u3057\u304b\u304b\u308b\u306e\u3067\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044
\u30d5\u30a1\u30a4\u30eb\u540d ubuntu-20.04.5-desktop-amd64.iso

"},{"location":"setup/air-gap-guid/#2-virtualbox_1","title":"2- VirtualBox\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9/\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

2-1. \u4ee5\u4e0b\u306e\u30ea\u30f3\u30af\u5148\u304b\u3089VirtualBox\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002

  • VirtualBox\u3092\u5165\u624b\u3059\u308b
\u30d5\u30a1\u30a4\u30eb\u540d VirtualBox-7.0.4-154605-OSX.dmg

2-2. \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30a6\u30a3\u30b6\u30fc\u30c9\u306b\u5f93\u3063\u3066\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002 \u5b8c\u4e86\u3057\u305f\u3089\u300c\u9589\u3058\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u7d42\u4e86\u3057\u307e\u3059\u3002

macOS BigSur \u4ee5\u964d\u3067\u306f\u3001\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u305f\u30ab\u30fc\u30cd\u30eb\u62e1\u5f35\u3092\u30ed\u30fc\u30c9\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u306b\u518d\u8d77\u52d5\u304c\u5fc5\u8981\u3067\u3059\u3002

"},{"location":"setup/air-gap-guid/#3-virtualbox_1","title":"3- VirtualBox\u3067\u4eee\u60f3\u30de\u30b7\u30f3\u3092\u4f5c\u6210","text":"

VirtualBox\u306e\u30a2\u30a4\u30b3\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u8d77\u52d5\u3057\u307e\u3059\u3002

3-1. VirtualBox\u304c\u8d77\u52d5\u3057\u305f\u3089\u300c\u65b0\u898f\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

3-2. \u4ee5\u4e0b\u306e\u9805\u76ee\u3092\u8a2d\u5b9a\u3057\u3001\u300c\u7d9a\u304d\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\u203b \u540d\u524d\u306f\u304a\u597d\u307f\u3067\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002 ISO Image\u306f\u3001\u300c\u305d\u306e\u4ed6\u300d\u3092\u9078\u629e\u3057\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305fUbuntu-20.04.5\u306eISO\u30a4\u30e1\u30fc\u30b8\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3057\u307e\u3059\u3002 \u30bf\u30a4\u30d7\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u3064\u3044\u3066\u306f\u4e0a\u8a18\u3092\u9078\u629e\u3059\u308c\u3070\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u8a2d\u5b9a\u3055\u308c\u307e\u3059\u3002 Skip Unattended Installation\u306b\u30c1\u30a7\u30c3\u30af

\u540d\u524d airGap Folder \u30c7\u30d5\u30a9\u30eb\u30c8\u3067OK

3-3. \u4eee\u60f3\u30de\u30b7\u30f3\u306b\u5272\u5f53\u3066\u308b\u30e1\u30e2\u30ea\u30b5\u30a4\u30ba\u306f\u300c4096MB\u300d\u3001Processors\u306f\u300c2\u300d\u3092\u9078\u629e\u3057\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

3-4. Virtual Hard disk\u306f\u300c50GB\u300d\u3092\u5165\u529b\u3057\u3001\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

3-5. \u6982\u8981\u3092\u78ba\u8a8d\u3057\u3066\u300c\u5b8c\u4e86\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

"},{"location":"setup/air-gap-guid/#4-","title":"4- \u4eee\u60f3\u30de\u30b7\u30f3\u306e\u4ed5\u69d8\u8a2d\u5b9a","text":"

\u300c\u5b8c\u4e86\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u305f\u3089\u300cOracle VM VirtualBox \u30de\u30cd\u30fc\u30b8\u30e3\u30fc\u300d\u753b\u9762\u306b\u9077\u79fb\u3059\u308b\u306e\u3067\u8a2d\u5b9a\u6bce\u306b\u300c\u8a2d\u5b9a\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002

\u4e00\u822c

4-1. \u300c\u8a2d\u5b9a\u300d\u2192\u300c\u4e00\u822c\u300d\u2192\u300c\u9ad8\u5ea6\u300d\u30bf\u30d6\u304b\u3089\u3001\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u3092\u300c\u53cc\u65b9\u5411\u300d\u306b\u3057\u3001\u300cOK\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\u30b7\u30b9\u30c6\u30e0

4-2. \u300c\u30de\u30b6\u30fc\u30dc\u30fc\u30c9\u300d\u30bf\u30d6\u3092\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u306b\u3057\u3001\u300cOK\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\u30de\u30b6\u30fc\u30dc\u30fc\u30c9 \u8d77\u52d5\u9806\u5e8f \u300c\u30d5\u30ed\u30c3\u30d4\u30fc\u300d\u306e\u30c1\u30a7\u30c3\u30af\u30de\u30fc\u30af\u3092\u5916\u3059 \u30c1\u30c3\u30d7\u30bb\u30c3\u30c8 ICH9 \u30dd\u30a4\u30f3\u30c6\u30a3\u30f3\u30b0\u30c7\u30d0\u30a4\u30b9 PS/2\u30de\u30a6\u30b9

\u30c7\u30a3\u30b9\u30d7\u30ec\u30a4

4-3. \u300c\u30b9\u30af\u30ea\u30fc\u30f3\u300d\u30bf\u30d6\u304b\u3089\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u306b\u3057\u3001\u300cOK\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\u30d3\u30c7\u30aa\u30e1\u30e2\u30ea\u30fc 128MB \u8868\u793a\u500d\u7387 200% \u30b0\u30e9\u30d5\u30a3\u30c3\u30af\u30b9\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc VMSVGA

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u30fc

4-4. \u30db\u30b9\u30c8\u5074\u3067\u5171\u6709\u3055\u305b\u305f\u3044\u30d5\u30a9\u30eb\u30c0\u3092\u4e8b\u524d\u306b\u4f5c\u6210\u3057\u3066\u304a\u304d\u307e\u3059\u3002 - \u4f8b\uff09\u300cairGap\u300d\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u5f8c\u3001\u914d\u4e0b\u306b\u300cshare\u300d\u30d5\u30a9\u30eb\u30c0\u3092\u4f5c\u6210\u3002

Mac Terminal

mkdir -p $HOME/airGap/share\n

4-5. \u5171\u6709\u30d5\u30a9\u30eb\u30c0\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002

"},{"location":"setup/air-gap-guid/#5-ubuntu","title":"5- \u4eee\u60f3\u30de\u30b7\u30f3\u306bUbuntu\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

5-1. \u4eee\u60f3\u30de\u30b7\u30f3\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002

PC\u304b\u3089\u6a29\u9650\u8a31\u53ef\u3092\u6c42\u3081\u3089\u308c\u305f\u3089\u300c\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3068\u30d7\u30e9\u30a4\u30d0\u30b7\u30fc\u300d\u306b\u3066\u5fc5\u8981\u306a\u6a29\u9650\u3092\u8a31\u53ef\u3057\u3001VirtualBox\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

5-2. \u8aad\u307f\u8fbc\u307f\u7d42\u4e86\u5f8c\u3001\u8a00\u8a9e\u306f\u300c\u65e5\u672c\u8a9e\u300d\u306b\u3057\u3001\u300cInstall Ubuntu\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-3. \u30ad\u30fc\u30dc\u30fc\u30c9\u8a2d\u5b9a\u3067\u306f\u3001\u65e5\u672c\u8a9e\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u65b9\u306f\u3001\u4e21\u65b9\u3068\u3082\u300cJapanese\u300d\u3092\u9078\u629e\u3057\u3001\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

US\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u65b9\u306f\u300c\u30ad\u30fc\u30dc\u30fc\u30c9\u30ec\u30a4\u30a2\u30a6\u30c8\u300d\u2192\u300c\u30ad\u30fc\u30dc\u30fc\u30c9\u30ec\u30a4\u30a2\u30a6\u30c8\u306e\u691c\u51fa\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u203b \u753b\u9762\u304c\u898b\u5207\u308c\u3066\u3044\u305f\u5834\u5408\u306e\u5bfe\u51e6\u6cd5\uff1aAlt\uff0bF7\u3067\u79fb\u52d5\u3067\u304d\u307e\u3059)

5-4. \u300c\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3068\u4ed6\u306e\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u3001\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-5. \u300c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306e\u7a2e\u985e\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u300c\u30c7\u30a3\u30b9\u30af\u3092\u524a\u9664\u3057\u3066Ubuntu\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u300d\u3092\u9078\u629e\u3057\u3001\u300c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-6. \u300c\u30c7\u30a3\u30b9\u30af\u306b\u5909\u66f4\u3092\u66f8\u304d\u8fbc\u307f\u307e\u3059\u304b?\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-7. \u30bf\u30a4\u30e0\u30be\u30fc\u30f3\u306e\u8a2d\u5b9a\u306f\u3001\u300cTokyo\u300d\u3092\u9078\u629e\u3057\u3001\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-8. \u5fc5\u8981\u306a\u60c5\u5831\u3092\u5165\u529b\u3057\u3001\u300c\u7d9a\u3051\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

\u203b \u753b\u50cf\u306f\u4e00\u4f8b\u3067\u3059\u306e\u3067\u304a\u597d\u307f\u3067\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

5-9. \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u958b\u59cb\u3002

5-10. \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u5b8c\u4e86\u5f8c\u3001VM\u306e\u518d\u8d77\u52d5\u3092\u6c42\u3081\u3089\u308c\u308b\u306e\u3067\u300c\u4eca\u3059\u3050\u518d\u8d77\u52d5\u3059\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001Enter\u30ad\u30fc\u3092\u62bc\u4e0b\u3057\u307e\u3059\u3002

5-11. \u518d\u8d77\u52d5\u5f8c\u3001\u30e6\u30fc\u30b6\u30fc\u540d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u30ed\u30b0\u30a4\u30f3\u3057\u307e\u3059\u3002

5-12. \u300c\u30aa\u30f3\u30e9\u30a4\u30f3\u30a2\u30ab\u30a6\u30f3\u30c8\u3078\u306e\u63a5\u7d9a\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u53f3\u4e0a\u306e\u300c\u30b9\u30ad\u30c3\u30d7\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-13. \u300cLivepatch\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u53f3\u4e0a\u306e\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-14. \u300cUbuntu\u306e\u6539\u5584\u3092\u652f\u63f4\u3059\u308b\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u3001\u300c\u3044\u3044\u3048\u3001\u9001\u4fe1\u3057\u307e\u305b\u3093\u300d\u3092\u9078\u629e\u5f8c\u3001\u53f3\u4e0a\u306e\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-15. \u300c\u30d7\u30e9\u30a4\u30d0\u30b7\u30fc\u300d\u306e\u8a2d\u5b9a\u3067\u306f\u53f3\u4e0a\u306e\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-16. \u300c\u6e96\u5099\u5b8c\u4e86\u300d\u3068\u8868\u793a\u3055\u308c\u305f\u3089\u53f3\u4e0a\u306e\u300c\u5b8c\u4e86\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-17. \u300c\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u66f4\u65b0\u300d\u3092\u6c42\u3081\u3089\u308c\u305f\u3089\u300c\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\u3057\u306a\u3044\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u305d\u306e\u5f8c\u300cOK\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

5-18. \u300c\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u60c5\u5831\u2192\u4e0d\u5b8c\u5168\u306a\u8a00\u8a9e\u30b5\u30dd\u30fc\u30c8\u300d\u304c\u8868\u793a\u3055\u308c\u305f\u3089\u300c\u3053\u306e\u64cd\u4f5c\u3092\u4eca\u3059\u3050\u5b9f\u884c\u3059\u308b\u300d\u2192\u300c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u300d\u3092\u30af\u30ea\u30c3\u30af\u5f8c\u3001\u8a8d\u8a3c\u3092\u6c42\u3081\u3089\u308c\u308b\u306e\u3067\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3001\u300c\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306b\u9069\u7528\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

"},{"location":"setup/air-gap-guid/#6-guest-additions","title":"6- Guest Additions\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb","text":"

6-1. \u30bf\u30fc\u30df\u30ca\u30eb\u3092\u958b\u3044\u3066\u4ee5\u4e0b\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

Guest Additions\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u306a\u3044\u72b6\u614b\u306a\u306e\u3067\u30db\u30b9\u30c8\u304b\u3089\u30b2\u30b9\u30c8\u306b\u30b3\u30d4\u30fc\u30a2\u30f3\u30c9\u30da\u30fc\u30b9\u30c8\u3067\u304d\u307e\u305b\u3093\u3002\u30bf\u30a4\u30d7\u30df\u30b9\u306b\u7559\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u307e\u305f\u4ee5\u4e0b\u306e\u624b\u9806\u3092\u884c\u306a\u3063\u3066\u3082\u3001\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u304cGUI\u3067\u8868\u793a\u3055\u308c\u306a\u3044\u3001\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u5316\u3055\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u3001\u4e00\u5ea6VBox_GAs_6.1.36\u3092\u30a2\u30f3\u30de\u30a6\u30f3\u30c8\u3057\u3066\u304b\u3089\u518d\u5ea6\u633f\u5165\u3057\u3001\u518d\u8d77\u52d5\u3059\u308b\u3068\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u306f\u5b8c\u4e86\u3057\u307e\u3059\u3002 \u305d\u308c\u3067\u3082\u30c0\u30e1\u306a\u3089GUI\u64cd\u4f5c\u3067Guest Additions\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u306a\u304b\u3063\u305f\u5834\u5408\u3092\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002

sudo apt update -y\nsudo apt upgrade -y\nsudo apt install gcc make perl -y\n

6-2. \u30db\u30b9\u30c8\u30e1\u30a4\u30f3\u753b\u9762\u4e0a\u90e8\u306e\u300cDevices\u300d\u30bf\u30d6\u304b\u3089\u300cInsert Guest Additions CD image...\u300d\u2192\u300cOK\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

6-3. \u4ee5\u4e0b\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u305f\u3089\u300c\u5b9f\u884c\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u305f\u5f8c\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u307e\u3059\u3002

6-4. \u51e6\u7406\u5b8c\u4e86\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u305f\u3089Enter\u30ad\u30fc\u3092\u62bc\u4e0b\u3057\u307e\u3059\u3002

\u753b\u9762\u304c\u70b9\u6ec5\u3057\u305f\u5834\u5408\u306f\u3001\u30ea\u30b5\u30a4\u30ba\u304c\u884c\u308f\u308c\u3066\u3044\u308b\u306e\u3067\u305d\u306e\u307e\u307e\u5c11\u3057\u5f85\u3063\u3066\u3044\u308b\u3068\u70b9\u6ec5\u3057\u306a\u304f\u306a\u308b\u306f\u305a\u3067\u3059\u3002

6-5. \u30e6\u30fc\u30b6\u30fc\u3092vboxsf\u30b0\u30eb\u30fc\u30d7\u306b\u8ffd\u52a0\u3057\u3066\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo adduser $USER vboxsf\nsudo reboot\n

6-6. \u300cView\u300d\u2192\u300cAuto-resize\u3000Guest\u3000Display\u300d\u306b\u30c1\u30a7\u30c3\u30af\u304c\u5165\u3063\u3066\u3044\u308b\u4e8b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

\u78ba\u8a8d\u5f8c\u3001\u53f3\u30af\u30ea\u30c3\u30af\u2192\u300c\u53d6\u308a\u51fa\u3059\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002

6-7. \u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210 \u30bf\u30fc\u30df\u30ca\u30eb\u3092\u958b\u3044\u3066\u4ee5\u4e0b\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u306b\u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u3066\u30db\u30b9\u30c8\u5074\u3067\u78ba\u8a8d\u3067\u304d\u305f\u3089\u6210\u529f\u3067\u3059\u3002

touch /media/sf_share/test.txt\nls /media/sf_share/\n

\u5b9f\u884c\u7d50\u679c\u3068\u3057\u3066VM\u3068\u30db\u30b9\u30c8\u306btest.txt\u304c\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

"},{"location":"setup/air-gap-guid/#6-swap","title":"6- Swap\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210","text":"

6-1. \u65e2\u5b58Swap\u30d5\u30a1\u30a4\u30eb\u3092\u524a\u9664

sudo swapoff /swapfile\n
sudo rm /swapfile\n

6-2. \u65b0\u898fSwap\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210

cd $HOME\nsudo fallocate -l 6G /swapfile\n
sudo chmod 600 /swapfile\n
sudo mkswap /swapfile\nsudo swapon /swapfile\nsudo swapon --show\n
sudo cp /etc/fstab /etc/fstab.bak\necho '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab\necho 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf\necho 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf\ncat /proc/sys/vm/vfs_cache_pressure\ncat /proc/sys/vm/swappiness\n

"},{"location":"setup/air-gap-guid/#_4","title":"\u88dc\u8db3","text":""},{"location":"setup/air-gap-guid/#_5","title":"\u672c\u756a\u904b\u7528\u3067\u4f7f\u7528\u3059\u308b\u969b\u306e\u6ce8\u610f\u70b9","text":"
  • \u672c\u756a\u904b\u7528\u3067\u4f7f\u7528\u3055\u308c\u308b\u5834\u5408\u306f\u5fc5\u305a\u300c\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u6709\u52b9\u5316\u300d\u306e\u30c1\u30a7\u30c3\u30af\u3092\u5916\u3057\u3066\u304f\u3060\u3055\u3044\u3002 2-8. \u30a8\u30a2\u30ae\u30e3\u30c3\u30d7\u30aa\u30d5\u30e9\u30a4\u30f3\u30de\u30b7\u30f3\u306e\u4f5c\u6210\u3092\u7d42\u3048\u305f\u5f8c\u306b\u884c\u3063\u3066\u304f\u3060\u3055\u3044\u3002
"},{"location":"setup/air-gap-guid/#guiguest-additions","title":"GUI\u64cd\u4f5c\u3067Guest Additions\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3067\u304d\u306a\u304b\u3063\u305f\u5834\u5408","text":"

Virtualbox guest addition packages\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002

\u30bf\u30fc\u30df\u30ca\u30eb\u3092\u958b\u3044\u3066\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Guest Additions\u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u306a\u3044\u72b6\u614b\u306a\u306e\u3067\u30db\u30b9\u30c8\u304b\u3089\u30b2\u30b9\u30c8\u306b\u30b3\u30d4\u30fc\u30a2\u30f3\u30c9\u30da\u30fc\u30b9\u30c8\u3067\u304d\u307e\u305b\u3093\u3002\u30bf\u30a4\u30d7\u30df\u30b9\u306b\u7559\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u6210\u529f\u3057\u3066\u3044\u308c\u3070\u518d\u8d77\u52d5\u5f8c\u3001\u30b3\u30d4\u30fc\u30a2\u30f3\u30c9\u30da\u30fc\u30b9\u30c8\u3067\u304d\u307e\u3059\u3002

sudo apt update -y\nsudo apt upgrade -y\nsudo add-apt-repository multiverse\nsudo apt install virtualbox-guest-dkms virtualbox-guest-x11 -y\n

\u30e6\u30fc\u30b6\u30fc\u3092vboxsf\u30b0\u30eb\u30fc\u30d7\u306b\u8ffd\u52a0\u3057\u3066\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002

sudo adduser $USER vboxsf\nsudo reboot\n

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u308b\u304b\u78ba\u8a8d

df\n

share 488245288 203122832 285122456 42% /media/sf_share

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u306e\u30b0\u30eb\u30fc\u30d7\u3092\u78ba\u8a8d

ls -l /media\n

drwxrwx--- 1 root vboxsf 96 x\u6708 xx xx:xx sf_share

\u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u4f5c\u6210

\u5171\u6709\u30d5\u30a9\u30eb\u30c0\u306b\u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u3066\u30db\u30b9\u30c8\u5074\u3067\u78ba\u8a8d\u3067\u304d\u305f\u3089\u6210\u529f\u3067\u3059\u3002

touch /media/sf_share/test.txt\nls /media/sf_share/\n

\u5b9f\u884c\u7d50\u679c\u3068\u3057\u3066VM\u3068\u30db\u30b9\u30c8\u306btest.txt\u304c\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002

"}]} \ No newline at end of file diff --git a/setup/1-ubuntu-setup/index.html b/setup/1-ubuntu-setup/index.html new file mode 100644 index 00000000..4a40bdda --- /dev/null +++ b/setup/1-ubuntu-setup/index.html @@ -0,0 +1,3303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.Ubuntu初期設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

1.Ubuntu初期設定

+
+

AWSをご利用の方

+

AWS EC2及びlightsailは特殊環境なため、このマニュアル通りに動かない場合がございます。
+不明な点はGuildコミュニティで質問してみてください。

+
+
+

ヒント

+

この手順はエアギャップオフラインマシン(VirtualBox上のUbuntu)では実施する必要はありません

+
+

1-1.オススメのターミナルソフト

+

1.R-Login(Windows)
+https://kmiya-culti.github.io/RLogin/

+
+

接続状態維持のための設定

+

R-Login使用の際は、未操作時の接続状態を保持するため以下の設定を行ってください。 +

+
+

2.Terminal(Mac)
+https://www.webdesignleaves.com/pr/plugins/mac_terminal_basics_01.html

+

1-2.ユーザーアカウントの作成

+
+

ヒント

+

rootアカウントはサーバーの最上位権限です。 +サーバを操作する場合はrootアカウントを使用せず、root権限を付与したユーザーアカウントで操作するようにしましょう。

+
+

新しいユーザーの追加 (例:cardano)

+

1.上記ターミナルソフトを使用し、サーバーに割り当てられた初期アカウント(rootなど)でログインする。

+

2.新しいユーザーアカウントを作る(任意のアルファベット文字)

+
adduser cardano
+
+
New password:           # ユーザーのパスワードを設定
+Retype new password:    # 確認再入力
+
+Enter the new value, or press ENTER for the default
+        Full Name []:   # フルネーム等の情報を設定 (不要であればブランクでも OK)
+        Room Number []:
+        Work Phone []:
+        Home Phone []:
+        Other []:
+Is the information correct? [Y/n]:y
+
+

cardanoをsudoグループに追加する

+
usermod -G sudo cardano
+
+

rootユーザーからログアウトする

+
exit
+
+

3.ターミナルソフトのユーザーをパスワードを上記で作成したユーザーとパスワードに書き換えて再接続します。

+
+

Ubuntu22.04の場合の特別設定

+

ご利用のOSがUbuntu22.04の場合は、以下のコマンドを実行してください。

+

ブラケットペーストモードOFF +

echo "set enable-bracketed-paste off" >> ~/.inputrc
+

+

デーモン再起動自動化 +

echo "\$nrconf{restart} = 'a';" | sudo tee /etc/needrestart/conf.d/50local.conf
+
+
echo "\$nrconf{blacklist_rc} = [qr(^cardano-node\\.service$) => 0,];" | sudo tee -a /etc/needrestart/conf.d/50local.conf
+

+
+

1-3.SSH鍵認証方式へ切り替え

+
+

Summary

+

SSHを強化する基本的なルールは次の通りです。

+
    +
  • SSHログイン時パスワード無効化 (秘密鍵を使用)
  • +
  • SSHデフォルトポート(22)の変更
  • +
  • rootアカウントでのSSHログイン無効化 (root権限が必要なコマンドはsu or sudoコマンドを使う)
  • +
  • 許可されていないアカウントからのログイン試行をログに記録する (fail2banなどの、不正アクセスをブロックまたは禁止するソフトウェアの導入を検討する)
  • +
  • SSHログイン元のIPアドレス範囲のみに限定する (希望する場合のみ)※利用プロバイダーによっては、定期的にグローバルIPが変更されるので注意が必要
  • +
+
+

ペア鍵の作成

+
ssh-keygen -t ed25519 -N '' -C ssh_connect -f ~/.ssh/ssh_ed25519
+
+

cd ~/.ssh
+ls
+
+ssh_ed25519(秘密鍵)とssh_ed25519.pub(公開鍵)というファイルが作成されているか確認する。

+
cd ~/.ssh/
+cat ssh_ed25519.pub >> authorized_keys
+chmod 600 authorized_keys
+chmod 700 ~/.ssh
+
+

SSH鍵ファイルをダウンロードする

+

1.R-loginの場合はファイル転送ウィンドウを開く
+2.左側ウィンドウ(ローカル側)は任意の階層にフォルダを作成する。
+3.右側ウィンドウ(サーバ側)は「.ssh」フォルダを選択する
+4.右側ウィンドウから、ssh_ed25519とssh_ed25519.pubの上で右クリックして「ファイルのダウンロード」を選択する
+5.一旦サーバからログアウトする
+6.R-Loginのサーバ接続編集画面を開き、「SSH認証鍵」をクリックし4でダウンロードしたssh_ed25519ファイルを選ぶ
+7.サーバへ接続する

+

SSHの設定変更

+

/etc/ssh/sshd_configファイルを開く

+
sudo nano /etc/ssh/sshd_config
+
+

ResponseAuthenticationの項目を「no」にします。

+
+
+
+
ChallengeResponseAuthentication no
+
+
+
+
KbdInteractiveAuthentication no
+
+
+
+
+

PasswordAuthenticationの項目を「no」にする

+
PasswordAuthentication no 
+
+

PermitRootLoginの項目を「no」にする

+
PermitRootLogin no
+
+

PermitEmptyPasswordsの項目を「no」にする

+
PermitEmptyPasswords no
+
+
+

SSHポートのヒント

+

SSHポートは世界標準で22番が割り当てられています。
+しかし、ポートアタックの標的となり得るため任意の番号へ変更することをおすすめしています。任意の番号は49513~65535までの数字で設定してください。

+
+

SSHポートを任意の番号へ変更する。先頭の#を削除して番号を指定してください。 +

Port xxxxx
+

+
+

Ctrl+O で保存し、Ctrl+Xで閉じる

+
+

SSH構文にエラーがないかチェックします。

+
sudo sshd -t
+
+

SSH構文エラーがない場合、SSHプロセスを再起動します。

+
sudo service sshd reload
+
+

接続したまま、ターミナルソフトをもう一つ起動する。

+
+

ターミナルソフト設定について

+

接続設定のSSHポート番号を変更し秘密鍵を設定しサーバーへログインできるか確認して下さい。 +接続できない場合は、接続されてるターミナル画面でサーバー設定を確認して下さい。

+
+

1-4.ファイアウォール有効化

+

標準のUFWファイアウォールを使用して、インバウンドアクセスポートを限定します。

+
+設定前の注意事項 +

ご利用のVPSによっては管理画面からFWを設定する場合があります(例AWS系など)
+その場合は以下の設定を行わず、VPSマイページ管理画面などから個別に設定してください。

+
+
+さくらVPSをご利用の場合 +

管理画面からパケットフィルターを、”利用しない”に設定してください。

+
+

SSHポートを許可する

+
PORT=`grep "Port" /etc/ssh/sshd_config`
+s_PORT=${PORT#"Port"}
+ssh_PORT=`echo ${s_PORT} | sed -e 's/[^0-9]//g'`
+echo ${ssh_PORT}
+
+

sudo ufw allow ${ssh_PORT}/tcp
+
+FWを有効化 +
sudo ufw enable
+
+以下のメッセージが表示されたら y を入力して Enter

+
+

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y

+
+

ステータス確認 +

sudo ufw status
+
+以下の戻り値があればOK

+
+

Status: active

+
+

1-5.システムを更新する

+
+

重要

+

不正アクセスを予防するには、システムに最新のパッチを適用することが重要です。

+
+
sudo apt update -y && sudo apt upgrade -y
+sudo apt autoremove
+sudo apt autoclean
+
+

自動更新を有効にすると、手動でインストールする手間を省けます。

+
+

YESを選択しEnter

+
+
sudo apt install unattended-upgrades
+sudo dpkg-reconfigure --priority=low unattended-upgrades
+
+

1-6.rootアカウントを無効にする

+

サーバーのセキュリティを維持するために、頻繁にrootアカウントでログインしないでください。

+
+

通常はrootアカウント無効にします

+
sudo passwd -l root
+
+
+
+

# 何らかの理由でrootアカウントを有効にする必要がある場合は、-uオプションを使用します。

+
sudo passwd -u root
+
+
+

1-7.安全な共有メモリー

+

システムで共有されるメモリを保護します。

+

/etc/fstabを開きます

+
sudo nano /etc/fstab
+
+

次の行をファイルの最後に追記して保存します。

+
tmpfs   /run/shm    tmpfs   ro,noexec,nosuid    0 0
+
+

1-8.Fail2banのインストール

+
+

Fail2banは、ログファイルを監視し、ログイン試行に失敗した特定のパターンを監視する侵入防止システムです。特定のIPアドレスから(指定された時間内に)一定数のログイン失敗が検知された場合、Fail2banはそのIPアドレスからのアクセスをブロックします。

+
+
sudo apt install fail2ban -y
+
+

SSHログインを監視する設定ファイルを開きます。

+
sudo nano /etc/fail2ban/jail.local
+
+

ファイルの最後に次の行を追加し保存します。

+
+

コマンド中の (SSHポートを入力してください) については1-3で設定したSSHポートを入力してください。()は不要です。

+
+
[sshd]
+enabled = true
+port = (SSHポートを入力してください)
+filter = sshd
+logpath = /var/log/auth.log
+maxretry = 3
+
+

fail2banを再起動して設定を有効にします。

+
sudo systemctl restart fail2ban
+
+

1-9.Chronyを設定する

+

chronyをインストールします。

+
sudo apt install chrony
+
+

/etc/chrony/chrony.conf を更新します。

+
cat > $HOME/chrony.conf << EOF
+pool time.google.com       iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3
+pool time.facebook.com     iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3
+pool time.euro.apple.com   iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3
+pool time.apple.com        iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3
+pool ntp.ubuntu.com        iburst minpoll 2 maxpoll 2 maxsources 3 maxdelay 0.3
+
+# This directive specify the location of the file containing ID/key pairs for
+# NTP authentication.
+keyfile /etc/chrony/chrony.keys
+
+# This directive specify the file into which chronyd will store the rate
+# information.
+driftfile /var/lib/chrony/chrony.drift
+
+# Uncomment the following line to turn logging on.
+#log tracking measurements statistics
+
+# Log files location.
+logdir /var/log/chrony
+
+# Stop bad estimates upsetting machine clock.
+maxupdateskew 5.0
+
+# This directive enables kernel synchronisation (every 11 minutes) of the
+# real-time clock. Note that it can’t be used along with the 'rtcfile' directive.
+rtcsync
+
+# Step the system clock instead of slewing it if the adjustment is larger than
+# one second, but only in the first three clock updates.
+makestep 0.1 -1
+
+# Get TAI-UTC offset and leap seconds from the system tz database
+leapsectz right/UTC
+
+# Serve time even if not synchronized to a time source.
+local stratum 10
+EOF
+
+

作成したchrony.confを/etc/chrony/chrony.confに移動します。 +

sudo mv $HOME/chrony.conf /etc/chrony/chrony.conf
+

+

UFWで以下を設定します。 +

sudo ufw allow 123/udp
+

+

設定を有効にするには、Chronyを再起動します。

+
sudo systemctl reload-or-restart chronyd.service
+
+

ヘルプコマンド

+

同期データのソースを確認します。

+
chronyc sources
+
+

現在のステータスを表示します。

+
chronyc tracking
+
+

1-10.SSHの2段階認証を設定する

+
+

注意

+
    +
  • +

    こちらの導入は必須ではありません。導入する場合、事前にお手元のスマートフォンに「Google認証システムアプリ」のインストールが必要です

    +
  • +
  • +

    設定に失敗するとログインできなくなる場合があるので、設定前に二つ目のウィンドウでサーバーにログインしておいてください。万が一ログインできなくなった場合、復旧できます。

    +
  • +
+
+
sudo apt update
+sudo apt upgrade
+sudo apt install libpam-google-authenticator -y
+
+

SSHがGoogle Authenticator PAM モジュールを使用するために、/etc/pam.d/sshdファイルを編集します。

+
sudo nano /etc/pam.d/sshd 
+
+

4行目の @include common-authの先頭へ#を付与してコメントアウトする。 +

#@include common-auth
+

+

以下の行を追加します。

+
auth required pam_google_authenticator.so
+
+

以下を使用してsshdデーモンを再起動します。

+
sudo systemctl restart sshd.service
+
+

/etc/ssh/sshd_config ファイルを開きます。

+
sudo nano /etc/ssh/sshd_config
+
+

ResponseAuthenticationの項目を「yes」にします。

+
+
+
+
ChallengeResponseAuthentication yes
+
+
+
+
KbdInteractiveAuthentication yes
+
+
+
+
+

UsePAMの項目を「yes」にします。

+
UsePAM yes
+
+

最後の行に1行追加します。(SSH公開鍵秘密鍵ログインを利用の場合)

+
AuthenticationMethods publickey,keyboard-interactive
+
+

ファイルを保存して閉じます。

+

以下を使用してsshdデーモンを再起動します。

+
sudo systemctl restart sshd.service
+
+

google-authenticator コマンドを実行します。

+
google-authenticator
+
+

いくつか質問事項が表示されます。推奨項目は以下のとおりです。

+
Do you want authentication tokens to be time-based (y/n) : y
+
+
Do you want me to update your 
+"/home/cardano/.google_authenticator" file? (y/n): y
+
+
Do you want to disallow multiple uses of the same authentication
+token? This restricts you to one login about every 30s, but it increases
+your chances to notice or even prevent man-in-the-middle attacks (y/n): y
+
+

By default, a new token is generated every 30 seconds by the mobile app.
+In order to compensate for possible time-skew between the client and the server,
+we allow an extra token before and after the current time. This allows for a
+time skew of up to 30 seconds between authentication server and client. If you
+experience problems with poor time synchronization, you can increase the window
+from its default size of 3 permitted codes (one previous code, the current
+code, the next code) to 17 permitted codes (the 8 previous codes, the current
+code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
+between client and server.
+Do you want to do so? (y/n): n
+
+
If the computer that you are logging into isn't hardened against brute-force
+login attempts, you can enable rate-limiting for the authentication module.
+By default, this limits attackers to no more than 3 login attempts every 30s.
+Do you want to enable rate-limiting? (y/n) : y
+

+

プロセス中に大きなQRコードが表示されますが、その下には緊急時のスクラッチコードが表示されますので、忘れずに書き留めておいて下さい。

+

スマートフォンでGoogle認証システムアプリを開き、QRコードを読み取り2段階認証を機能させます。

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/10-blocklog-setup/index.html b/setup/10-blocklog-setup/index.html new file mode 100644 index 00000000..2a648246 --- /dev/null +++ b/setup/10-blocklog-setup/index.html @@ -0,0 +1,3741 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.ブロックログセットアップ - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

10.ステークプールブロックログ導入手順

+
+

ブロックログについて

+

このツールはPoSにおける自プールのブロック生成スケジュールを事前に取得するツールです。

+
+
+

制作クレジット

+

このツールは海外ギルドオペレーター制作のCNCLI By AndrewWestberglogmonitor by Guild OperatorsGuild LiveViewBLOCK LOG for CNToolsを組み合わせたツールとなっております。カスタマイズするにあたり、開発者のAHLNET(AHL)にご協力頂きました。ありがとうございます。

+
+

10-0. インストール要件

+
+

設定サーバー

+
    +
  • BPノード限定
  • +
+
+
+

稼働要件

+
    +
  • 4つのサービス(プログラム)をsystemd × tmuxにて常駐させます。
  • +
  • ブロックチェーン同期用DBを新しく設置します(sqlite3)
  • +
  • 日本語マニュアルのフォルダ構成に合わせて作成されています。
  • +
  • vrf.skey と vrf.vkeyが必要です。
  • +
+
+
+

構成図

+
    flowchart TB
+        a1[cardano-node] --> a2[logファイル]
+        a3 --> a5[leaderlog.service]
+        a3 --> a6[validate.service]
+        a1[cardano-node] --> a3[cncli.service]
+        a2 --> a4[logmonitor.service]
+        a3[cncli.service]
+        a4[logmonitor.service]
+        a5[leaderlog.service]
+        a6[validate.service]
+        subgraph Guild-DB
+            a7[cncli.db]
+            a8[blocklog.db]
+        end
+        subgraph ステータス通知
+            a9[blockcheck] --> 各アプリ
+        end
+        Guild-DB --> blocks.sh
+        a8[blocklog.db] --> a9[blockcheck]
+        a3[cncli.service] --> a7[cncli.db]
+        a5[leaderlog.service] --> a8[blocklog.db]
+        a6[validate.service] --> a8[blocklog.db]
+
+
+

10-1. CNCLIインストール

+
+

CNCLIについて

+

AndrewWestbergさんによって開発されたCNCLIはプールのブロック生成スケジュールを算出し、Shelley期におけるSPOに革命をもたらしました。

+
+

RUST環境を準備します

+
mkdir $HOME/.cargo && mkdir $HOME/.cargo/bin
+chown -R $USER $HOME/.cargo
+touch $HOME/.profile
+chown $USER $HOME/.profile
+
+

rustupをインストールします-デフォルトのインストールを続行します(オプション1) +

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+

+
+

1) Proceed with installation (default) 1を入力してEnter

+
+
source $HOME/.cargo/env
+rustup install stable
+rustup default stable
+rustup update
+rustup component add clippy rustfmt
+rustup target add x86_64-unknown-linux-musl
+
+

依存関係をインストールし、cncliをビルドします

+

source $HOME/.cargo/env
+sudo apt update -y && sudo apt install -y automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw5 libtool autoconf musl-tools
+
+
cd $HOME/git
+git clone --recurse-submodules https://github.com/cardano-community/cncli
+cd cncli
+git checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)
+cargo install --path . --force
+

+

CNCLIのバージョンを確認します。 +

cncli --version
+

+
+

6.0.1 が最新バージョンです

+
+

10-2. sqlite3インストール

+
sudo apt install sqlite3
+sqlite3 --version
+
+
+

3.31.1以上のバージョンがインストールされたらOKです。

+
+

10-3. 依存ファイルダウンロード

+

依存関係のあるプログラムをダウンロードします。

+
cd $NODE_HOME
+mkdir scripts
+cd $NODE_HOME/scripts
+wget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/cncli.sh -O ./cncli.sh
+wget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env -O ./env
+wget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh -O ./gLiveView.sh
+wget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/cntools.library -O ./cntools.library
+wget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/blocks.sh -O ./blocks.sh 
+wget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/logMonitor.sh -q -O ./logMonitor.sh
+
+

パーミッションを設定する +

chmod 755 cncli.sh
+chmod 755 logMonitor.sh
+chmod 755 gLiveView.sh
+chmod 755 blocks.sh
+

+

設定ファイルを修正する

+

envファイルを修正します

+

PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+
+
sed -i $NODE_HOME/scripts/env \
+  -e '1,73s!#CNODEBIN="${HOME}/.local/bin/cardano-node"!CNODEBIN="/usr/local/bin/cardano-node"!' \
+  -e '1,73s!#CCLI="${HOME}/.local/bin/cardano-cli"!CCLI="/usr/local/bin/cardano-cli"!' \
+  -e '1,73s!#CNCLI="${HOME}/.local/bin/cncli"!CNCLI="${HOME}/.cargo/bin/cncli"!' \
+  -e '1,73s!#CNODE_HOME="/opt/cardano/cnode"!CNODE_HOME='${NODE_HOME}'!' \
+  -e '1,73s!#CNODE_PORT=6000!CNODE_PORT='${b_PORT}'!' \
+  -e '1,73s!#UPDATE_CHECK="Y"!UPDATE_CHECK="N"!' \
+  -e '1,73s!#CONFIG="${CNODE_HOME}/files/config.json"!CONFIG="${CNODE_HOME}/'${NODE_CONFIG}'-config.json"!' \
+  -e '1,73s!#SOCKET="${CNODE_HOME}/sockets/node0.socket"!SOCKET="${CNODE_HOME}/db/socket"!' \
+  -e '1,73s!#BLOCKLOG_TZ="UTC"!BLOCKLOG_TZ="Asia/Tokyo"!' \
+  -e '1,73s!#POOL_NAME=""!POOL_DIR=${CNODE_HOME}!'
+

+

cncli.shファイルを修正します

+

プールIDを確認する。以下のコマンドをすべてコピーして実行してください +

pool_hex=`cat $NODE_HOME/pool.id`
+pool_bech32=`cat $NODE_HOME/pool.id-bech32`
+printf "\nプールID(hex)は \e[32m${pool_hex}\e[m です\n\n"
+printf "\nプールID(bech32)は \e[32m${pool_bech32}\e[m です\n\n"
+

+

ご自身のプールID 2種類が表示されていることを確認してください
+プールIDが表示されていない場合は、こちらの手順を実行してください

+


+cncli.shファイルを修正します。以下のコマンドをすべてコピーして実行してください +

sed -i $NODE_HOME/scripts/cncli.sh \
+-e '1,73s!#POOL_ID=""!POOL_ID="'${pool_hex}'"!' \
+-e '1,73s!#POOL_ID_BECH32=""!POOL_ID_BECH32="'${pool_bech32}'"!' \
+-e '1,73s!#POOL_VRF_SKEY=""!POOL_VRF_SKEY="${CNODE_HOME}/vrf.skey"!' \
+-e '1,73s!#POOL_VRF_VKEY=""!POOL_VRF_VKEY="${CNODE_HOME}/vrf.vkey"!'
+

+

10-4. サービスファイル作成・登録

+
cd $NODE_HOME
+mkdir service
+cd service
+
+
+
+
+
cat > $NODE_HOME/service/cnode-cncli-sync.service << EOF 
+# file: /etc/systemd/system/cnode-cncli-sync.service
+
+[Unit]
+Description=Cardano Node - CNCLI sync
+BindsTo=cardano-node.service
+After=cardano-node.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME/scripts
+ExecStart=/bin/bash -c "sleep 5;/usr/bin/tmux new -d -s cncli"
+ExecStartPost=/usr/bin/tmux send-keys -t cncli ./cncli.sh Space sync Enter
+ExecStop=/usr/bin/tmux kill-session -t cncli
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-cncli-sync
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cardano-node.service
+EOF
+
+
+
+
cat > $NODE_HOME/service/cnode-cncli-validate.service << EOF 
+# file: /etc/systemd/system/cnode-cncli-validate.service
+
+[Unit]
+Description=Cardano Node - CNCLI validate
+BindsTo=cnode-cncli-sync.service
+After=cnode-cncli-sync.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME/scripts
+ExecStart=/bin/bash -c "sleep 10;/usr/bin/tmux new -d -s validate"
+ExecStartPost=/usr/bin/tmux send-keys -t validate ./cncli.sh Space validate Enter
+ExecStop=/usr/bin/tmux kill-session -t validate
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-cncli-validate
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cnode-cncli-sync.service
+EOF
+
+
+
+
cat > $NODE_HOME/service/cnode-cncli-leaderlog.service << EOF 
+# file: /etc/systemd/system/cnode-cncli-leaderlog.service
+
+[Unit]
+Description=Cardano Node - CNCLI Leaderlog
+BindsTo=cnode-cncli-sync.service
+After=cnode-cncli-sync.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME/scripts
+ExecStart=/bin/bash -c "sleep 15;/usr/bin/tmux new -d -s leaderlog"
+ExecStartPost=/usr/bin/tmux send-keys -t leaderlog ./cncli.sh Space leaderlog Enter
+ExecStop=/usr/bin/tmux kill-session -t leaderlog
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-cncli-leaderlog
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cnode-cncli-sync.service
+EOF
+
+
+
+
cat > $NODE_HOME/service/cnode-logmonitor.service << EOF 
+# file: /etc/systemd/system/cnode-logmonitor.service
+
+[Unit]
+Description=Cardano Node - CNCLI logmonitor
+BindsTo=cnode-cncli-sync.service
+After=cnode-cncli-sync.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME
+ExecStart=/bin/bash -c "sleep 20;/usr/bin/tmux new -d -s logmonitor"
+ExecStartPost=/usr/bin/tmux send-keys -t logmonitor $NODE_HOME/scripts/logMonitor.sh Enter
+ExecStop=/usr/bin/tmux kill-session -t logmonitor
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-logmonitor
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cnode-cncli-sync.service
+EOF
+
+
+
+
+

サービスファイルをシステムフォルダにコピーして権限を付与します

+

1行ずつコマンドに貼り付けてください +

sudo cp $NODE_HOME/service/cnode-cncli-sync.service /etc/systemd/system/cnode-cncli-sync.service
+sudo cp $NODE_HOME/service/cnode-cncli-validate.service /etc/systemd/system/cnode-cncli-validate.service
+sudo cp $NODE_HOME/service/cnode-cncli-leaderlog.service /etc/systemd/system/cnode-cncli-leaderlog.service
+sudo cp $NODE_HOME/service/cnode-logmonitor.service /etc/systemd/system/cnode-logmonitor.service
+

+
sudo chmod 644 /etc/systemd/system/cnode-cncli-sync.service
+sudo chmod 644 /etc/systemd/system/cnode-cncli-validate.service
+sudo chmod 644 /etc/systemd/system/cnode-cncli-leaderlog.service
+sudo chmod 644 /etc/systemd/system/cnode-logmonitor.service
+
+

サービスファイルを有効化します

+
sudo systemctl daemon-reload
+sudo systemctl enable cnode-cncli-sync.service
+sudo systemctl enable cnode-cncli-validate.service
+sudo systemctl enable cnode-cncli-leaderlog.service
+sudo systemctl enable cnode-logmonitor.service
+
+

10-5. ブロックチェーンとDBを同期

+

cncli-syncサービスを開始し、ログ画面を表示します +

sudo systemctl start cnode-cncli-sync.service
+tmux a -t cncli
+

+
+

確認

+

「100.00% synced」になるまで待ちます。
+100%になったら、Ctrl+bを押した後に d を押し元の画面に戻ります(バックグラウンド実行に切り替え)

+
+

10-6. 過去のブロック生成実績取得

+
cd $NODE_HOME/scripts
+./cncli.sh init
+
+

tmux起動確認

+
tmux ls
+
+
+

確認

+

ノードを再起動してから、約20秒後に4プログラムがバックグラウンドで起動中であればOKです

+
    +
  • cncli
  • +
  • leaderlog
  • +
  • validate
  • +
  • logmonitor
  • +
+
+
+

便利なコマンド

+

●各種サービスをストップする方法

+

sudo systemctl stop cnode-cncli-sync.service
+
+上記コマンドを実行すると以下サービスも連動して止まります

+
    +
  • cnode-cncli-validate.service
  • +
  • cnode-cncli-leaderlog.service
  • +
  • cnode-logmonitor.service
  • +
+

●各種サービスを再起動する方法

+

sudo systemctl reload-or-restart cnode-cncli-sync.service
+
+上記コマンドを実行すると以下サービスも連動して止まります

+
    +
  • cnode-cncli-validate.service
  • +
  • cnode-cncli-leaderlog.service
  • +
  • cnode-logmonitor.service
  • +
+
+

プログラムのログ画面を確認します

+
+
+
+
+

こちらのプログラムは生成したブロックが、ブロックチェーン上に記録されているか照合するためのプログラムです

+
+

tmux a -t validate
+
+以下の表示なら正常です。 +
~ CNCLI Block Validation started ~
+
+Ctrl+bを押した後すぐにd でバックグラウンド実行に切り替えます(デタッチ)

+
+
+
+

こちらのプログラムはスロットリーダーを自動的に算出するプログラムです。
+次エポックの1.5日前から次エポックのスケジュールを算出することができます。

+
+
tmux a -t leaderlog
+
+

以下の表示なら正常です。
+スケジュール予定がある場合、表示されるまでに5分ほどかかります。

+
~ CNCLI Leaderlog started ~
+
+

Ctrl+bを押した後すぐにd でバックグラウンド実行に切り替えます(デタッチ)

+
+
+
+

こちらのプログラムはプールのノードログからブロック生成結果を抽出します。

+
+
tmux a -t logmonitor
+
+

以下の表示なら正常です。

+

~~ LOG MONITOR STARTED ~~
+monitoring logs/node.json for traces
+
+Ctrl+bを押した後すぐにd でバックグラウンド実行に切り替えます(デタッチ)

+
+
+
+

10-8. ブロックログを表示する

+

このツールでは上記で設定してきたプログラムを組み合わせ、割り当てられたスロットリーダーに対してのブロック生成結果をデータベースに格納し、確認することができます。

+
cd $NODE_HOME/scripts
+./blocks.sh
+
+
+

便利な設定

+

スクリプトへのパスを通し、任意の単語で起動出来るようにする。 +

echo alias blocks="'cd $NODE_HOME/scripts; ./blocks.sh'" >> $HOME/.bashrc
+source $HOME/.bashrc
+

+

単語を入力するだけで、どこからでも起動できます。
+blocks・・・blocks.sh

+
+

+

(s)実績概要---エポック毎のブロック生成実績参照
+(e)エポック詳細---個別エポックのブロック生成スケジュールおよび生成実績参照

+

+

ブロックステータス

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目意味
Leaderブロック生成割り当て数
Idealアクティブステーク(シグマ)に基づいて割り当てられたブロック数の期待値/理想値
Luck期待値における実際に割り当てられたスロットリーダー数のパーセンテージ
Adoptedブロック生成フラグ
Confirmed生成したブロックのうち確実にオンチェーンであることが検証されたブロック (ブロック生成成功)
Missedスロットでスケジュールされているが、 cncli DB には記録されておらず他のプールがこのスロットのためにブロックを作った可能性
Ghostedブロックは作成されましたが「Orphans(孤立ブロック)」となっております。 スロットバトル・ハイトバトルで敗北したか、ブロック伝播の問題で有効なブロックになっていません
Stolen別のプールに有効なブロックが登録されているため、スロットバトルで敗北した可能性
Invalidプールはブロックの作成に失敗しました。base64でエンコードされたエラーメッセージがlogmonitorに表示されます
+

Invalidのエラー内容は次のコードでデコードできます +

echo (base64コードを入れる) | base64 -d | jq -r
+

+

メニュー項目が文字化けする場合は、システム文字コードが「UTF-8」であることを確認してください。
+

echo $LANG
+

+

10-9. スケジュールを取得する

+
+

ブロック生成スケジュール取得のタイミングについて

+

取得タイミングは、エポックスロットが約302400を過ぎてから次エポックのスケジュールを取得できるようになります。(次エポックの1.5日前)

+

11.ブロック生成ステータス通知を導入することで「自動取得」を設定することが可能です。
+エポックスロットが約302400を過ぎると次エポックのスケジュールを自動取得し、任意の通知プラットフォームに通知します。

+

各自の運用方針に合せて、次エポックのスケジュール 「自動取得」または 「手動取得」 を選択してください。
+「手動取得」 の場合は、以下のコマンドを手動実行することでスケジュールを取得することが出来ます。

+
+

スケジュール取得コマンドを実行する(手動取得の場合)

+

tmux send-keys -t leaderlog './cncli.sh leaderlog' C-m
+
+スケジュール取得状況を確認する +
tmux a -t leaderlog
+

+
+

Tip

+
    +
  • スケジュールの中にError: database is lockedがある場合は、よくある質問のQ4.スケジュール取得時「Error: database is locked」が表示されるをご確認ください
  • +
  • Leaderslots: 0 - Ideal slots for epoch based on active stake: 0.01 - Luck factor 0%が表示された場合は、残念がらブロック生成スケジュールはありません。
  • +
  • スケジュール取得が確認できたら Ctrl+b d でデタッチしてください。
  • +
+
+

1エポックで1ブロック割り当てられるために必要な委任量の目安は以下の通りです。%は確率
+1M 60%
+2M 85%
+3M 95%

+

プール開設時は、2エポック後から割り当てがスタートします。
+303 プール登録
+304 待機期間 次エポックスケジュール算出
+305 委任有効 ブロック生成
+306 報酬計算
+307 報酬振り込み

+
+

ブロック生成ステータスを通知する

+

ブロックログDBに保存されるブロック生成ステータスをLINE/Slack/discord/telegramに通知することができます。
+設定手順はブロック生成ステータス通知設定手順を参照してください。

+
+

10-99.CNCLI更新手順

+

以下は最新版がリリースされた場合に実行してください

+

cncli旧バージョンからの更新手順

+
+

注意

+

1時間以内にブロック生成スケジュールがないことを確認してから、以下を実施してください

+
+
rustup update
+rustup target add x86_64-unknown-linux-musl
+
+
sudo apt update -y && sudo apt install -y automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw5 libtool autoconf musl-tools
+
+

cd $HOME/git/cncli
+git fetch --all --prune
+git checkout $(curl -s https://api.github.com/repos/cardano-community/cncli/releases/latest | jq -r .tag_name)
+cargo install --path . --force
+
+バージョンを確認する +
cncli --version
+

+
+

5.3.2 が最新バージョンです

+
+

ノードを再起動する +

sudo systemctl reload-or-restart cardano-node
+

+
+

ノードが同期したことを確認する

+
+
tmux a -t cncli
+
+
+

100% syncedになったことを確認する

+
+

各サービスを表示し、envまたはcncli.shのアップデートメッセージがある場合は"n"で拒否 +

tmux a -t leaderlog
+tmux a -t validate
+

+
+

envまたはcncli.shのアップデートが必要になった場合は改めてアナウンスします。

+
+

スケジュールにないブロックが生成される場合

+

CNCLIのブロック生成スケジュールは正しい値が取得できていれば、100%正確です。
+cncli.dbを再作成することで正しいスケジュールを取得することができます。

+

修正手順

+

・サービスを止める +

sudo systemctl stop cnode-cncli-sync.service
+

+

cncli.dbを削除する +

cd $NODE_HOME/guild-db/cncli
+rm cncli.db
+

+

サービスを起動し、同期が100%になるまで待つ +

sudo systemctl start cnode-cncli-sync.service
+tmux a -t cncli
+

+

リーダースケジュールを再取得する +

tmux a -t leaderlog
+(Ctrl+C)で処理を中断する
+$NODE_HOME/scripts/cncli.sh leaderlog force
+
+過去のブロック生成実績をDBに登録する +
cd $NODE_HOME/scripts
+./cncli.sh init
+

+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/11-blocknotify-setup/index.html b/setup/11-blocknotify-setup/index.html new file mode 100644 index 00000000..f678f313 --- /dev/null +++ b/setup/11-blocknotify-setup/index.html @@ -0,0 +1,3418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.ブロック生成ステータス通知セットアップ - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

** ブロック生成ステータス通知 **

+
+

概要

+

最終更新日:2023/09/28 v1.9.5

+
    +
  • +

    ブロックログで表示されるブロック生成結果を任意のソーシャルアプリへ通知します。 +*

    +
  • +
  • +

    ブロック生成スケジュールを自動取得し、取得スケジュール一覧を通知します。 +*

    +
  • +
  • +

    通知先対応アプリ LINE/Slack/discord/telegram

    +
  • +
  • +

    ブロックログと連動しておりますので、まだ設定されてない場合はブロックログ導入手順を先に導入してください。

    +
  • +
  • +

    以下の作業はguild-dbが存在するBPサーバーのみで実施し、ブロック生成スケジュールがないタイミングで実施してください。

    +
  • +
  • +

    設定は任意です。(設定しなくてもブロック生成に影響はありません)

    +
  • +
+
+
+更新履歴▼ +
    +
  • 1.9.5 ・LINE通知不具合修正
  • +
  • 1.9.4 ・スケジュール取得スロットを303300317700間でランダム化
  • +
  • 1.9.0 ・ノード再起動時のエラー修正
  • +
  • +

    1.8.9 ・エポック境界の通知内容不具合修正
    +   ・通知内容フォーマット変更

    +
  • +
  • +

    1.8.8 ・ステータス通知サービス起動時に通知
    +   ・通知先トークン未入力の場合にサービス画面でエラー排出

    +
  • +
  • 1.8.7 ノード再起動後、通知されない不具合を修正
  • +
  • 1.8.6 スケジュール取得自動化導入(選択式)
    +   ・取得スケジュール一覧通知
  • +
  • 1.7 スケジュール取得タイミング通知
    +   ・生成ブロックのPooltoolリンク追加
  • +
  • 1.6 ブロック未生成プールで使用する場合の起動時エラーを修正
  • +
  • 1.5 10分以内に複数のスケジュールがある場合の通知バグ修正
  • +
  • 1.4 次のスケジュールを表示
  • +
  • 1.3 ノード再起動時の不具合を修正
  • +
  • 1.2.3 エポック取得フロー修正
  • +
  • 1.2.2 通知バグ修正
  • +
  • 1.2 ・Telegram、Slackに対応
    +   ・通知基準設定( 全て/confirm以外全て/Missedとivaildのみ)
    +   ・通知内容を変更(X番目/トータルスケジュール数)
  • +
  • 1.1 スケジュール取得時、その他通知判定修正
  • +
  • 1.0.1 軽微な修正
  • +
  • 1.0 初版リリース
  • +
+
+

11-1. 依存プログラムをインストールする

+

Python環境をセットアップする

+

pythonバージョンを確認する +

python3 -V
+

+
+

Python 3.8.10以上

+
+

パッケージを更新する +

sudo apt update -y
+

+

sudo apt install -y python3-watchdog python3-tz python3-dateutil python3-requests build-essential libssl-dev libffi-dev python3-dev python3-pip
+
+
pip install discordwebhook python-dotenv slackweb
+

+

実行スクリプトと設定ファイルをダウンロードする

+
cd $NODE_HOME/guild-db/blocklog
+wget -N https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/block_check.py
+wget -N https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/.env
+chmod 755 block_check.py
+
+

cncli.sh適用状態確認

+

** cncli.sh適用状態を確認する**
+スケジュール取得自動化にはKOIOS-API対応のcncli.shが必要となります。以下のコマンドを実行し確認してください。 +

cat $NODE_HOME/scripts/cncli.sh | grep -o '#USE_KOIOS_API=Y'
+

+
+

戻り値確認

+
+
+
+

#USE_KOIOS_API=Y の戻り値があれば、対応するcncli.shが適用されています。
+次へ進んでください。

+
+
+ +
+
+
+
+

11-2. 通知アプリの設定

+

通知させたいアプリのタブをクリックし設定を確認してください。

+
+
+
+
    +
  • +

    1.LINEグループを作成する
    +*

    +
  • +
  • +

    2.「Line Notify」を追加する
    +*

    +
  • +
  • +

    3.任意のグループ名を設定し「作成」をクリックする +*

    +
  • +
  • +

    4.LINE Notifyマイページにアクセスする

    +
  • +
  • +

    5.トークンを発行するをクリックします
    +*

    +
  • +
  • +

    6.トークン名「ブロック生成通知」(任意)を入力し、3で作成したグループ名を選択する
    +*

    +
  • +
  • +

    7.「発行する」をクリックする

    +
  • +
  • +

    8.表示されたトークンをコピーし、一旦メモ帳などに貼り付ける
    +(発行されたトークンを閉じると2度と確認できませんのでご注意ください)
    +*

    +
  • +
+
+
+
    +
  • +

    1.サーバーを追加する
    +*

    +
  • +
  • +

    2.「オリジナルの作成」を選択する
    +*

    +
  • +
  • +

    3.「自分と友達のため」を選択する
    +*

    +
  • +
  • +

    4.任意のサーバー名を入力して「新規作成」をクリックする
    +*

    +
  • +
  • +

    5.通知したいチャンネルの歯車マークをクリックする
    +*

    +
  • +
  • +

    6.「連携サービス」をクリックし、「ウェブフックを作成」をクリックする
    +*

    +
  • +
  • +

    7.「ウェブフックURLをコピー」をクリックし、一旦メモ帳などに貼り付ける
    +*

    +
  • +
+
+
+
    +
  • +

    1.Telegramの検索欄で「@botFather」を検索して認証マーク付きのアカウントをクリックする
    +*

    +
  • +
  • +

    2.「START」をクリックする
    +*

    +
  • +
  • +

    3.「/newbot」コマンドを入力する
    +*

    +
  • +
  • +

    4.任意のbot名を入力する 例)「btbf_bot」最後は必ず_botで終わるようにする
    +*

    +
  • +
  • +

    5.緑で隠した部分のAPIトークンをメモ帳に控える
    +*

    +
  • +
  • +

    6.赤枠で囲ったbotチャンネルに参加する
    +*

    +
  • +
  • +

    7.検索欄で「@RawDataBot」を検索してクリックする
    +*

    +
  • +
  • +

    8.「START」をクリックする
    +*

    +
  • +
  • +

    9.「Chat id」をメモ帳に控える
    +*

    +
  • +
+
+
+
    +
  • +

    1.Slackを起動し、通知用のワークスペースとチャンネルを設定する

    +
  • +
  • +

    2.Incoming Webhookの設定ページへアクセスする

    +
  • +
  • +

    3.通知したいワークスペースとチャンネルを選択する
    +*

    +
  • +
  • +

    4.「Webhook URL」をメモ帳に控える
    +*

    +
  • +
  • +

    5.ページ下部の「設定を保存する」をクリックする
    +*

    +
  • +
+
+
+
+

11-3. 通知プログラムの設定

+

設定ファイルの編集

+
cd $NODE_HOME/guild-db/blocklog
+nano .env
+
+
+

.envは隠しファイルになっているので、ls -aコマンドで一覧表示されます。

+
+
+

envファイル内容詳細

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
項目使用用途
tickerプールティッカー名を入力する
line_notify_tokenLine Notifyトークンを入力する
dc_notify_urlDiscordウェブフックURLを入力する
slack_notify_urlSlackウェブフックURLを入力する
teleg_tokenTelegram APIトークンを入力する
teleg_idTelegram ChatIDを入力する
b_timezoneお住いのタイムゾーンを指定する
bNotify通知先を指定する
bNotify_st通知基準を設定する
auto_leaderスケジュール取得方法を設定する
+
    +
  • 各自の運用方針に合せて、次エポックのスケジュール 「自動取得」または 「手動取得」 を選択してください。
  • +
  • 「自動取得」 は、エポックスロットが約302400を過ぎてから自動的に発動します。
  • +
  • 「手動取得」 は、手動でのコマンド実行によるスケジュール取得となります。
  • +
+
+

サービスファイルを設定する

+
+
+
+
cat > $NODE_HOME/service/cnode-blockcheck.service << EOF 
+# file: /etc/systemd/system/cnode-blockcheck.service
+
+[Unit]
+Description=Cardano Node - CNCLI blockcheck
+BindsTo=cnode-cncli-sync.service
+After=cnode-cncli-sync.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+Restart=on-failure
+RestartSec=20
+User=$(whoami)
+WorkingDirectory=$NODE_HOME
+ExecStart=/usr/bin/tmux new -d -s blockcheck
+ExecStartPost=/usr/bin/tmux send-keys -t blockcheck 'cd $NODE_HOME/guild-db/blocklog' Enter
+ExecStartPost=/usr/bin/tmux send-keys -t blockcheck python3 Space block_check.py Enter
+ExecStop=/usr/bin/tmux kill-session -t blockcheck
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+SuccessExitStatus=143
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=cnode-blockcheck
+TimeoutStopSec=5
+
+[Install]
+WantedBy=cnode-cncli-sync.service
+EOF
+
+
sudo cp $NODE_HOME/service/cnode-blockcheck.service /etc/systemd/system/cnode-blockcheck.service
+sudo chmod 644 /etc/systemd/system/cnode-blockcheck.service
+
+

sudo systemctl daemon-reload
+sudo systemctl enable cnode-blockcheck.service
+
+ノードを再起動する +
sudo systemctl reload-or-restart cardano-node
+

+
+
+
+

起動確認

+
tmux a -t blockcheck
+
+
+

「Guild-db monitoring started」 が表示されていればOKです
+任意の通知先に通知が届いているか確認してください
+cnode-cncli-sync.serviceと同じく、node再起動・停止と連動します

+
+

通知確認

+

ブロック生成スケジュール予定時刻が過ぎてから、約15分以内に通知が届きます。

+

11-4. バージョンアップ手順

+

サービスを停止する +

sudo systemctl stop cnode-blockcheck.service
+

+

バージョン確認 +

cd $NODE_HOME/guild-db/blocklog
+cat block_check.py | grep -HnI -m1 -r btbf
+

+
+バージョン1.7以下の場合はこちらを先に実行する(クリックして開く) +

1) cncli.sh適用状態を確認する
+スケジュール取得自動化にはKOIOS-API対応のcncli.shが必要となります。以下のコマンドを実行し確認してください。 +

cat $NODE_HOME/scripts/cncli.sh | grep -o '#USE_KOIOS_API=Y'
+

+
+

戻り値確認

+
+
+
+

#USE_KOIOS_API=Y の戻り値があれば、対応するcncli.shが適用されています。
+2)へ進んでください。

+
+
+ +
+
+
+
+


+2) ステータス通知用.envファイルを修正する

+
    +
  • 各自の運用方針に合せて、次エポックのスケジュール 「自動取得」または 「手動取得」 を選択してください。
  • +
  • 「自動取得」 は、エポックスロットが約302400を過ぎてから自動的に発動します。
  • +
  • 「手動取得」 は、手動でのコマンド実行によるスケジュール取得となります。
  • +
+
+
+
+
sed -i $NODE_HOME/guild-db/blocklog/.env \
+-e '1,73s!###############################!\n#リーダースケジュール自動取得 自動:1 手動:0\nauto_leader = "1"!'
+
+
+
+
sed -i $NODE_HOME/guild-db/blocklog/.env \
+-e '1,73s!###############################!\n#リーダースケジュール自動取得 自動:1 手動:0\nauto_leader = "0"!'
+
+
+
+
+
+

参考

+

上記で実行するコマンドは、スケジュール自動/手動化に対応するフラグを.envに追加しています。 +

#リーダースケジュール自動取得 自動:1 手動:0
+auto_leader = "1"
+

+
+
+

スクリプトをダウンロードする +

cd $NODE_HOME/guild-db/blocklog
+wget https://raw.githubusercontent.com/btbf/spojapanguild/master/scripts/block_notify/block_check.py -O block_check.py
+
+バージョン確認 +
cd $NODE_HOME/guild-db/blocklog
+cat block_check.py | grep -HnI -m1 -r btbf
+
+現在の最新バージョン

+
+

2023/09/28 v1.9.5 @btbf

+
+

サービスを再起動する +

sudo systemctl start cnode-blockcheck.service
+

+

サービス起動確認 +

tmux a -t blockcheck
+

+
+

「Guild-db monitoring started」 が表示されていればOKです。(デタッチして戻る)
+任意の通知先に通知が届いているか確認してください

+
+

11-5.通知を停止(アンインストール)する手順

+
sudo systemctl stop cnode-blockcheck.service
+sudo systemctl disable cnode-blockcheck.service
+sudo rm /etc/systemd/system/cnode-blockcheck.service
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/2-node-setup/index.html b/setup/2-node-setup/index.html new file mode 100644 index 00000000..fcbd29b3 --- /dev/null +++ b/setup/2-node-setup/index.html @@ -0,0 +1,3630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.ノードインストール - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

2. ノードインストール

+
+

インストールバージョン

+ + + + + + + + + + + + + + + + + +
NodeCLIGHCCabal
8.7.38.17.0.08.10.73.8.1.0
+
    +
  • 複数行のコードをコードボックスのコピーボタンを使用してコマンドラインに貼り付ける場合は、最後の行が自動実行されないため確認の上Enterを押してコードを実行してください。
  • +
+
+

2-1. 依存関係インストール

+

ターミナルを起動し、以下のコマンドを入力しましょう!

+

新しいTMUXセッションを開く

+
tmux new -s build
+
+

まずはじめに、パッケージを更新しUbuntuを最新の状態に保ちます。

+

sudo apt update -y && sudo apt upgrade -y
+
+
sudo apt install git jq bc automake tmux rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf liblmdb-dev -y
+

+

Libsodiumインストール

+
mkdir $HOME/git
+cd $HOME/git
+git clone https://github.com/IntersectMBO/libsodium
+cd libsodium
+git checkout dbb48cc
+./autogen.sh
+./configure
+make
+make check
+sudo make install
+
+
+

makeコマンド実行後半に出現する warning は無視して大丈夫です。

+
+

Secp256k1ライブラリインストール

+
cd $HOME/git
+git clone https://github.com/bitcoin-core/secp256k1.git
+
+
cd secp256k1/
+git checkout ac83be33
+./autogen.sh
+./configure --prefix=/usr --enable-module-schnorrsig --enable-experimental
+make
+make check
+
+
+

戻り値確認

+
Testsuite summary for libsecp256k1 0.1.0-pre
+============================================================================
+# TOTAL: 2
+# PASS:  2
+# SKIP:  0
+# XFAIL: 0
+# FAIL:  0
+# XPASS: 0
+# ERROR: 0
+============================================================================
+
+
+

PASS:2であることを確認する

+
+
+

インストールコマンドを必ず実行する +

sudo make install
+

+

blstインストール

+

1.blstダウンロード +

cd $HOME/git
+git clone https://github.com/supranational/blst
+cd blst
+git checkout v0.3.10
+./build.sh
+

+

2.設定ファイル作成

+
+

このボックスはすべてコピーして実行してください

+
+
cat > libblst.pc << EOF
+prefix=/usr/local
+exec_prefix=\${prefix}
+libdir=\${exec_prefix}/lib
+includedir=\${prefix}/include
+
+Name: libblst
+Description: Multilingual BLS12-381 signature library
+URL: https://github.com/supranational/blst
+Version: 0.3.10
+Cflags: -I\${includedir}
+Libs: -L\${libdir} -lblst
+EOF
+
+

3.設定ファイルコピー

+
+

このボックスは1行ずつコピーして実行してください

+
+
sudo cp libblst.pc /usr/local/lib/pkgconfig/
+sudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp  /usr/local/include/
+sudo cp libblst.a /usr/local/lib
+sudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}
+
+

GHCUPインストール

+

インストール変数設定 +

cd $HOME
+BOOTSTRAP_HASKELL_NONINTERACTIVE=1
+BOOTSTRAP_HASKELL_NO_UPGRADE=1
+BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes
+BOOTSTRAP_HASKELL_ADJUST_BASHRC=1
+unset BOOTSTRAP_HASKELL_INSTALL_HLS
+export BOOTSTRAP_HASKELL_NONINTERACTIVE BOOTSTRAP_HASKELL_INSTALL_STACK BOOTSTRAP_HASKELL_ADJUST_BASHRC
+

+

インストール +

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | bash
+

+ + +
+

Cabal/GHCバージョンについて

+

最新バージョンはcardano-node/cliのビルドに失敗するため必ず以下で指定されたバージョンをインストールしてください。

+
+

cabalインストール +

source ~/.bashrc
+ghcup upgrade
+ghcup install cabal 3.8.1.0
+ghcup set cabal 3.8.1.0
+

+

GHCインストール

+
ghcup install ghc 8.10.7
+ghcup set ghc 8.10.7
+
+

バージョン確認

+
cabal update
+cabal --version
+ghc --version
+
+
+

チェック

+

Cabalバージョン:「3.8.1.0」
+GHCバージョン:「8.10.7」であることを確認してください。

+
+

環境変数を設定しパスを通します。
+ノード設定ファイルは $NODE_HOME(例:/home/user/cnode) に設定されます。

+
echo PATH="$HOME/.local/bin:$PATH" >> $HOME/.bashrc
+echo export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" >> $HOME/.bashrc
+echo export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" >> $HOME/.bashrc
+echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc
+
+

環境変数に接続ネットワークを指定する +

echo export NODE_CONFIG=mainnet >> $HOME/.bashrc
+echo export NODE_NETWORK='"--mainnet"' >> $HOME/.bashrc
+echo export CARDANO_NODE_NETWORK_ID=mainnet >> $HOME/.bashrc
+

+
+テストネットの場合はこちら +
+
+
+
echo export NODE_CONFIG=preview >> $HOME/.bashrc
+echo export NODE_NETWORK='"--testnet-magic 2"' >> $HOME/.bashrc
+echo export CARDANO_NODE_NETWORK_ID=2 >> $HOME/.bashrc
+
+
+
+
echo export NODE_CONFIG=preprod >> $HOME/.bashrc
+echo export NODE_NETWORK='"--testnet-magic 1"' >> $HOME/.bashrc
+echo export CARDANO_NODE_NETWORK_ID=1 >> $HOME/.bashrc
+
+
+
+
+
+

bashrc再読み込み +

source $HOME/.bashrc
+

+

2-2. ソースコードからビルド

+
+

確認

+

バイナリーファイルは必ずソースコードからビルドするようにし、整合性をチェックしてください。IOGは現在ARMアーキテクチャ用のバイナリファイルを提供していません。Raspberry Piを使用してプールを構築する場合は、ARM用コンパイラでコンパイルする必要があります。

+
+

Gitからソースコードをダウンロードし、最新のタグに切り替えます。

+
cd $HOME/git
+git clone https://github.com/IntersectMBO/cardano-node.git
+cd cardano-node
+git fetch --all --recurse-submodules --tags
+git checkout tags/8.7.3
+
+

Cabalのビルドオプションを構成します。

+
cabal clean
+cabal update
+cabal configure --with-compiler=ghc-8.10.7
+
+

カルダノノードをビルドします。

+
cabal build cardano-cli cardano-node
+
+
+

ヒント

+

サーバスペックによって、ビルド完了までに数分から数時間かかる場合があります。

+
+

cardano-cliファイルと cardano-nodeファイルをbinディレクトリにコピーします。

+

sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-cli") /usr/local/bin/cardano-cli
+
+
sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-node") /usr/local/bin/cardano-node
+

+

cardano-clicardano-nodeのバージョンが最新Gitタグバージョンであることを確認してください。

+
cardano-node version
+cardano-cli version
+
+

以下の戻り値を確認する

+
+

cardano-cli 8.17.0.0 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+

cardano-node 8.7.3 - linux-x86_64 - ghc-8.10
+git rev a4a8119b59b1fbb9a69c79e1e6900e91292161e7

+
+

TMUXセッションを閉じる

+
exit
+
+

2-3. ノード設定ファイルの修正

+

ノード構成に必要な設定ファイルを取得します。
+config.json、genesis.json、topology.json

+
mkdir $NODE_HOME
+cd $NODE_HOME
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/byron-genesis.json -O ${NODE_CONFIG}-byron-genesis.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/topology-legacy.json -O ${NODE_CONFIG}-topology.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/shelley-genesis.json -O ${NODE_CONFIG}-shelley-genesis.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/alonzo-genesis.json -O ${NODE_CONFIG}-alonzo-genesis.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/conway-genesis.json -O ${NODE_CONFIG}-conway-genesis.json
+wget --no-use-server-timestamps -q https://book.play.dev.cardano.org/environments/${NODE_CONFIG}/config.json -O ${NODE_CONFIG}-config.json
+
+

以下のコードを実行し config.jsonファイルを更新します。

+

設定ファイルを書き換える

+
sed -i ${NODE_CONFIG}-config.json \
+    -e 's!"EnableP2P": true!"EnableP2P": false!' \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e "s/TraceMempool\": false/TraceMempool\": true/g" \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e 's!"rpKeepFilesNum": 10!"rpKeepFilesNum": 30!' \
+    -e 's!"rpMaxAgeHours": 24!"rpMaxAgeHours": 48!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+テストネットの場合はこちら +
sed -i ${NODE_CONFIG}-config.json \
+    -e 's!"EnableP2P": true!"EnableP2P": false!' \
+    -e 's!"AlonzoGenesisFile": "alonzo-genesis.json"!"AlonzoGenesisFile": "'${NODE_CONFIG}'-alonzo-genesis.json"!' \
+    -e 's!"ByronGenesisFile": "byron-genesis.json"!"ByronGenesisFile": "'${NODE_CONFIG}'-byron-genesis.json"!' \
+    -e 's!"ShelleyGenesisFile": "shelley-genesis.json"!"ShelleyGenesisFile": "'${NODE_CONFIG}'-shelley-genesis.json"!' \
+    -e 's!"ConwayGenesisFile": "conway-genesis.json"!"ConwayGenesisFile": "'${NODE_CONFIG}'-conway-genesis.json"!' \
+    -e 's!"TraceBlockFetchDecisions": false!"TraceBlockFetchDecisions": true!' \
+    -e '/"defaultScribes": \[/a\    \[\n      "FileSK",\n      "'${NODE_HOME}'/logs/node.json"\n    \],' \
+    -e '/"setupScribes": \[/a\    \{\n      "scFormat": "ScJson",\n      "scKind": "FileSK",\n      "scName": "'${NODE_HOME}'/logs/node.json"\n    \},' \
+    -e "s/127.0.0.1/0.0.0.0/g"
+
+
+

環境変数を追加し、.bashrcファイルを更新します。

+
echo export CARDANO_NODE_SOCKET_PATH="$NODE_HOME/db/socket" >> $HOME/.bashrc
+source $HOME/.bashrc
+
+

2-4. ノード起動スクリプトの作成

+

起動スクリプトには、ディレクトリ、ポート番号、DBパス、構成ファイルパス、トポロジーファイルパスなど、カルダノノードを実行するために必要な変数が含まれています。

+

全行をコピーしコマンドラインに送信します。

+
+
+
+

リレーノードで使用するポート番号を指定してターミナルで実行する +

PORT=6000
+

+

起動スクリプトファイルを作成する +

cat > $NODE_HOME/startRelayNode1.sh << EOF 
+#!/bin/bash
+DIRECTORY=$NODE_HOME
+PORT=${PORT}
+HOSTADDR=0.0.0.0
+TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
+DB_PATH=\${DIRECTORY}/db
+SOCKET_PATH=\${DIRECTORY}/db/socket
+CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
+/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A16m -F1.5 -H2500M -RTS run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG}
+EOF
+

+
+
+
+

注意

+
    +
  • BPノードポートはセキュリティを高めるために、49513~65535までの任意番号を設定してください。ここで設定する番号は1-3で設定したSSHポート番号とは別の番号を設定してください.
  • +
+
+

BPノードで使用するポート番号を指定してターミナルで実行する +

PORT=xxxxx
+

+

起動スクリプトファイルを作成する +

cat > $NODE_HOME/startBlockProducingNode.sh << EOF 
+#!/bin/bash
+DIRECTORY=$NODE_HOME
+PORT=${PORT}
+HOSTADDR=0.0.0.0
+TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
+DB_PATH=\${DIRECTORY}/db
+SOCKET_PATH=\${DIRECTORY}/db/socket
+CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
+/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A16m -F1.5 -H2500M -RTS run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG}
+EOF
+

+
+
+
+

2-5. ノード起動

+

起動スクリプトに実行権限を付与し、ブロックチェーンの同期を開始します。

+

リレーノードから実施します。

+
+
+
+
cd $NODE_HOME
+chmod +x startRelayNode1.sh
+./startRelayNode1.sh
+
+
+
+
cd $NODE_HOME
+chmod +x startBlockProducingNode.sh
+./startBlockProducingNode.sh
+
+
+
+
+
+

勢いよくログが流れていたら起動成功です

+
+

一旦ノードを停止します。 +

Ctrl+C
+

+

2-6. 自動起動の設定(systemd)

+

先程のスクリプトだけでは、ターミナル画面を閉じるとノードが終了してしまうので、スクリプトをサービスとして登録し、自動起動するように設定しましょう

+
+

ステークプールにsystemdを使用するメリット

+
    +
  1. メンテナンスや停電など、自動的にコンピュータが再起動したときステークプールを自動起動します。
  2. +
  3. クラッシュしたステークプールプロセスを自動的に再起動します。
  4. +
  5. ステークプールの稼働時間とパフォーマンスをレベルアップさせます。
  6. +
+
+

始める前にステークプールが停止しているか確認してください。

+
killall -s 2 cardano-node
+
+

以下のコードを実行して、ユニットファイルを作成します。

+
+
+
+
cat > $NODE_HOME/cardano-node.service << EOF 
+# The Cardano node service (part of systemd)
+# file: /etc/systemd/system/cardano-node.service 
+
+[Unit]
+Description     = Cardano node service
+Wants           = network-online.target
+After           = network-online.target 
+
+[Service]
+User            = ${USER}
+Type            = simple
+WorkingDirectory= ${NODE_HOME}
+ExecStart       = /bin/bash -c '${NODE_HOME}/startRelayNode1.sh'
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+TimeoutStopSec=300
+LimitNOFILE=32768
+Restart=always
+RestartSec=5
+SyslogIdentifier=cardano-node
+
+[Install]
+WantedBy    = multi-user.target
+EOF
+
+
+
+
cat > $NODE_HOME/cardano-node.service << EOF 
+# The Cardano node service (part of systemd)
+# file: /etc/systemd/system/cardano-node.service 
+
+[Unit]
+Description     = Cardano node service
+Wants           = network-online.target
+After           = network-online.target 
+
+[Service]
+User            = ${USER}
+Type            = simple
+WorkingDirectory= ${NODE_HOME}
+ExecStart       = /bin/bash -c '${NODE_HOME}/startBlockProducingNode.sh'
+KillSignal=SIGINT
+RestartKillSignal=SIGINT
+TimeoutStopSec=300
+LimitNOFILE=32768
+Restart=always
+RestartSec=5
+SyslogIdentifier=cardano-node
+
+[Install]
+WantedBy    = multi-user.target
+EOF
+
+
+
+
+

/etc/systemd/systemにユニットファイルをコピーして、権限を付与します。

+
sudo cp $NODE_HOME/cardano-node.service /etc/systemd/system/cardano-node.service
+
+
sudo chmod 644 /etc/systemd/system/cardano-node.service
+
+

次のコマンドを実行して、OS起動時にサービスの自動起動を有効にします。

+

sudo systemctl daemon-reload
+sudo systemctl enable cardano-node
+sudo systemctl start cardano-node
+
+システム起動後に、ログモニターを表示します

+
journalctl --unit=cardano-node --follow
+
+
+

コマンド入力に戻る場合は「Ctrl+C」(この場合ノードは終了しません)

+
+

便利なエイリアス設定

+
+

エイリアス設定

+

スクリプトへのパスを通し、任意の単語で起動出来るようにする。 +

echo alias cnode='"journalctl -u cardano-node -f"' >> $HOME/.bashrc
+echo alias cnstart='"sudo systemctl start cardano-node"' >> $HOME/.bashrc
+echo alias cnrestart='"sudo systemctl reload-or-restart cardano-node"' >> $HOME/.bashrc
+echo alias cnstop='"sudo systemctl stop cardano-node"' >> $HOME/.bashrc
+source $HOME/.bashrc
+

+

単語を入力するだけで、起動状態(ログ)を確認できます。
+

cnode ・・・ログ表示
+cnstart ・・・ノード起動
+cnrestart ・・・ノード再起動
+cnstop ・・・ノード停止
+

+
+

2-7. gLiveViewのインストール

+

cardano-nodeはログが流れる画面だけでは何が表示されているのかよくわかりません。
+それを視覚的に確認できるツールがgLiveViewです。

+
+

gLiveViewは重要なノードステータス情報を表示し、systemdサービスとうまく連携します。このツールを作成した Guild Operators の功績によるものです。

+
+

Guild LiveViewをインストールします。

+

mkdir $NODE_HOME/scripts
+cd $NODE_HOME/scripts
+sudo apt install bc tcptraceroute -y
+
+
curl -s -o gLiveView.sh https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh
+curl -s -o env https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env
+chmod 755 gLiveView.sh
+

+

env ファイル内の定義を修正します

+
+
+
+
PORT=`grep "PORT=" $NODE_HOME/startRelayNode1.sh`
+b_PORT=${PORT#"PORT="}
+echo "リレーポートは${b_PORT}です"
+
+
+
+
PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+
+
+
+
+
sed -i $NODE_HOME/scripts/env \
+    -e '1,73s!#CNODE_HOME="/opt/cardano/cnode"!CNODE_HOME=${NODE_HOME}!' \
+    -e '1,73s!#CNODE_PORT=6000!CNODE_PORT='${b_PORT}'!' \
+    -e '1,73s!#UPDATE_CHECK="Y"!UPDATE_CHECK="N"!' \
+    -e '1,73s!#CONFIG="${CNODE_HOME}/files/config.json"!CONFIG="${CNODE_HOME}/'${NODE_CONFIG}'-config.json"!' \
+    -e '1,73s!#SOCKET="${CNODE_HOME}/sockets/node0.socket"!SOCKET="${CNODE_HOME}/db/socket"!'
+
+

Guild Liveviewを起動します。

+
./gLiveView.sh
+
+

Guild Live View

+
+

GliveView起動ショートカットコード登録

+

スクリプトへのパスを通し、任意の単語で起動出来るようにする。 +

echo alias glive="'cd $NODE_HOME/scripts; ./gLiveView.sh'" >> $HOME/.bashrc
+source $HOME/.bashrc
+

+

コマンドラインにgliveと入力するだけで、どこからでも起動できます。

+
+
+gLiveViewについて▼ +
    +
  • このツールを立ち上げてもノードは起動しません。ノードは別途起動しておく必要があります
  • +
  • リレー/BPの自動判別は、手順4-5終了後に行われるようになります。
  • +
  • リレーノードでは基本情報に加え、トポロジー接続状況を確認できます。
  • +
  • BPノードでは基本情報に加え、KES有効期限、ブロック生成状況を確認できます。
  • +
+
+
+CONECTIONSについて▼ +

ノードにpingを送信する際ICMPpingを使用します。接続先ノードのファイアウォールがICMPトラフィックを受け付ける場合のみ機能します。

+
+
+

重要:ノード同期について

+

0エポックからブロックチェーンデータをダウンロードし同期します。最新エポックまで追いつくまでに1日半~2日かかり、完全に同期するまで次の項目には進めません。 +BPサーバーや2つ目のリレーサーバーでも同じ作業を実施してください。

+

<Mithril-ClientによるDB同期(ベータ版)>
+Mithril-Clientを使用することで、約2日かかっていた初回のDB同期時間を約30分以内にまで短縮することができます。
+手順はこちら→DB同期(Mithril)

+
+

2-8. エアギャップマシンセットアップ

+
+

エアギャップマシンとは?

+

エアギャップオフラインマシンは「コールド環境」と呼ばれコンピュータネットワークにおいてセキュリティを高める方法の一つ。 安全にしたいコンピュータやネットワークを、インターネットや安全でないLANといったネットワークから物理的に隔離することを指す。

+
    +
  • プール運営においてコールドキーを管理し、トランザクション署名ファイルを作成します。
  • +
  • キーロギング攻撃、マルウエア/ウイルスベースの攻撃、その他ファイアウォールやセキュリティーの悪用から保護します。
  • +
  • 有線・無線のインターネットには接続しないでください。
  • +
  • ネットワーク上にあるVMマシンではありません。
  • +
  • エアギャップについて更に詳しく知りたい場合は、こちらを参照下さい。
  • +
+
+

1.2-1. 依存関係インストール2-2. ソースコードからビルドをエアギャップマシンで実行する

+

2.以下のパスを環境変数にセットし、フォルダを作成します。

+
echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc
+echo export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" >> $HOME/.bashrc
+echo export NODE_NETWORK="--mainnet" >> $HOME/.bashrc
+echo export CARDANO_NODE_NETWORK_ID=mainnet >> $HOME/.bashrc
+source $HOME/.bashrc
+mkdir -p $NODE_HOME
+
+
+テストネットの場合はこちら +
+
+
+
+
+

echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc +echo export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" >> $HOME/.bashrc +echo export NODE_CONFIG=preview >> $HOME/.bashrc +echo export NODE_NETWORK='"--testnet-magic 2"' >> $HOME/.bashrc +echo export CARDANO_NODE_NETWORK_ID=2 >> $HOME/.bashrc +source $HOME/.bashrc +mkdir -p $NODE_HOME

+
+
+
+
+
+

echo export NODE_HOME=$HOME/cnode >> $HOME/.bashrc +echo export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" >> $HOME/.bashrc +echo export NODE_CONFIG=preview >> $HOME/.bashrc +echo export NODE_NETWORK='"--testnet-magic 1"' >> $HOME/.bashrc +echo export CARDANO_NODE_NETWORK_ID=1 >> $HOME/.bashrc +source $HOME/.bashrc +mkdir -p $NODE_HOME

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/3-relay-bp-setup/index.html b/setup/3-relay-bp-setup/index.html new file mode 100644 index 00000000..86ab26ae --- /dev/null +++ b/setup/3-relay-bp-setup/index.html @@ -0,0 +1,3027 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3.リレー/BPの接続 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

3. リレーとBPを接続する

+
+

前提条件

+

以下の項目を実施する前にリレー/BPノードが起動しているか確認してください。 +

cardano-cli query tip --mainnet | grep syncProgress
+

+

戻り値確認 +"syncProgress": "100.00"

+
+

戻り値が99以下の場合は100(最新ブロックまで同期)になるまで待ちましょう。

+
+
+
+

BPとリレーの役割

+
    +
  • +

    ブロックプロデューサーノード(BP)
    +ブロック生成に必要なキーと証明書 (node.cert, kes.skey vrf.skey)を用いて起動します。自身のリレーノードのみに接続します。

    +
  • +
  • +

    リレーノード(リレー)
    +自身のBPと他のリレーノードとの繋がりを持ち最新スロットを取得しブロック伝播の役割を果たします。

    +
  • +
+
+

+

3-1. リレーサーバーの設定変更

+

3-1-1. ファイアウォール設定を変更

+
+

設定前の注意事項

+

ご利用のVPSによっては管理画面からFWを設定する場合があります(例AWS系など)
+その場合は以下の設定を行わず、VPSマイページ管理画面などから個別に設定してください。

+
+

リレーノードで使用する 6000 番ポートのインバウンド通信を許可する。任意の番号で設定している場合はその番号を許可する。

+
+
+
+
+
+
sudo ufw allow 6000/tcp
+sudo ufw reload
+
+

3-1-2. Topologyファイル変更

+
+

topology.json とは?

+
    +
  • +

    P2P(ピアツーピア)接続における接続先ノードを記述するファイルです。

    +
  • +
  • +

    リレーノードでは、パブリックノード (IOHKや他のリレーノード) 及び、自身のブロックプロデューサーノード情報を記述します。

    +
  • +
  • +

    ブロックプロデューサーノードでは、自身のリレーノード情報のみ記述します。

    +
  • +
  • +

    「xxx.xxx.xxx.xxx」はパブリックIP(静的)アドレスに置き換えて下さい

    +
  • +
  • +

    ポート番号を変更している場合は修正してください

    +
  • +
+
+
+
+
+
+
+

自身のリレーノードから接続するノードを指定します。
+「xxx.xxx.xxx.xxx」はBPのパブリックIP(静的)アドレスと2-4で設定したBPポート番号に置き換えて下さい。

+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
+ {
+    "Producers": [
+      {
+        "addr": "relays-new.cardano-mainnet.iohk.io",
+        "port": 3001,
+        "valency": 2
+      },
+      {
+        "addr": "xxx.xxx.xxx.xxx",
+        "port": xxxxx,
+        "valency": 1
+      }
+    ]
+  }
+EOF
+
+

リレーノードを再起動する +

sudo systemctl reload-or-restart cardano-node
+

+

3-2. BPサーバーの設定変更

+

3-2-1. ファイアウォール設定を変更

+
+

BPのセキュリティ

+

BPサーバーにはプール運営の秘密鍵を保管するため、ファイアウォールでリレーサーバーからの通信のみに限定する必要があります。

+
+

BPノードに設定したポート番号を確認する +

PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+

+

BPノードで使用するポート(上記で表示された番号)の通信を許可する。

+

<リレーノード1のIP><>を除いてIPのみ入力してください。

+
+
+
+
sudo ufw allow from <リレーノード1のIP> to any port ${b_PORT}
+sudo ufw reload
+
+
+
+
sudo ufw allow from <リレーノード1のIP> to any port ${b_PORT}
+sudo ufw allow from <リレーノード2のIP> to any port ${b_PORT}
+sudo ufw reload
+
+
+

上記はBPノードポートに対しリレーIPからの通信のみ許可するという設定になります

+
+
+
+
+

3-2-2. Topologyファイル変更

+
+

ヒント

+

自身のBPノードから接続するリレーノードのIPとポート番号を指定します。 +あらかじめ、「xxx.xxx.xxx.xxx」はご自身のリレーサーバーパブリックIP(静的)アドレスとポート番号 に置き換えてからコマンドを実行して下さい。リレー台数分記載します。

+
+
+
+
+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
+{
+    "Producers": [
+      {
+        "addr": "xxx.xxx.xxx.xxx",
+        "port": 6000,
+        "valency": 1
+      }
+    ]
+  }
+EOF
+
+
+
+
cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
+{
+    "Producers": [
+      {
+        "addr": "aa.xxx.xxx.xxx",
+        "port": 6000,
+        "valency": 1
+      },
+      {
+        "addr": "bb.xxx.xxx.xxx",
+        "port": 6000,
+        "valency": 1
+      }
+    ]
+  }
+EOF
+
+
+
+
+

BPノードを再起動する +

sudo systemctl reload-or-restart cardano-node
+

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/4-bp-setup/index.html b/setup/4-bp-setup/index.html new file mode 100644 index 00000000..8380bd1e --- /dev/null +++ b/setup/4-bp-setup/index.html @@ -0,0 +1,3062 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4.BPセットアップ - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

4.BPのセットアップ

+
+

事前確認

+

以下の項目を実施する前にBPノードが起動しているか確認してください。 +

cardano-cli query tip --mainnet | grep syncProgress
+

+

戻り値確認 +"syncProgress": "100.00" 戻り値が99以下の場合は100(最新ブロックまで同期)になるまで待ちましょう。

+
+
+

BP起動に必要なファイルとは?

+

ブロックプロデューサーノードでは3つのキーを生成する必要があります。

+
    +
  • ステークプールの運用証明書 (node.cert)
  • +
  • ステークプールのセキュリティキー (kes.skey)
  • +
  • ステークプールのVRFキー (vrf.skey)
  • +
+
+

1.KESキーの作成

+
+

KESキーについて

+

(KES=Key Evolving Signature)の略
+キーを悪用するハッカーからステークプールを保護するために作成され、90日ごとに再生成する必要があります。詳細は運用マニュアルを参照してください

+
+
+
+
+
cd $NODE_HOME
+cardano-cli node key-gen-KES \
+    --verification-key-file kes.vkey \
+    --signing-key-file kes.skey
+
+
+
+
+

2.コールドキーの作成

+
+

注意

+

コールドキーはエアギャップオフラインマシンで生成し保管する必要があります
+このファイルはプール運営で重要なコールドキーです。エアギャップマシンで作成しオンライン環境に保管しないようご注意下さい。
+外部に流出するとプールが乗っ取られる可能性がありますので管理には十分注意してください +また複数のUSBに保管し、絶対に上書き・削除しないようご注意下さい。コールドキーは次のパスに格納されます $HOME/cold-keys

+
+
+
+
+
mkdir $HOME/cold-keys
+
+

コールドキーのペアキーとカウンターファイルを作成します。

+

cd $HOME/cold-keys
+cardano-cli node key-gen \
+    --cold-verification-key-file node.vkey \
+    --cold-signing-key-file node.skey \
+    --operational-certificate-issue-counter node.counter
+
+アクセス権を読み取り専用に更新します。 +
chmod 400 node.vkey
+chmod 400 node.skey
+

+
+
+
+
+

重要

+

すべてのキーを別の安全なストレージデバイス(USB)などにバックアップしましょう!複数のバックアップを作成することをおすすめします。

+
+

3.プール運用証明書の作成

+
+

事前確認

+

ブロックチェーンと完全に同期している必要があります。 同期が途中の場合、正しいslotsPerKESPeriodを取得できません。 あなたのBPノードが完全に同期されたことを確認するには、カルダノエクスプローラーで自身の同期済みエポックとスロットが一致しているかをご確認ください。

+
+
+
+
+

ジェネシスファイルからslotsPerKESPeriodを出力します。 +

cd $NODE_HOME
+slotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')
+echo slotsPerKESPeriod: ${slotsPerKESPeriod}
+
+同期済みslotNoを算出します。 +
slotNo=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo slotNo: ${slotNo}
+

+

startKesPeriodを算出します。

+
kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))
+echo kesPeriod: ${kesPeriod}
+startKesPeriod=${kesPeriod}
+echo startKesPeriod: ${startKesPeriod}
+
+
+
+
+
+

ファイル転送

+

BPのkes.skeykes.vkey をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|kes.skey / kes.vkey| B[エアギャップ];

+
+

BPとエアギャップでkes.vkeyファイルハッシュを比較する

+
+
+
+
cd $NODE_HOME
+sha256sum kes.vkey
+
+
+
+
+
+

BPとエアギャップで表示された戻り値を比較して、ハッシュ値が一致していればOK

+
+
+
+
+
cd $NODE_HOME
+sha256sum kes.vkey
+
+
+
+
+
+

確認

+

ステークプールオペレータは、プールを実行する権限があることを確認するための運用証明書を発行する必要があります。証明書には、オペレータの署名が含まれプールに関する情報(アドレス、キーなど)が含まれます。

+
+
+
+
+
cd $NODE_HOME
+read -p "BPで算出したstartKesPeriodを入力してください:" kes
+
+
+

↑このままコマンドに入力してください
+コマンド実行後に、数字入力モードになりますので
+そこでBPで算出したstartKesPeriodの数字を入力します

+
+

入力した数字が戻り値に表示されているか確認し証明書を作成する +

echo "入力した数字は$kesです"
+

+
cardano-cli node issue-op-cert \
+    --kes-verification-key-file kes.vkey \
+    --cold-signing-key-file $HOME/cold-keys/node.skey \
+    --operational-certificate-issue-counter $HOME/cold-keys/node.counter \
+    --kes-period $kes \
+    --out-file node.cert
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのnode.cert をBPのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|node.cert| B[BP];
+
+

** BPとエアギャップでnode.certファイルハッシュを比較する **

+
+
+
+
cd $NODE_HOME
+sha256sum node.cert
+
+
+
+
+
+

BPとエアギャップで表示された戻り値を比較して、ハッシュ値が一致していればOK

+
+
+
+
+
cd $NODE_HOME
+sha256sum node.cert
+
+
+
+
+

4.VRFキーの作成

+
+
+
+
cd $NODE_HOME
+cardano-cli node key-gen-VRF \
+    --verification-key-file vrf.vkey \
+    --signing-key-file vrf.skey
+
+

vrfキーのアクセス権を読み取り専用に更新します。 +

chmod 400 vrf.skey
+chmod 400 vrf.vkey
+

+
+

注意

+

vrfキーを誤って削除しないように注意してください。

+
+
+
+
+

5.BPノードとして再起動

+

BPノードを一旦停止する

+
+
+
+
sudo systemctl stop cardano-node
+
+

ノードポート番号を確認する +

PORT=`grep "PORT=" $NODE_HOME/startBlockProducingNode.sh`
+b_PORT=${PORT#"PORT="}
+echo "BPポートは${b_PORT}です"
+

+
+

↑そのまま実行し、BPのポート番号が表示されることを確認する

+
+

起動スクリプトにKES、VRF、運用証明書のパスを追記し更新します。

+
cat > $NODE_HOME/startBlockProducingNode.sh << EOF 
+#!/bin/bash
+DIRECTORY=$NODE_HOME
+PORT=${b_PORT}
+HOSTADDR=0.0.0.0
+TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
+DB_PATH=\${DIRECTORY}/db
+SOCKET_PATH=\${DIRECTORY}/db/socket
+CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
+SNAPSHOT=43200
+KES=\${DIRECTORY}/kes.skey
+VRF=\${DIRECTORY}/vrf.skey
+CERT=\${DIRECTORY}/node.cert
+/usr/local/bin/cardano-node +RTS -N --disable-delayed-os-memory-return -I0.1 -Iw300 -A32m -n4m -F1.5 -H2500M -T -S -RTS run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG} --shelley-kes-key \${KES} --shelley-vrf-key \${VRF} --shelley-operational-certificate \${CERT} --snapshot-interval \${SNAPSHOT}
+EOF
+
+

BPを起動します。

+
sudo systemctl start cardano-node
+
+

BPとして起動しているか確認する

+
cd $NODE_HOME/scripts
+./gLiveView.sh
+
+

チェーン同期後にCoreの表示があればOK

+
+
+
+
+

注意事項

+

ブロックプロデューサーノードを実行するためには、以下の3つのファイルが必要です。このファイルが揃っていない場合や起動時に指定されていない場合はブロックが生成できません。

+
    +
  • kes.skey
  • +
  • vrf.skey
  • +
  • node.cert
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/5-generate-address/index.html b/setup/5-generate-address/index.html new file mode 100644 index 00000000..8819a67d --- /dev/null +++ b/setup/5-generate-address/index.html @@ -0,0 +1,3207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5.アドレスの作成 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

5.プール運営で使用するアドレスを作成する

+
+

注意

+

プール登録後、以下の手順をやり直しすると変更手続きが面倒になるのでご注意ください。

+
+

1.プロトコルパラメータの取得

+
+
+
+
cd $NODE_HOME
+cardano-cli query protocol-parameters \
+    $NODE_NETWORK \
+    --out-file params.json
+
+
+
+
+
+

運用上のセキュリティに関する重要なアドバイス

+

キーの生成はエアギャップオフラインマシンで生成する必要があり、インターネット接続が無くても生成可能です。
+paymentキーは支払い用アドレスに使用され、stakeキーはプール委任アドレス用の管理に使用されます。

+
+

2.支払いアドレスキーの作成

+
+
+
+
+
+
cd $NODE_HOME
+cardano-cli address key-gen \
+    --verification-key-file payment.vkey \
+    --signing-key-file payment.skey
+
+

3. ステークアドレスキーの作成

+
+
+
+
+
+
cardano-cli stake-address key-gen \
+    --verification-key-file stake.vkey \
+    --signing-key-file stake.skey
+
+

4.ステークアドレスの作成

+
+
+
+
+
+
cardano-cli stake-address build \
+    --stake-verification-key-file stake.vkey \
+    --out-file stake.addr \
+    $NODE_NETWORK
+
+

5.支払い用アドレスの作成

+
+
+
+
+
+
cardano-cli address build \
+    --payment-verification-key-file payment.vkey \
+    --stake-verification-key-file stake.vkey \
+    --out-file payment.addr \
+    $NODE_NETWORK
+
+

上書き・削除されないようパーミッションを変更する。

+
+
+
+
+
+
chmod 400 payment.vkey
+chmod 400 payment.skey
+chmod 400 stake.vkey
+chmod 400 stake.skey
+chmod 400 stake.addr
+chmod 400 payment.addr
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ファイル用途
payment.vkeypaymentアドレス公開鍵
payment.skeypaymentアドレス秘密鍵
payment.addrpaymentアドレスファイル
stake.vkeyステークアドレス公開鍵
stake.skeyステークアドレス秘密鍵
stake.addrステークアドレスファイル
+
+

注意

+

これらのファイルは紛失しないようにご注意ください。特に.vkey/.skeyを無くした場合、プール報酬や誓約金を引き出せなくなります。複数の外部デバイスにバックアップを取ってください。

+
+ + +

6.支払い用アドレスに入金する

+

次のステップは、あなたの支払いアドレスに送金する手順です。

+
+

ファイル転送

+

エアギャップマシンのpayment.addrstake.addr をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|payment.addr / stake.addr| B[BP];

+
+
+
+
+
+

以下のウォレットから送金が可能です

+
    +
  • ダイダロス / ヨロイウォレット / nami / ccvault.io
  • +
+
+

支払いアドレスを表示させ、このアドレスに送金します。

+
echo "$(cat $NODE_HOME/payment.addr)"
+
+
+

何ADA入金したらいい?

+

初回はテストで少額から入金してください

+

payment.addrは以下の役割があるため必要分入金してください
+●プール登録料の支払い(500ADA)
+●ステークアドレス登録料の支払い(2ADA)
+●トランザクション手数料の支払い(数ADA)
+●誓約金の預け先(誓約として設定したい額)

+
+
+
+
+

テストネット用ADAの請求

+

テストネット用口座にあなたの支払い用アドレスをリクエストします。
+テストネット用口座は24時間ごとに1000tADAを提供します。

+
+

次のコードを実行し。支払いアドレスを表示させます。

+
echo "$(cat $NODE_HOME/payment.addr)"
+
+

このアドレスを上記ページのリクエスト欄に貼り付けます。

+
+
+
+

支払い用アドレスに送金後、残高を確認してください。

+
+

ノードをブロックチェーンと完全に同期させる必要があります。完全に同期されていない場合は、残高が表示されません。

+
+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK
+
+

次のように表示されたら入金完了です。

+
                        TxHash                                 TxIx        Lovelace
+----------------------------------------------------------------------------------------
+100322a39d02c2ead....                                              0        1000000000
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/6-register-stakeaddress/index.html b/setup/6-register-stakeaddress/index.html new file mode 100644 index 00000000..8791260d --- /dev/null +++ b/setup/6-register-stakeaddress/index.html @@ -0,0 +1,2926 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6.ステークアドレスの登録 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+ +
+ + + +
+ + + + + + + +
+ + + + + + + + +

6.ステークアドレスの登録

+

1.ステーク証明書を作成する

+
+
+
+
cd $NODE_HOME
+cardano-cli stake-address registration-certificate \
+    --stake-verification-key-file stake.vkey \
+    --out-file stake.cert
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのstake.cert をBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|stake.cert| B[BP];

+
+

2.ステークアドレスを登録する

+
+

ステークアドレスの登録には2000000 lovelace (2ADA)が必要です。

+
+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

payment.addrの残高を出力します。

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

keyDepositの値を出力します。

+
+
+
+
keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakeAddressDeposit')
+echo keyDeposit: $keyDeposit
+
+
+
+
+

トランザクション仮ファイルを作成します

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+0 \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --out-file tx.tmp \
+    --certificate stake.cert
+
+
+
+
+

現在の最低手数料を計算します。

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 2 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

計算結果を出力します。

+
+
+
+
txOut=$((${total_balance}-${keyDeposit}-${fee}))
+echo Change Output: ${txOut}
+
+
+
+
+

ステークアドレスを登録するトランザクションファイルを作成します。

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --certificate-file stake.cert \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.rawをエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];

+
+

paymentとstakeの秘密鍵でトランザクションファイルに署名します。

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのtx.signedをBPのcnodeディレクトリにコピーします。

+
graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];
+
+

署名されたトランザクションを送信します。

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/7-register-stakepool/index.html b/setup/7-register-stakepool/index.html new file mode 100644 index 00000000..8d8a501b --- /dev/null +++ b/setup/7-register-stakepool/index.html @@ -0,0 +1,3305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.ステークプールの登録 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

7.ステークプールの登録

+
+

概要

+

こちらの手順は初回プール登録時のみ有効です。
+プール登録後にメタ情報、誓約、固定費、変動費、リレー情報を変更する場合は、プール情報(pool.cert)の更新の変更手順を実施してください。

+
+
+

プール登録料

+

ステークプール登録には500ADAの登録料が必要です。payment.addrに入金されている必要があります。

+
+

1.メタデータの作成

+
+

ホームページを持っていない場合

+

「jsonファイルをGithubでホストする方法」を実施してください

+
+
+
+
+
+

1.Githubアカウントを作成しログインします https://github.com/
+ ユーザー名を最大13文字以内で作成してください

+

2.Repositoriesタブをクリックし、右上のNew をクリックします。

+

3.リポジトリ作成

+
    +
  • Repository nameに任意のリポジトリ名(最大13文字以内)を入力
  • +
  • Publicを選択
  • +
  • Create repositoryをクリック
  • +
+

+

4.小さい文字で書かれた"creating a new file"をクリックします。

+

+

5.ファイル名を poolMetaData.json として入力し json コンテンツを貼り付けます。

+

+
{
+"name": "MyPoolName",
+"description": "My pool description",
+"ticker": "MPN",
+"homepage": "https://myadapoolnamerocks.com"
+}
+
+
+

作成時の注意

+
    +
  • 下記は参考フォーマットとなります。ご自身のプール名、Ticker名に書き換えてください
  • +
  • まだhomepageアドレスが無い場合は、ご自身のTwitterアドレスでも大丈夫です。
  • +
  • ticker名の長さは3~5文字以内で、A-Zと0-9のみで構成する必要があります。
  • +
  • descriptionの長さは255文字以内(255byte)となります。(ひらがな、漢字、カタカナは1文字2byte)
  • +
+
+

6.Commit Changes...をクリックします。

+

+

+

7.上部のメニュータブからSettingsをクリックします

+

+

8.GitPages設定

+
    +
  • 左メニューからPagesをクリックします。
  • +
  • Branchのプルダウンからmain /rootを選択する
  • +
  • Saveをクリックします
  • +
+

+

9.URLの生成

+
    +
  • 左メニューからPagesをクリックします。
  • +
  • 上部にこのリポジトリの公開URLが表示されたことを確認します
  • +
  • 赤枠のURLをコピーします
  • +
+

+

10.メタデータURLの生成

+

9でコピーしたURLにpoolMetaData.jsonを繋げます

+
+

例)https://btbf.github.io/sjg/poolMetaData.json

+
+

このURLの文字列が64文字以内であることを確認してください

+

11.ブロックプロデューサーノードでjsonファイルをダウンロードし、ハッシュ値を計算する。

+
+

URLを書き換えてから実行して下さい

+

10で作成したメタデータURLを用いて下さい。

+
+
cd $NODE_HOME
+wget -O poolMetaData.json https://xxx.github.io/xxx/poolMetaData.json 
+
+
+
+
+
+
+

下記は参考フォーマットとなります。ご自身のプール名、Ticker名に書き換えてください

+
+
+

作成ルール

+

ticker名の長さは3~5文字にする必要があります。文字はA-Zと0-9のみで構成する必要があります。
+descriptionの長さは255文字以内(255byte)となります。(ひらがな、漢字、カタカナは1文字2byte)

+
+

メタデータファイルを作成する。

+
+
+
+
cd $NODE_HOME
+cat > poolMetaData.json << EOF
+{
+"name": "MyPoolName",
+"description": "My pool description",
+"ticker": "MPN",
+"homepage": "https://myadapoolnamerocks.com"
+}
+EOF
+
+
+
+
+
+

注意

+

poolMetaData.jsonをあなたの公開用WEBサーバへアップロードしてください。

+
+
+
+
+
+

メタデータJSONをチェックする +

cat $NODE_HOME/poolMetaData.json | jq .
+

+
+

戻り値にエラーが表示される場合

+

戻り価にparse error:が表示される場合は、JSON構文に誤りがあります。 +作成したメタデータJSONファイルをご確認ください。

+
+

メタデータファイルのハッシュ値を計算します。

+
+
+
+
cd $NODE_HOME
+cardano-cli stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt
+
+
+
+
+

2.プール登録証明書の作成

+
+

ファイル転送

+

BPにあるvrf.vkeypoolMetaDataHash.txt をエアギャップマシンのcnodeディレクトリにコピーします。 +

graph LR
+    A[BP] -->| vrf.vkey / poolMetaDataHash.txt | B[エアギャップ];

+
+

** BPとエアギャップでvrf.vkeyファイルハッシュを比較する **

+
+
+
+
cd $NODE_HOME
+sha256sum vrf.vkey
+
+
+
+
+
+

BPとエアギャップで表示された戻り値を比較して、ハッシュ値が一致していればOK

+
+
+
+
+
cd $NODE_HOME
+sha256sum vrf.vkey
+
+
+
+
+

最小プールコスト(最低固定費)を出力します。

+
+
+
+
minPoolCost=$(cat $NODE_HOME/params.json | jq -r .minPoolCost)
+echo minPoolCost: ${minPoolCost}
+
+
+
+
+
+

minPoolCost(最低固定費)は 170000000 lovelace (170 ADA)です。

+
+

エアギャップマシンでpool.certを作成する

+
+

pool.cert作成時の注意点▼

+

pool.certはプール登録証明書の役割を果たし、プール情報を記載します。サンプルコードは以下の値に設定されています。

+
    +
  • 誓約 100ADA  (--pool-pledge)  注釈→(1)
  • +
  • 固定手数料 170ADA (--pool-cost)  注釈→(2)
  • +
  • 変動手数料5% (--pool-margin)  注釈→(3)
  • +
+
+
    +
  1. 🙋‍♂️ 誓約(Pledge)とは?
    Pledge(誓約)はシビル攻撃を防ぐ目的で導入されているパラメータで、SPOが自身のプールにADAをより預けることで委任者様の報酬が若干多く分配される設計になっており、複数プールを開設するよりも単一プールでの運営メリット促すために設けられた制度です。2022/02/16時点でのPledge(誓約)の設計は、SPOが差し出すADA(Pledge)が10M ADA以上からじゃないと報酬が増える割合が変わらないため、あまり機能していないのが実情です。(現在改良が検討されています)
  2. +
  3. 🙋‍♂️ 固定手数料(cost)とは?
    プール運営におけるオペレーター報酬の1つで、最低170ADAから設定可能
  4. +
  5. 🙋‍♂️ 変動手数料(margin)とは?
    プール運営におけるオペレーター報酬の1つで (総報酬-固定手数料費)におけるオペレーター報酬率
  6. +
+
+誓約(Pledge)について▼ +

自分のプールに保証金を預けることをPledge(誓約)と呼びます

+
    +
  • 支払い用アドレス(payment.addr)の残高はPledge額よりも大きい必要があります。
  • +
  • 誓約金はpayment.addrに入金されている必要があります。
  • +
  • 設定した誓約数よりpayment.addrに入金されてるADAが下回っている場合、プール報酬が0になります。
  • +
  • 誓約金はロックされません。いつでも自由に取り出せますがプール登録証明書を再提出する必要があります。
  • +
+
+
+リレー(--pool-relay-ipv4)の記述について▼ +

上記のpool.cert作成時、自身のリレー情報を以下の3パターンの記述方法があります。

+

複数のリレーノードを構成する記述方法

+

IPアドレス方式: 1ノード1IPアドレスの場合(分からない場合はこちら)
+[xxx.xxx.xxx]をリレーノードのパブリックIP(静的)アドレスへ書き換え +

    --pool-relay-ipv4 xxx.xxx.xxx \
+    --pool-relay-port 6000 \
+    --pool-relay-ipv4 xxx.xxx.xxx \
+    --pool-relay-port 6000 \
+

+

DNS方式:1つのエントリーの場合
+[relay1.yourdomain.com]をあなたのドメイン名に書き換え +

    --single-host-pool-relay relay1.yourdomain.com \
+    --pool-relay-port 6000 \
+    --single-host-pool-relay relay2.yourdomain.com \
+    --pool-relay-port 6000 \
+

+

ラウンドロビンDNSベース SRV DNS recordの場合
+[relay.yourdomain.com]をあなたのドメイン名に書き換え +

    --multi-host-pool-relay relay.yourdomain.com \
+    --pool-relay-port 6000 \
+

+
+
+
+
+

下記のスクリプトは例です。ご自身のプール運用設定値に変更してから実行してください。

+
+

値を変更する

+

--pool-pledge 誓約数
+--pool-cost 固定手数料
+--pool-margin 変動手数料
+***.***.***.***はリレー1のIPに置き換えてください
+https://xxx.github.io/xxx/poolMetaData.json はご自身のメタデータURLに置き換えてください

+
+
cd $NODE_HOME
+cardano-cli stake-pool registration-certificate \
+    --cold-verification-key-file $HOME/cold-keys/node.vkey \
+    --vrf-verification-key-file vrf.vkey \
+    --pool-pledge 100000000 \
+    --pool-cost 170000000 \
+    --pool-margin 0.05 \
+    --pool-reward-account-verification-key-file stake.vkey \
+    --pool-owner-stake-verification-key-file stake.vkey \
+    $NODE_NETWORK \
+    --pool-relay-ipv4 ***.***.***.*** \
+    --pool-relay-port 6000 \
+    --metadata-url https://xxx.github.io/xxx/poolMetaData.json \
+    --metadata-hash $(cat poolMetaDataHash.txt) \
+    --out-file pool.cert
+
+
+
+

下記のスクリプトは例です。ご自身のプール運用設定値に変更してから実行してください。

+
+

値を変更する

+

--pool-pledge 誓約数
+--pool-cost 固定手数料
+--pool-margin 変動手数料
+***.***.***.***はリレー1、リレー2のIPに置き換えてください
+https://xxx.github.io/xxx/poolMetaData.json はご自身のメタデータURLに置き換えてください

+
+
cd $NODE_HOME
+cardano-cli stake-pool registration-certificate \
+    --cold-verification-key-file $HOME/cold-keys/node.vkey \
+    --vrf-verification-key-file vrf.vkey \
+    --pool-pledge 100000000 \
+    --pool-cost 170000000 \
+    --pool-margin 0.05 \
+    --pool-reward-account-verification-key-file stake.vkey \
+    --pool-owner-stake-verification-key-file stake.vkey \
+    $NODE_NETWORK \
+    --pool-relay-ipv4 ***.***.***.*** \
+    --pool-relay-port 6000 \
+    --pool-relay-ipv4 ***.***.***.*** \
+    --pool-relay-port 6000 \
+    --metadata-url https://xxx.github.io/xxx/poolMetaData.json \
+    --metadata-hash $(cat poolMetaDataHash.txt) \
+    --out-file pool.cert
+
+
+
+
+

自身のステークプールに委任する証明書(deleg.cert)を作成します

+
+
+
+
cardano-cli stake-address delegation-certificate \
+    --stake-verification-key-file stake.vkey \
+    --cold-verification-key-file $HOME/cold-keys/node.vkey \
+    --out-file deleg.cert
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのpool.certdeleg.certをBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|pool.cert / deleg.cert| B[BP];

+
+

3.プール登録トランザクションの送信

+

最新のスロット番号を取得する必要があります

+
+
+
+
cd $NODE_HOME
+currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
+echo Current Slot: $currentSlot
+
+
+
+
+

payment.addrの残高を出力します

+
+
+
+
cardano-cli query utxo \
+    --address $(cat payment.addr) \
+    $NODE_NETWORK > fullUtxo.out
+
+tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out
+
+cat balance.out
+
+
+
+
+

UTXOを算出します

+
+
+
+
tx_in=""
+total_balance=0
+while read -r utxo; do
+    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
+    idx=$(awk '{ print $2 }' <<< "${utxo}")
+    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
+    total_balance=$((${total_balance}+${utxo_balance}))
+    echo TxHash: ${in_addr}#${idx}
+    echo ADA: ${utxo_balance}
+    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
+done < balance.out
+txcnt=$(cat balance.out | wc -l)
+echo Total ADA balance: ${total_balance}
+echo Number of UTXOs: ${txcnt}
+
+
+
+
+

poolDepositを出力します

+
+
+
+
poolDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakePoolDeposit')
+echo poolDeposit: $poolDeposit
+
+
+
+
+

トランザクション仮ファイルを作成します

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+$(( ${total_balance} - ${poolDeposit}))  \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee 0 \
+    --certificate-file pool.cert \
+    --certificate-file deleg.cert \
+    --out-file tx.tmp
+
+
+
+
+

最低手数料を計算します

+
+
+
+
fee=$(cardano-cli transaction calculate-min-fee \
+    --tx-body-file tx.tmp \
+    --tx-in-count ${txcnt} \
+    --tx-out-count 1 \
+    $NODE_NETWORK \
+    --witness-count 3 \
+    --byron-witness-count 0 \
+    --protocol-params-file params.json | awk '{ print $1 }')
+echo fee: $fee
+
+
+
+
+

計算結果を出力します

+
+
+
+
txOut=$((${total_balance}-${poolDeposit}-${fee}))
+echo txOut: ${txOut}
+
+
+
+
+

トランザクションファイルを作成します

+
+
+
+
cardano-cli transaction build-raw \
+    ${tx_in} \
+    --tx-out $(cat payment.addr)+${txOut} \
+    --invalid-hereafter $(( ${currentSlot} + 10000)) \
+    --fee ${fee} \
+    --certificate-file pool.cert \
+    --certificate-file deleg.cert \
+    --out-file tx.raw
+
+
+
+
+
+

ファイル転送

+

BPのtx.rawをエアギャップマシンのcnodeディレクトリにコピーします。

+
graph LR
+    A[BP] -->|tx.raw| B[エアギャップ];
+
+

トランザクションに署名します

+
+
+
+
cd $NODE_HOME
+cardano-cli transaction sign \
+    --tx-body-file tx.raw \
+    --signing-key-file payment.skey \
+    --signing-key-file $HOME/cold-keys/node.skey \
+    --signing-key-file stake.skey \
+    $NODE_NETWORK \
+    --out-file tx.signed
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのtx.signedをBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|tx.signed| B[BP];

+
+

トランザクションを送信します

+
+
+
+
cardano-cli transaction submit \
+    --tx-file tx.signed \
+    $NODE_NETWORK
+
+
+
+
+
+

Transacsion Successfully submittedと表示されれば成功

+
+

4. プール登録確認

+

ステークプールIDは以下のように出力できます

+
+
+
+
chmod u+rwx $HOME/cold-keys
+cardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format bech32 --out-file pool.id-bech32
+cardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format hex --out-file pool.id
+chmod a-rwx $HOME/cold-keys
+
+
+
+
+
+

ファイル転送

+

エアギャップマシンのpool.id-bech32pool.idをBPのcnodeディレクトリにコピーします。 +

graph LR
+    A[エアギャップ] -->|pool.id-bech32 / pool.id| B[BP];

+
+

以下のコマンドを実行し、プール情報が表示されればブロックチェーンに登録されています

+
+
+
+
curl -s -X POST "https://api.koios.rest/api/v0/pool_info" \
+    -H "Accept: application/json" \
+    -H "Content-Type: application/json" \
+    -d '{"_pool_bech32_ids":["'$(cat $NODE_HOME/pool.id-bech32)'"]}' | jq .
+
+
+
+
+

自分のステークプールがCardanoscanに登録されているか確認します

+
+
+
+
cd $NODE_HOME
+cat pool.id-bech32
+
+
+
+
+

表示されたPoolIDであなたのステークプールがブロックチェーンに登録されているか、次のサイトで確認することが出来ます。
+Cardanoscan

+
+

あと一息です!

+

上記サイトであなたのプールティッカーが表示されたらブロックチェーンに登録されました!しかしまだブロック生成できる状態ではありません。この後も重要な作業が続きますがもう少し頑張ってください!

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/8.topology-setup/index.html b/setup/8.topology-setup/index.html new file mode 100644 index 00000000..e828c119 --- /dev/null +++ b/setup/8.topology-setup/index.html @@ -0,0 +1,3185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8.P2Pトポロジー設定 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

8.P2Pトポロジー設定

+
+

前提条件

+

この項目はリレーノードで実施します
+リレーノードが起動しているか確認してください** +

journalctl --unit=cardano-node --follow
+

+
+
+

重要:トポロジーの形成について

+

2022/01/07時点では手動P2P(ピア・ツー・ピア)モードのため、手動でトポロジーを構成する必要があります。この手順をスキップすると生成したブロックがブロックチェーン外で孤立するため、必須の設定項目となります。

+
+

TopologyUpdaterの設定

+ + + + + + + + + + + + + + + + + +
ファイル用途
topologyUpdater.shトポロジーフェッチリスト登録スクリプト
relay-topology_pull.shトポロジーファイル生成スクリプト
+

ノード情報をトポロジーフェッチリストに登録するスクリプト「topologyUpdater.sh」を作成します。

+
+

topologyUpdater.shについて

+

リレーノード情報(IPアドレスとポート番号、オン/オフライン状態)をトポロジーフェッチリストへ1時間に1回送信することで、世界中のリレーノードに自プールのリレー情報が登録される仕組みです

+
+

スクリプトファイルの作成

+
+

注意

+

以下は、リレーノードのパブリックIPとノードポートに合わせる
+CNODE_HOSTNAMEの「xxx.xxx.xxx.xx」はリレーのパブリックIP(静的)アドレスに置き換えて下さい +ポート番号を6000から変更している場合は修正してください +※26行目の"CHANGE ME"は変更しないでください

+
+
+
+
+
cat > $NODE_HOME/topologyUpdater.sh << EOF
+#!/bin/bash
+# shellcheck disable=SC2086,SC2034
+
+USERNAME=$(whoami)
+CNODE_PORT=6000
+CNODE_HOSTNAME="xxx.xxx.xxx.xx"
+CNODE_BIN="/usr/local/bin"
+CNODE_HOME=$NODE_HOME
+CNODE_LOG_DIR="\${CNODE_HOME}/logs"
+GENESIS_JSON="\${CNODE_HOME}/${NODE_CONFIG}-shelley-genesis.json"
+NETWORKID=\$(jq -r .networkId \$GENESIS_JSON)
+CNODE_VALENCY=1   # optional for multi-IP hostnames
+NWMAGIC=\$(jq -r .networkMagic < \$GENESIS_JSON)
+[[ "\${NETWORKID}" = "Mainnet" ]] && HASH_IDENTIFIER="--mainnet" || HASH_IDENTIFIER="--testnet-magic \${NWMAGIC}"
+[[ "\${NWMAGIC}" = "764824073" ]] && NETWORK_IDENTIFIER="--mainnet" || NETWORK_IDENTIFIER="--testnet-magic \${NWMAGIC}"
+
+export PATH="\${CNODE_BIN}:\${PATH}"
+export CARDANO_NODE_SOCKET_PATH="\${CNODE_HOME}/db/socket"
+
+blockNo=\$(/usr/local/bin/cardano-cli query tip \${NETWORK_IDENTIFIER} | jq -r .block )
+
+# Note:
+# if you run your node in IPv4/IPv6 dual stack network configuration and want announced the
+# IPv4 address only please add the -4 parameter to the curl command below  (curl -4 -s ...)
+if [ "\${CNODE_HOSTNAME}" != "CHANGE ME" ]; then
+T_HOSTNAME="&hostname=\${CNODE_HOSTNAME}"
+else
+T_HOSTNAME=''
+fi
+
+if [ ! -d \${CNODE_LOG_DIR} ]; then
+mkdir -p \${CNODE_LOG_DIR};
+fi
+
+curl -4 -s "https://api.clio.one/htopology/v1/?port=\${CNODE_PORT}&blockNo=\${blockNo}&valency=\${CNODE_VALENCY}&magic=\${NWMAGIC}\${T_HOSTNAME}" | tee -a \$CNODE_LOG_DIR/topologyUpdater_lastresult.json
+EOF
+
+
+
+
+

権限を追加し、「topologyUpdater.sh」を実行します。

+
+
+
+
cd $NODE_HOME
+chmod +x topologyUpdater.sh
+./topologyUpdater.sh
+
+
+
+
+

topologyUpdater.shが正常に実行された場合、以下の形式が表示されます。

+
+

{ "resultcode": "201", "datetime":"2020-07-28 01:23:45", "clientIp": "1.2.3.4", "iptype": 4, "msg": "nice to meet you" }

+
+
+

注意

+

topologyUpdater.shは1時間以内に2回以上実行しないで下さい。最悪の場合ブラックリストに追加されることがあります。スクリプトが実行されるたびに、$NODE_HOME/logsにログが作成されます。

+
+

Cronジョブの設定

+

crontabジョブを追加し、「topologyUpdater.sh」を1時間に1回自動実行されるように設定します。

+
+

注意

+
    +
  • 以下のコードは複数回実行しないで下さい。複数回実行した場合、同じ時間に複数自動実行されるスケジュールが登録されてしまうので、ブラックリストに入ります。
  • +
  • 以下のコードは毎時5分に実行されるように指定しています。 + 
  • +
+
+
+
+
+
cat > $NODE_HOME/crontab-fragment.txt << EOF
+5 * * * * ${NODE_HOME}/topologyUpdater.sh
+EOF
+crontab -l | cat - crontab-fragment.txt >crontab.txt && crontab crontab.txt
+rm crontab-fragment.txt
+
+
+

no crontab for ~~ +というメッセージが表示されることがありますが、Cron初回設定時に表示されるメッセージとなりますので、問題ありません。

+
+

crontab -l
+
+以下が返り値として表示されればOK。

+
+

"5 * * * * /home/***/cnode/topologyUpdater.sh"

+
+
+

フェッチリストへの登録について

+

4時間の間で4回スクリプトが実行された後に、ノードがオンライン状態で有ることが認められた場合にノードIPがトポロジーフェッチリストに登録されます。上記設定から4時間後に次の項目を実施してください。

+
+
+
+
+

フェッチリスト登録確認

+
+
+
+
cd $NODE_HOME/logs
+cat topologyUpdater_lastresult.json
+
+
+
+
+

以下の内容が表示されていれば登録成功
+最後の一行が最新のresultcodeになり、400番台・500番台の場合は、サーバ設定に問題があります。 +

{ "resultcode": "201", "datetime":"2021-01-10 18:30:06", "clientIp": "000.000.000.000", "iptype": 4, "msg": "nice to meet you" }
+{ "resultcode": "203", "datetime":"2021-01-10 19:30:03", "clientIp": "000.000.000.000", "iptype": 4, "msg": "welcome to the topology" }
+{ "resultcode": "204", "datetime":"2021-01-10 20:30:04", "clientIp": "000.000.000.000", "iptype": 4, "msg": "glad you're staying with us" }
+

+

トポロジーファイルを生成する

+
+

前提条件

+

リレーノードIPがトポロジーフェッチリストに登録されたことを確認後、以下のセクションを実行して下さい。

+
+
+トポロジーの形成方法▼ +

トポロジーファイルを更新するrelay-topology_pull.shスクリプトを作成します。 +このスクリプトを作成・実行することで、世界中のリレーノード情報の中から自分のリレーノードに対して近距離・中距離・遠距離に分散したリレーノードを抽出し半自動でトポロジーを形成できます。

+
+
+個別に追加したい場合▼ +

※お知り合いのノードや自ノードが複数ある場合は、IOHKノード情報の後に "|" で区切ってIPアドレス:ポート番号:Valency の形式で追加できます。
+

|relays-new.cardano-mainnet.iohk.io:3001:2|relay1-eu.xstakepool.com:3001:1|00.000.000.00:3001:1
+

+
+
+

注意

+

以下は、BPのパブリックIPとノードポートに書き換えてからコマンドを実行する
+BLOCKPRODUCING_IPの「xxx.xxx.xxx」はBPのパブリックIP(静的)アドレスに置き換えて下さい +BLOCKPRODUCING_PORTは任意で設定した番号に置き換えてください。

+
+
+
+
+
cat > $NODE_HOME/relay-topology_pull.sh << EOF
+#!/bin/bash
+BLOCKPRODUCING_IP=xxx.xxx.xxx
+BLOCKPRODUCING_PORT=xxxxx
+PEERS=18
+cp $NODE_HOME/${NODE_CONFIG}-topology.json $NODE_HOME/${NODE_CONFIG}-topology-bk.json
+curl -4 -s -o $NODE_HOME/${NODE_CONFIG}-topology.json "https://api.clio.one/htopology/v1/fetch/?max=\${PEERS}&customPeers=\${BLOCKPRODUCING_IP}:\${BLOCKPRODUCING_PORT}:1|relays-new.cardano-mainnet.iohk.io:3001:2"
+EOF
+
+
+
+
+

shファイルに権限を追加し、relay-topology_pull.shを実行する

+
+
+
+
cd $NODE_HOME
+chmod +x relay-topology_pull.sh
+./relay-topology_pull.sh
+
+
+
+
+
+

relay-topology_pull.shを実行すると新しいトポロジーファイル(mainnet-topology.json)を生成します。

+
+
+

トポロジーファイルを更新した場合は、リレーノードを再起動することを忘れないで下さい。

+
+
+
+
+
sudo systemctl reload-or-restart cardano-node
+
+
+
+
+
+

重要な確認事項

+

ブロックを生成するには、「Total Tx」が増加していることを確認する必要があります。万一、増加していない場合にはファイアウォールやトポロジーファイルの内容を再確認して下さい。「P2P」数はノードが他ノードと接続している数を表しています。

+
+

🛠 リレーノード/BPでgLiveView を確認

+
+
+
+
+
+
cd $NODE_HOME/scripts
+./gLiveView.sh
+
+
+

「Total Tx」が増加しているか確認する

+
+

+
+

おめでとうございます!

+

Total Txの増加が確認できれば、ブロックを作成する準備が出来ています。

+
+

ノード起動最終調整

+

ブロック生成可能状態チェック

+

SPO JAPAN GUILD TOOLを導入する

+

導入手順はプール構築マニュアル内のSJG TOOLをご参照ください

+

TOOLを実行する

+
gtool
+
+
+

[2] ブロック生成状態チェック を選択する

+
+

Tracemempool無効

+
+

重要な最終調整

+

ノード稼働時の、CPU/メモリ消費を抑えるためノード設定を調整します。 +この調整はプール運営のパフォーマンスを左右しますので推奨設定となります。

+
    +
  • トランザクション流入ログをトレース(記録)することで、CPU/メモリ消費を増加させる原因となることがわかっているため、この機能を無効にします。
  • +
  • この設定を行うと、上記で確認した「Total TX」「Pending Tx」は増加しなくなりますが、設定前に増加が確認できていれば問題ございません
  • +
+
+
+
+
+
sed -i $NODE_HOME/${NODE_CONFIG}-config.json \
+    -e "s/TraceMempool\": true/TraceMempool\": false/g"
+
+
+
+
+

** ノードを再起動する ** +

sudo systemctl reload-or-restart cardano-node
+

+

ノードログにエラーが出ていないか確認する +

journalctl --unit=cardano-node --follow
+

+
+

!重要!

+

プール運用マニュアル運用ガイドを必ず確認し、プール運営について学習してください。

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/9-monitoring-tools-setup/index.html b/setup/9-monitoring-tools-setup/index.html new file mode 100644 index 00000000..09a02200 --- /dev/null +++ b/setup/9-monitoring-tools-setup/index.html @@ -0,0 +1,3134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9.監視ツールセットアップ - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

9.監視ツールセットアップ

+

プロメテウスはターゲットに指定したメトリックHTTPエンドポイントをスクレイピングし、情報を収集する監視ツールです。オフィシャルドキュメントはこちら グラファナは収集されたデータを視覚的に表示させるダッシュボードツールです。

+

9-1.インストール

+
+

概要

+

「prometheus」および「prometheus node exporter」をインストールします。 この手順では、リレーノード1でprometheusとGrafana本体を稼働させ、各サーバーの情報を取得する方法です。

+
+

構成図 +

    flowchart TB
+        bp[ローカルPC] -- 3000ポート開放 --> a1[Grafana] 
+        a2[prometheus] -- リレー1IP指定で<br>9100/12798ポート開放 --> ide2[BP] & ide3[リレー2]
+        subgraph ide1[リレー1]
+            a1[Grafana] <--> a2[prometheus]
+        end
+        subgraph ide2[BP]
+            a3[node-exporter]
+        end
+        subgraph ide3[リレー2]
+            a4[node-exporter]
+        end

+

prometheusインストール

+
+
+
+
sudo apt install -y prometheus prometheus-node-exporter
+
+
+
+
sudo apt install -y prometheus-node-exporter
+
+
+
+
+

grafanaインストール

+
+
+
+

sudo apt-get install -y apt-transport-https software-properties-common
+
+
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
+
+
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" > grafana.list
+sudo mv grafana.list /etc/apt/sources.list.d/grafana.list
+
+
sudo apt update && sudo apt install -y grafana
+

+
+
+
+

サービス有効化とファイアウォールを設定する。

+
+
+
+
sudo systemctl enable grafana-server.service
+sudo systemctl enable prometheus.service
+sudo systemctl enable prometheus-node-exporter.service
+
+

FW設定でGrafanaポートを開放する +

sudo ufw allow 3000/tcp
+sudo ufw reload
+

+
+
+
sudo systemctl enable prometheus-node-exporter.service
+
+

FW設定でPrometheusメトリクスポートをリレー1のIP限定で開放する +

sudo ufw allow from <リレーノード1のIP> to any port 12798
+sudo ufw allow from <リレーノード1のIP> to any port 9100
+sudo ufw reload
+

+
+
+
+

prometheus-node-exporterアップデート

+
+
+
+

prometheus-node-exporterのパスを取得する +

cd $HOME/git
+nodeexPath=`which prometheus-node-exporter`
+

+

1.5.0をダウンロードする +

wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz
+

+

ダウンロードファイルを解凍する +

tar xvf node_exporter-1.5.0.linux-amd64.tar.gz
+

+

サービスを停止する +

sudo systemctl stop prometheus-node-exporter.service
+

+

バイナリファイルをシステムフォルダへコピーする +

cd node_exporter-1.5.0.linux-amd64
+sudo cp node_exporter $nodeexPath
+

+

サービスをスタートする +

sudo systemctl start prometheus-node-exporter.service
+

+

バージョン確認

+
prometheus-node-exporter --version
+
+
+

戻り値1行目がnode_exporter, version 1.5.0ならOK

+
+
+
+
+

9-2.設定ファイルの作成

+

リレーノード1にインストールしたPrometheusの設定ファイルを作成します。ここに記載されたサーバーのデータを取得します。

+
+
+
+
+

注意

+

targets:の「xxx.xxx.xxx」は、BPのパブリックIP(静的)アドレスに置き換えて下さい

+
+
cat > $HOME/prometheus.yml << EOF
+global:
+  scrape_interval:     15s # By default, scrape targets every 15 seconds.
+
+  # Attach these labels to any time series or alerts when communicating with
+  # external systems (federation, remote storage, Alertmanager).
+  external_labels:
+    monitor: 'codelab-monitor'
+
+# A scrape configuration containing exactly one endpoint to scrape:
+# Here it's Prometheus itself.
+scrape_configs:
+  # The job name is added as a label job=<job_name> to any timeseries scraped from this config.
+  - job_name: 'prometheus'
+
+    static_configs:
+      - targets: ['localhost:9100']
+        labels:
+          alias: 'relaynode1'
+          type:  'system'
+      - targets: ['xxx.xxx.xxx.xxx:9100']
+        labels:
+          alias: 'block-producing-node'
+          type:  'system'
+      - targets: ['xxx.xxx.xxx.xxx:12798']
+        labels:
+          alias: 'block-producing-node'
+          type:  'cardano-node'
+      - targets: ['localhost:12798']
+        labels:
+          alias: 'relaynode1'
+          type:  'cardano-node'
+EOF
+
+
+
+
+

注意

+

targets:の「xxx.xxx.xxx」は、BPのパブリックIP(静的)アドレスに置き換えて下さい。
+targets:の「bb.xxx.xxx」は、リレー2のパブリックIP(静的)アドレスに置き換えて下さい。

+
+
cat > $HOME/prometheus.yml << EOF
+global:
+  scrape_interval:     15s # By default, scrape targets every 15 seconds.
+
+  # Attach these labels to any time series or alerts when communicating with
+  # external systems (federation, remote storage, Alertmanager).
+  external_labels:
+    monitor: 'codelab-monitor'
+
+# A scrape configuration containing exactly one endpoint to scrape:
+# Here it's Prometheus itself.
+scrape_configs:
+  # The job name is added as a label job=<job_name> to any timeseries scraped from this config.
+  - job_name: 'prometheus'
+
+    static_configs:
+      - targets: ['localhost:9100']
+        labels:
+          alias: 'relaynode1'
+          type:  'system'
+      - targets: ['bb.xxx.xxx.xxx:9100']
+        labels:
+          alias: 'relaynode2'
+          type:  'system'
+      - targets: ['xx.xxx.xxx.xxx:9100']
+        labels:
+          alias: 'block-producing-node'
+          type:  'system'
+      - targets: ['xxx.xxx.xxx.xxx:12798']
+        labels:
+          alias: 'block-producing-node'
+          type:  'cardano-node'
+      - targets: ['localhost:12798']
+        labels:
+          alias: 'relaynode1'
+          type:  'cardano-node'
+      - targets: ['bb.xxx.xxx.xxx:12798']
+        labels:
+          alias: 'relaynode2'
+          type:  'cardano-node'
+EOF
+
+
+
+
+

prometheus.yml構文チェック

+
+
+
+
+
+
sudo promtool check config $HOME/prometheus.yml
+
+
+

戻り値確認

+

構文エラーなしの場合 +

Checking /home/user/prometheus.yml
+SUCCESS: 0 rule files found
+

+

構文エラーの場合(一例) +

Checking /home/user/prometheus.yml
+FAILED: parsing YAML file /home/user/prometheus.yml: yaml: line XX: did not find expected '-' indicator
+

+

※/home/user/prometheus.yml(userは各自で設定したユーザー名)

+

構文エラーだった場合は、$HOME/prometheus.ymlを開いて余分なスペースや記号の有無などを確認し、修正してください。 +

sudo nano $HOME/prometheus.yml
+

+
+

修正したら、Ctrl + Oで保存し、Enter。その後Ctrl + Xで閉じる

+
+
+

prometheus.ymlを移動します +

sudo mv $HOME/prometheus.yml /etc/prometheus/prometheus.yml
+

+

Grafanaプラグインをインストールする +

sudo grafana-cli plugins install yesoreyeram-infinity-datasource
+

+

サービスを起動します。

+
+
+
+
sudo systemctl restart grafana-server.service
+sudo systemctl restart prometheus.service
+sudo systemctl restart prometheus-node-exporter.service
+
+
+
+
+

サービスが正しく実行されていることを確認します。

+
+
+
+
sudo systemctl --no-pager status grafana-server.service prometheus.service prometheus-node-exporter.service
+
+
+

戻り値確認

+
    +
  • grafana-server.service
  • +
  • prometheus.service
  • +
  • prometheus-node-exporter.service
    +上記3つのプログラムが 緑色 active (running) になっていることを確認する。
  • +
+
+
+
+
+

既存の設定ファイルを更新する場合

+
sudo nano /etc/prometheus/prometheus.yml
+
+
+

修正したら、Ctrl + Oで保存し、Enter。その後Ctrl + Xで閉じる

+
+

prometheus.yml構文チェック

+
+
+
+
+
+
sudo promtool check config /etc/prometheus/prometheus.yml
+
+
+

戻り値確認

+

構文エラーなしの場合 +

Checking /etc/prometheus/prometheus.yml
+SUCCESS: 0 rule files found
+

+

構文エラーの場合(一例) +

Checking /etc/prometheus/prometheus.yml
+FAILED: parsing YAML file /etc/prometheus/prometheus.yml: yaml: line XX: did not find expected '-' indicator
+
+/etc/prometheus/prometheus.ymlを開いて余分なスペースや記号の有無などを確認してください。

+
+

サービスを再起動する +

sudo systemctl restart prometheus.service
+

+

9-3.Grafanaダッシュボードの設定

+
    +
  1. ローカルPCのブラウザから http://<リレーノード1IPアドレス>:3000 を開きます。
  2. +
  3. ログイン名・PWは admin / admin
  4. +
  5. パスワードを変更します。
  6. +
  7. 左上の三本線メニューを開き「Connections」→「Data sources」をクリックします。
  8. +
  9. 「Add new data source」をクリックし、「Prometheus」を選択します。
  10. +
  11. 名前は Prometheusとしてください。
  12. +
  13. URLhttp://localhost:9090に設定します。
  14. +
  15. Save & TestをクリックしSuccessfully queried the Prometheus API.と表示されたら再度Data sourcesをクリックします。
  16. +
  17. 「Add new data source」をクリックし、下部にある「Infinity」をクリックします。
  18. +
  19. 設定内容を変更することなく、Save & TestをクリックしSettings savedと表示されたらOK。
  20. +
  21. BPサーバーでパネル用JSONファイルをダウンロードします。
  22. +
+
+
+
+
+
+

curl -s -o $NODE_HOME/SJG_Grafana_Dashboard.json https://raw.githubusercontent.com/akyo3/Extends-SJG-Knowledge/main/SJG_Grafana_Dashboard.json
+
+ 一部ファイル内容を書き換える +
sed -i $NODE_HOME/SJG_Grafana_Dashboard.json \
+    -e "s/bech32_id_of_your_pool/$(cat $NODE_HOME/pool.id-bech32)/g"
+
+12. BPのcnodeフォルダにあるSJG_Grafana_Dashboard.jsonをローカルPCにダウンロードします
+13. 左メニューの「Dashboards」→「New」→「+import」をクリックします。
+14. 「Upload JSON file」をクリックし、10でダウンロードしたSJG_Grafana_Dashboard.jsonを指定します。
+15. 「Prometheus」と「Infinity」のプルダウンを選択しImportボタンをクリックします。

+

Grafana system health dashboard

+
+

🎊おめでとうございます🎊

+

これで基本的な監視設定は完了です。

+

以下の追加設定も実施してください。

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/99-donation-credit/index.html b/setup/99-donation-credit/index.html new file mode 100644 index 00000000..1004ea9d --- /dev/null +++ b/setup/99-donation-credit/index.html @@ -0,0 +1,2843 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 寄付とクレジット - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+ + + + + + + +
+ + + + + + + + +

*寄付とクレジット

+

SPO JAPAN GUILDでは、ステークプール構築マニュアルの整備、コミュニティの運営、ホームページでの認知活動など皆様のプール運営をサポートしております。 +今後もカルダノ分散化を促進するためにも、継続性のある活動を行ってまいります。 +寄付して頂いた資金は、ホームページサーバー代、ドメイン代、開発費、人件費、マーケティング費に使用させていただきます。

+

SPO JAPAN GUILDプールへの委任

+

私達をサポート頂ける方は当プールへ委任頂けますと幸いです。

+
+

Ticker:SJG

+

pool1sqpksswmxpgk6yxllyq9ad4qhtnt5qyz2pv5xmz6kkt5ujrgqwf
+
+ [SJG] SPO JAPAN GUILD POOL
pool1sqpksswmxpgk6yxllyq9ad4qhtnt5qyz2pv5xmz6kkt5ujrgqwf

+
    +
  • 固定手数料:340ADA
  • +
  • 変動手数料:20%~
  • +
+
+

SPO JAPAN GUILDへの寄付

+
+

ADAアドレス

+
addr1qxq6jar2wtktu3nlak78ghugtd8vcxcze33wsk2ehlwkavp2f4gnzre574n6an99yql25wcy09ygededc7e6f77jutvs0lgxef
+
+
+
+

ADA Handle

+

ADA Handle対応ウォレットからなら 「$spojapanguild」宛てでも寄付いただけます!
+

$spojapanguild
+
+

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/air-gap-guid/index.html b/setup/air-gap-guid/index.html new file mode 100644 index 00000000..ba6fa2ab --- /dev/null +++ b/setup/air-gap-guid/index.html @@ -0,0 +1,3765 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + エアギャップマシン作成 - SPO JAPAN GUILD DOCS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+ + + + + + + +
+ + + + + + + + +

エアギャップマシンの作成

+
+

エアギャップマシンとは?

+

プール運営で使用するウォレットの秘密鍵やプール運営の秘密鍵をオフライン上で管理し、エアギャップオフラインマシンでCLIを起動しトランザクションファイルに署名する作業に使用します。

+
    +
  • ウォレットの秘密鍵やプール運営の秘密鍵をプール運営のオンラインマシン上に保管すると、ハッキングなどの際に資金盗難のリスクがあります。
  • +
+
+

Windowsの場合

+
+

貢献者

+

[SA8] SMAN8 さんに導入手順を作成頂きました。ありがとうございます!

+
+

インストール要件

+

環境

+
    +
  • Windows11 Home
  • +
  • 実装RAM 8.00 GB
  • +
+

ダウンロード/インストール

+
    +
  • Ubuntu Desktop 20.04.x LTS
  • +
  • VirtualBox-7.0.4
  • +
+
+

1- OS Ubuntuの入手

+

1-1.下の画像の赤い四角のところをタップしてダウンロードします。

+ +

2-1

+

1-2.ダウンロードしたubuntu-20.04.4-desktop-amd64を作成したフォルダ(ここではTest_CNodeというフォルダ)に移動しておく。

+

4-Ubuntu_download

+

2- VirtualBoxのダウンロード

+

2-1. VirtualBoxのダウンロードサイトにアクセスし、Windows hostsをタップしダウンロードする。

+ +

3- VirtualBoxのインストール

+

3-1.ダウンロードしたvirtualbox6.1.36のインストーラをダブルクリックで起動する。

+ + + + + + + + + + + +
ファイル名
VirtualBox-7.0.4-154605-Win.exe
+

1virtualbox

+

3-2.ダウンロードが完了したら、左下の赤い四角のインストーラーをタップして起動する。

+

2 virtualbox_setup

+

3-3.この画面になったら、Next>をタップ。

+

3 virtualbox_setup

+

3-4.続けてそのままNext>をタップし、画像の順番に進み最後にInstallをクリックする。

+

7 virtualbox_setup

+

3-5.Windowsセキュリティが作動し、デバイスのソフトウェアをインストールしますか?と聞かれたらインストール(I)をタップし、下の画像の赤い四角で囲まれたFinishをタップする。

+

10 virtualbox_setup

+

3-6.VirtualBoxの管理画面が立ち上がり、インストールが完了しました。

+

15

+

4- VirtualBoxの仮想マシンの作成

+

4-1.マシンを作成する為に下の画像の赤い四角の新規(N)をクリックする。

+

16

+

4-2.マシン設定
+名前・・・任意の仮想マシン名
+ISO Imagae・・・1でダウンロードしたUbuntu-ISOファイルを指定する
+「Skip Unattended Installation」にチェックして「次へ」をクリック。

+

VirtualMashine-1

+

4-3.メインメモリを4096MB、Processorosを2に設定し「次へ」をクリック

+

VirtualMashine-2

+

4-4.DiskSizeを50.00GBに設定し「次へ」をクリック

+

VirtualMashine-3

+

4-5.バーチャルマシン作成概要の確認。「完了」をクリック

+

VirtualMashine-4

+

5- VirtualBoxの仮想マシンの環境設定

+

5-1.使用する仮想マシン(ここではAirGap)を選択し、「設定」アイコンをクリックする

+

Setting_Mashine-1

+

一般 +5-2.「一般」→「高度」タブからクリップボードの共有とドラッグ&ドロップを「双方向」に変更してOKをクリック

+

Setting_Mashine-2

+

システム +5-3.「システム」→「マザーボード」タブの「フロッピー」のチェックを外す。チップセットをICH9に変更してOKをクリック

+

Setting_Mashine-3

+

共有フォルダ設定

+

5-4.WindowsとUbuntu間の共有フォルダ(Share)を作成する(ドキュメントフォルダなどの任意の場所)

+

Setting_Mashine-4

+

5-5.共有フォルダーから新規追加アイコンをクリック

+
    +
  • 「フォルダーのパス」に5-4で作成したフォルダを指定する
  • +
  • マウントポイントに/media/share_winを入力する
  • +
  • 「自動マウント」にチェックする
  • +
+

Setting_Mashine-4

+

6- Ubuntuのインストール

+

6-1.起動をクリック。

+

install_ubuntu-1

+

6-2.下の画像のようにディスクが起動し始めます。

+

install_ubuntu-3

+

6-3.左の枠の中から日本語を選択しUbuntuをインストールをクリックします。

+

install_ubuntu-4

+

6-5.日本語キーボードの方は、両方とも「Japanese」を選択し、設定が完了したら「続ける」をクリックします。

+
+

USキーボードの方は「キーボードレイアウト」→「キーボードレイアウトの検出」をクリックして設定してください。 +※ 画面が見切れている場合の対処法:Alt+F7を押すとマウスでウィンドウを移動できます)

+
+

install_ubuntu-5

+

6-6.下の画像の状態のまま、続けるをクリック

+

install_ubuntu-6

+

6-7.下の画像の状態のまま、インストールをクリック。

+

install_ubuntu-7

+

6-8.続けるをクリック。

+

install_ubuntu-8

+

6-9.お住まいの地域をクリックし、続けるをクリック。

+

install_ubuntu-9

+

6-10.あなたの名前はマシン名を入れると、その下のコンピューターの名前ユーザー名の入力にも自動で入力されます。そして、パスワードをご自身で決めて入力を済ませて下さい。終わりましたら、続けるをタップ。

+

install_ubuntu-10

+

6-11.Ubuntuのインストールが始まりました。しばらくお待ちください。

+

install_ubuntu-11

+

6-12.インストール完了後、再起動を行って下さい

+

install_ubuntu-12

+

6-13.ログインします

+

install_ubuntu-13

+

6-14.オンラインアカウントの接続は、右上のスキップ(S)をクリック。

+

install_ubuntu-14

+

6-15.次へをタップします。

+

install_ubuntu-15

+

6-16.そのまま、次へ(N)をタップ。

+

install_ubuntu-16

+

6-17.いいえ、送信しませんを選択し、右上の次へ(N)をタップします。

+

install_ubuntu-17

+

6-18.インストールが終わりました。完了をクリック。

+

install_ubuntu-18

+

6-19.新バージョンは「アップグレードしない」をクリックします

+

install_ubuntu20

+

6-20.OKをクリック。

+

install_ubuntu21

+

6-21.この操作を今すぐ実行をクリック。

+

install_ubuntu21

+

6-22.インストールをクリック。

+

install_ubuntu21

+

6-23.インストールをクリック。

+

install_ubuntu21

+

6-23.インストール完了後全体に適用するをクリックし閉じる

+

install_ubuntu21

+

7- Guest Additionsのインストール

+

アプリ一覧からターミナル(端末)を起動し以下コマンドを手動入力する。 +

sudo apt update -y
+sudo apt upgrade -y
+sudo apt install gcc make perl -y
+

+
+

まだコピーアンドペーストが利用できないため、タイプミスに留意してください。

+
+

7-1.ホストメイン画面上部の「Devices」タブから「Insert Guest Additions CD image...」⇒OKをクリックします。

+

共有フォルダ_5

+

7-2.以下のメッセージが表示されたら実行をクリックした後、パスワードを入力します。

+

共有フォルダ_6

+

7-3処理完了のメッセージが表示されましたらEnterキーをタップします。

+

共有フォルダ_7

+

7-4.ターミナル(端末)を起動しユーザーをグループ化するコマンドを実行。

+

sudo adduser $USER vboxsf
+
+共有フォルダ_6

+

7-5.フォルダにshere_winが表示されていれば、5の「共有フォルダ」で設定したローカルPCのフォルダと同期します。

+

共有フォルダ_6

+

7-6.コピー&ペーストできるかホストPCでコマンドをコピーしてゲストOSの端末で右クリックして貼り付けしてみる。問題なければ、これで終了です。お疲れ様でした!

+

コピ&ペイスト-7

+

7-7.「表示」→「Auto-resize Guest Display」にチェックが入っている事を確認します。

+

共有フォルダ_6

+
+

上記手順を行なっても、「共有フォルダが表示されない」「共有フォルダ化されていない」場合は、一度VBox_GAs_6.1.36をアンマウントしてから再度挿入し、再起動すると共有フォルダは完了します。それでもダメならGUI操作でGuest Additionsがインストールできなかった場合を試してください。

+

8- Swapファイルの作成

+

8-1. 既存Swapファイルを削除
+

sudo swapoff /swapfile
+
+
sudo rm /swapfile
+

+
+

8-2. 新規Swapファイルを作成
+

cd $HOME
+sudo fallocate -l 6G /swapfile
+
+
sudo chmod 600 /swapfile
+
+
sudo mkswap /swapfile
+sudo swapon /swapfile
+sudo swapon --show
+
+
sudo cp /etc/fstab /etc/fstab.bak
+echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
+echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
+echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf
+cat /proc/sys/vm/vfs_cache_pressure
+cat /proc/sys/vm/swappiness
+

+

Macの場合

+
+

貢献者

+

[AKYO] AKYO Akyoさんに導入手順を作成頂きました。ありがとうございます!

+
+

インストール要件

+

環境 +- macOS Ventura version13.0

+

ダウンロード/インストール +- VirtualBox バージョン 7.0.4 +- Ubuntu Desktop 20.04.5 LTS (Focal Fossa)

+
+

1- Ubuntuイメージファイルのダウンロード

+

1-1. 以下のリンク先からISOイメージファイルをダウンロードします。

+
    +
  • Ubuntuを入手する +※ ダウンロード完了まで少しかかるのでしばらくお待ちください
  • +
+ + + + + + + + + + + + + +
ファイル名ubuntu-20.04.5-desktop-amd64.iso
+

UbuntuInstall-1

+
+

2- VirtualBoxのダウンロード/インストール

+

2-1. 以下のリンク先からVirtualBoxをインストールします。

+ + + + + + + + + + + + + + +
ファイル名VirtualBox-7.0.4-154605-OSX.dmg
+

VirtualBoxInstall-1

+
+

2-2. ダウンロードしたファイルをクリックし、インストールウィザードに従ってインストールします。 +完了したら「閉じる」をクリックして終了します。

+
+

macOS BigSur 以降では、インストールしたカーネル拡張をロードできるようにするために再起動が必要です。

+
+

VirtualBoxInstall-2

+
+

3- VirtualBoxで仮想マシンを作成

+
+

VirtualBoxのアイコンをクリックし、起動します。

+
+

3-1. VirtualBoxが起動したら「新規」をクリックします。

+

UbuntuVMCreate-1

+
+

3-2. 以下の項目を設定し、「続き」をクリックします。

+
+

※ 名前はお好みで入力してください。 +ISO Imageは、「その他」を選択し、ダウンロードしたUbuntu-20.04.5のISOイメージファイルを選択します。
+タイプ、バージョンについては上記を選択すればデフォルトで設定されます。
+Skip Unattended Installationにチェック

+
+ + + + + + + + + + + + + +
名前airGap
FolderデフォルトでOK
+

UbuntuVMCreate-2

+
+

3-3. 仮想マシンに割当てるメモリサイズは「4096MB」、Processorsは「2」を選択し「次へ」をクリックします。

+

UbuntuVMCreate-3

+
+

3-4. Virtual Hard diskは「50GB」を入力し、「次へ」をクリックします。

+

UbuntuVMCreate-7

+

3-5. 概要を確認して「完了」をクリックします。

+

UbuntuVMCreate-7

+
+

4- 仮想マシンの仕様設定

+
+

「完了」をクリックしたら「Oracle VM VirtualBox マネージャー」画面に遷移するので設定毎に「設定」をクリックしてください。

+
+

一般

+

4-1. 「設定」→「一般」→「高度」タブから、以下の設定を「双方向」にし、「OK」をクリックします。

+

UbuntuSpecSettings-2

+
+

システム

+

4-2. 「マザーボード」タブを以下の設定にし、「OK」をクリックします。

+ + + + + + + + + + + + + + + + + + + + + +
マザーボード
起動順序「フロッピー」のチェックマークを外す
チップセットICH9
ポインティングデバイスPS/2マウス
+

UbuntuSpecSettings-3

+
+

ディスプレイ

+

4-3. 「スクリーン」タブから以下の設定にし、「OK」をクリックします。

+ + + + + + + + + + + + + + + + + +
ビデオメモリー128MB
表示倍率200%
グラフィックスコントローラーVMSVGA
+

UbuntuSpecSettings-4

+
+

共有フォルダー

+

4-4. ホスト側で共有させたいフォルダを事前に作成しておきます。 +- 例)「airGap」フォルダを作成後、配下に「share」フォルダを作成。

+

Mac Terminal +

mkdir -p $HOME/airGap/share
+

+
+

4-5. 共有フォルダを指定します。

+

UbuntuSpecSettings-6

+
+

5- 仮想マシンにUbuntuをインストール

+

5-1. 仮想マシンを起動します。

+

BootVirtualMachine-1

+
+

PCから権限許可を求められたら「セキュリティとプライバシー」にて必要な権限を許可し、VirtualBoxを再起動します。

+
+
+

5-2. 読み込み終了後、言語は「日本語」にし、「Install Ubuntu」をクリックします。

+

BootVirtualMachine-2

+
+

5-3. キーボード設定では、日本語キーボードの方は、両方とも「Japanese」を選択し、設定が完了したら「続ける」をクリックします。

+
+

USキーボードの方は「キーボードレイアウト」→「キーボードレイアウトの検出」をクリックして設定してください。
+※ 画面が見切れていた場合の対処法:Alt+F7で移動できます)

+
+
+

5-4. 「アップデートと他のソフトウェア」の設定では、以下のように設定し、「続ける」をクリックします。

+

BootVirtualMachine-3

+
+

5-5. 「インストールの種類」の設定では「ディスクを削除してUbuntuをインストール」を選択し、「インストール」をクリックします。

+

BootVirtualMachine-4

+
+

5-6. 「ディスクに変更を書き込みますか?」の設定では「続ける」をクリックします。

+

BootVirtualMachine-5

+
+

5-7. タイムゾーンの設定は、「Tokyo」を選択し、「続ける」をクリックします。

+

BootVirtualMachine-6

+
+

5-8. 必要な情報を入力し、「続ける」をクリックします。

+
+

※ 画像は一例ですのでお好みで設定してください。

+
+

BootVirtualMachine-7

+
+

5-9. インストール開始。

+

BootVirtualMachine-8

+
+

5-10. インストール完了後、VMの再起動を求められるので「今すぐ再起動する」をクリックし、Enterキーを押下します。

+

BootVirtualMachine-9

+
+

5-11. 再起動後、ユーザー名をクリックし、パスワードを入力してログインします。

+
+

5-12. 「オンラインアカウントへの接続」の設定では右上の「スキップ」をクリックします。

+

BootVirtualMachine-10

+
+

5-13. 「Livepatch」の設定では右上の「次へ」をクリックします。

+

BootVirtualMachine-11

+
+

5-14. 「Ubuntuの改善を支援する」の設定では、「いいえ、送信しません」を選択後、右上の「次へ」をクリックします。

+

BootVirtualMachine-12

+
+

5-15. 「プライバシー」の設定では右上の「次へ」をクリックします。

+

BootVirtualMachine-13

+
+

5-16. 「準備完了」と表示されたら右上の「完了」をクリックします。

+

BootVirtualMachine-14

+
+

5-17. 「ソフトウェアの更新」を求められたら「アップグレードしない」をクリックし、その後「OK」をクリックします。

+

BootVirtualMachine-14

+
+

5-18. 「アップデート情報→不完全な言語サポート」が表示されたら「この操作を今すぐ実行する」→「インストール」をクリック後、認証を求められるのでパスワードを入力し、「システム全体に適用」をクリックします。

+

BootVirtualMachine-14

+
+

6- Guest Additionsのインストール

+

6-1. ターミナルを開いて以下を実行します。

+
+

Guest Additionsがインストールされていない状態なのでホストからゲストにコピーアンドペーストできません。タイプミスに留意してください。
+また以下の手順を行なっても、共有フォルダがGUIで表示されない、共有フォルダ化されていない場合は、一度VBox_GAs_6.1.36をアンマウントしてから再度挿入し、再起動すると共有フォルダは完了します。
+それでもダメならGUI操作でGuest Additionsがインストールできなかった場合を試してください。 +

sudo apt update -y
+sudo apt upgrade -y
+sudo apt install gcc make perl -y
+

+
+
+

6-2. ホストメイン画面上部の「Devices」タブから「Insert Guest Additions CD image...」→「OK」をクリックします。

+
+

6-3. 以下のメッセージが表示されたら「実行」をクリックした後、パスワードを入力します。

+

BootVirtualMachine-15

+
+

6-4. 処理完了のメッセージが表示されたらEnterキーを押下します。

+
+

画面が点滅した場合は、リサイズが行われているのでそのまま少し待っていると点滅しなくなるはずです。

+
+

BootVirtualMachine-16

+
+

6-5. ユーザーをvboxsfグループに追加して再起動します。 +

sudo adduser $USER vboxsf
+sudo reboot
+

+
+

6-6. 「View」→「Auto-resize Guest Display」にチェックが入っている事を確認します。

+
+

確認後、右クリック→「取り出す」をクリックします。

+
+

BootVirtualMachine-18

+
+

6-7. テストファイル作成
+ターミナルを開いて以下を実行します。

+
+

共有フォルダにテストファイルを作成してホスト側で確認できたら成功です。

+
+
touch /media/sf_share/test.txt
+ls /media/sf_share/
+
+

実行結果としてVMとホストにtest.txtが作成されていることを確認します。 +BootVirtualMachine-18

+
+

6- Swapファイルの作成

+

6-1. 既存Swapファイルを削除
+

sudo swapoff /swapfile
+
+
sudo rm /swapfile
+

+
+

6-2. 新規Swapファイルを作成
+

cd $HOME
+sudo fallocate -l 6G /swapfile
+
+
sudo chmod 600 /swapfile
+
+
sudo mkswap /swapfile
+sudo swapon /swapfile
+sudo swapon --show
+
+
sudo cp /etc/fstab /etc/fstab.bak
+echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
+echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
+echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf
+cat /proc/sys/vm/vfs_cache_pressure
+cat /proc/sys/vm/swappiness
+

+
+

補足

+

本番運用で使用する際の注意点

+ +

BootVirtualMachine-21

+

GUI操作でGuest Additionsがインストールできなかった場合

+

Virtualbox guest addition packagesをインストールします。

+
+

ターミナルを開いて以下のコマンドを実行してください。
+Guest Additionsがインストールされていない状態なのでホストからゲストにコピーアンドペーストできません。タイプミスに留意してください。
+成功していれば再起動後、コピーアンドペーストできます。 +

sudo apt update -y
+sudo apt upgrade -y
+sudo add-apt-repository multiverse
+sudo apt install virtualbox-guest-dkms virtualbox-guest-x11 -y
+

+
+

ユーザーをvboxsfグループに追加して再起動します。 +

sudo adduser $USER vboxsf
+sudo reboot
+

+

共有フォルダが追加されているか確認 +

df
+

+
+

share 488245288 203122832 285122456 42% /media/sf_share

+
+

共有フォルダのグループを確認 +

ls -l /media
+

+
+

drwxrwx--- 1 root vboxsf 96 x月 xx xx:xx sf_share

+
+

テストファイル作成

+
+

共有フォルダにテストファイルを作成してホスト側で確認できたら成功です。

+
+
touch /media/sf_share/test.txt
+ls /media/sf_share/
+
+

実行結果としてVMとホストにtest.txtが作成されていることを確認します。 +BootVirtualMachine-18

+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..6fab77f9 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,223 @@ + + + + https://docs.spojapanguild.net/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/changelogs/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/contributors/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/learning/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/faq/blocklog/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/faq/monitoring/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/faq/node/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/add-relay/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/bp-move/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/bpport/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/catalyst-voting/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/cert-update/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/command/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/grafana-alert/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/grafana-repo/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/grafana-security/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/kes-update/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/mithril-client/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/node-update/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/p2p-settings/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/pool-retire/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/relay-move/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/rsync-ssh/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/sftp/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/sjg-fixed/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/spo-poll/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/start-guide/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/tool/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/transfer/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/ubuntu22/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/operation/withdrawal/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/1-ubuntu-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/10-blocklog-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/11-blocknotify-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/2-node-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/3-relay-bp-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/4-bp-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/5-generate-address/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/6-register-stakeaddress/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/7-register-stakepool/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/8.topology-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/9-monitoring-tools-setup/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/99-donation-credit/ + 2024-01-30 + daily + + + https://docs.spojapanguild.net/setup/air-gap-guid/ + 2024-01-30 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000..d13b24cd Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/extra.css b/stylesheets/extra.css new file mode 100644 index 00000000..f54408ec --- /dev/null +++ b/stylesheets/extra.css @@ -0,0 +1,105 @@ +.md-typeset { + font-size: .75rem; +} + +.md-typeset :is(.admonition,details) { + font-size: .75rem; +} + +.md-typeset pre>code { + font-size: .72rem; +} + +.md-grid { + max-width: 1500px; +} + +.md-sidebar--secondary { + width: 18rem; + +} +.md-sidebar--secondary .md-nav__link { + font-size:.65rem; +} + +.mermaid .label { + color: var(--md-mermaid-font-color) !important; +} + +.nodes .label text,.clusters .cluster .cluster-label text { + fill: var(--md-mermaid-font-color) !important; +} + +.label text{ + fill: var(--md-mermaid-font-color) !important; +} + +.clusters .cluster rect { + fill: var(--md-scheme-node-fg-color--transparent) !important; +} + +.note .quote{ + word-break:break-word; +} + + +.mermaid .edgeLabel { + padding: 10px; + background-color: var(--md-mermaid-node-label-bg-color) !important; + stroke:var(--md-mermaid-font-color) !important; +} + +.mermaid .arrowheadPath,.mermaid .edgePath .path { + stroke:var(--md-mermaid-node-fg-color) !important; +} + +.node rect { + fill: var(--md-mermaid-node-bg-color) !important; + stroke: var(--md-mermaid-node-fg-color) !important; + } + +:root>* { + + --md-mermaid-node-bg-color: var(--md-scheme-node-fg-color--transparent); + --md-mermaid-node-label-bg-color: var(--md-scheme-node-label-color); + --md-mermaid-node-fg-color: var(--md-scheme-node-fg-color); + --md-mermaid-font-color: var(--md-scheme-node-font-color); + +} + +[data-md-color-scheme="slate"] { + --md-scheme-node-font-color :#FFF; + --md-scheme-node-label-color: #333; + --md-scheme-node-fg-color: #00b0ff; + --md-scheme-node-fg-color--transparent: rgba(25, 151, 255, 0.1); + --md-scheme-node-bg-color: #fff; + --md-scheme-node-bg-color--light: hsla(0,0%,100%,.7); +} + +[data-md-color-scheme="default"] { + --md-scheme-node-font-color :#000; + --md-scheme-node-label-color: #FFF; + --md-scheme-node-fg-color: #4051b5; + --md-scheme-node-fg-color--transparent: rgba(25, 151, 255, 0.1); + --md-scheme-node-bg-color: #fff; + --md-scheme-node-bg-color--light: hsla(0,0%,100%,.7); +} + +.pricing .md-typeset__table{ + display:block; +} + +.pricing table:not([class]){ + display:revert; +} + +.pricing table:not([class]) tr:nth-child(-n + 2) th:not([align]){ + text-align: center; + font-size: 1.2em; + font-weight: 700; +} + +.pricing table:not([class]) td:not([align]){ + text-align: center; + font-size: 1.2em; +} \ No newline at end of file